Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1u3LoE-00ESmf-Jw for pgsql-hackers@arkaria.postgresql.org; Fri, 11 Apr 2025 21:21:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1u3LoC-00EXnw-OQ for pgsql-hackers@arkaria.postgresql.org; Fri, 11 Apr 2025 21:21:09 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1u3LoC-00EXld-79 for pgsql-hackers@lists.postgresql.org; Fri, 11 Apr 2025 21:21:08 +0000 Received: from mail-yw1-x1132.google.com ([2607:f8b0:4864:20::1132]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1u3LoA-004M9j-1m for pgsql-hackers@lists.postgresql.org; Fri, 11 Apr 2025 21:21:07 +0000 Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-6fece18b3c8so24522327b3.3 for ; Fri, 11 Apr 2025 14:21:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1744406466; x=1745011266; darn=lists.postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=Hp2FFZVygbVDozJVdp50aiaF8MlOH/Uc62/vobDK+0E=; b=VFMx/gQSlQ/IbtRrT27pZzGZZwYWsnNpUm4FdndkC7yzU8yALSxPdXhcRU2xMsNi0I 2/erkYsOF1eo/R89Tli9td9ZAKzLh/oVAb+4Bj7Qg9+tq/yWi4ODV/pTMX8bYCMMXXb0 OXcqKVrBQqo53SvBNb72vIG9dddEAh3k01iKb9/B6yiOsxRu6+WdgHgQAKwle2EhPQjq 6B1+VN2ZSwQJbZWBwYt0jMq6MfdUPvtsnjyWmkW655+3p7XZuWUL50xNMPDExiC87tvg hC/h02urs+6KFYqv2P/InHgOdMGTfjqQpXgoJQjPuLqIp90omvGbkLv/KZyibrdaxbL5 uTQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744406466; x=1745011266; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Hp2FFZVygbVDozJVdp50aiaF8MlOH/Uc62/vobDK+0E=; b=qshSWw7RcWQv//svM/to8TW0iY4luRyhXw0cJq4eE/ami0C5OGAcSQpibchbxZcTx5 rfOUugk9ZPPui4di/qrVyvMTkLJZE8cLub65Toe257QberyKv/TKHUPnvbABMHA+5e++ Sdwute9dyiTzMr0cS/v/m0DPbSozVimGhXVXCl3/vfMMjr7QPc+jzF5i5xJFfJ/31Iim GEruCRnHqOptcb7lRsfqNUdlj/NM59MCxlr9EB9uulGQivcSqjv7C21Hc5nRn0DhHB/c q9GX0To6R1DMsWeTo2dwtRZdT9tOwTORB3klynaDy5cJxoG2AE61pDx+zmtMJ0sfmbYz j1Jg== X-Forwarded-Encrypted: i=1; AJvYcCUbrKR7omvCgyKCIinFUAkM6JD3Z41Ao2ksMIhKSOv7WBuUOmXd0GpZpprPZ7A2i57kxL3gGohsKo8Nex4Z@lists.postgresql.org X-Gm-Message-State: AOJu0Yy3cgEp0tKW60q1PlGsqIERpcxQOZq03G3x5+rZkotDYBk0hjeF Yz34IKtgABQPC7apzDUuvL9R3lLskgvDRDHTUcvHpIyl5YFuNuce X-Gm-Gg: ASbGnctjnvVhEH61CKFWK/sAm/LSbjEzX5Eyb3ai4+0A2vb0jknlyJ/9aGFIEhGlCjG zlrCZmWcYhzKZmkOCNiJQ2F474XUbPibkNpN+lI8LI+i2Fw/pat6/vc2VRLPMXb3yjE8DSNFhvB xRIy34xyWYcGA9ra4wg3onTU7hntckL9Y9vozWJ1+JjyThXu/ykGHkCvJ0EYwpRIh/YOe719rDF 3QXo1xOfVZagbca61b9Mfr9OUH6dm/fGB15h70sPxe0AvTj7+/RRhhDbMN8U0MkTVwnAf0p22AT 9CEdWIJcnU2GEEhTiRtvCgodbgXWgxbSfWSl/bqorbBO3Yv3OWf89e/VYruQlxVQKFCG0rrOAhw ap9QSPEYx4jmCwKFAUc4eAx3dDManG1SYfRxMVF/HwQ== X-Google-Smtp-Source: AGHT+IHQIVro/gnZygqunUFF35Ekceq+5wtRFlyp7yjbzPNmNwmW23hykizrh3uYa6/p24r5qW7r9A== X-Received: by 2002:a05:690c:6f93:b0:702:4068:9bd7 with SMTP id 00721157ae682-705599ea22dmr75215427b3.22.1744406465613; Fri, 11 Apr 2025 14:21:05 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7053e0e8465sm16680297b3.21.2025.04.11.14.21.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 14:21:04 -0700 (PDT) Date: Fri, 11 Apr 2025 16:21:02 -0500 From: Nathan Bossart To: Euler Taveira Cc: Michael Paquier , Amit Kapila , Alexander Lakhin , Tom Lane , "Jonathan S. Katz" , PostgreSQL Hackers Subject: Re: Large expressions in indexes can't be stored (non-TOASTable) Message-ID: References: <4c2a6100-738e-48cc-8a11-2d85f95ae0ed@app.fastmail.com> <18a111db-9f31-449c-a14b-61779a69f344@app.fastmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="znuqeLo/iIPPYOto" Content-Disposition: inline In-Reply-To: <18a111db-9f31-449c-a14b-61779a69f344@app.fastmail.com> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --znuqeLo/iIPPYOto Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Apr 09, 2025 at 08:54:21PM -0300, Euler Taveira wrote: > LGTM. I have a few suggestions. Thanks for reviewing. > + /* > + * To avoid needing a TOAST table for pg_replication_origin, we restrict > + * replication origin names to 512 bytes. This should be more than enough > + * for all practical use. > + */ > + if (strlen(roname) > MAX_RONAME_LEN) > + ereport(ERROR, > > I wouldn't duplicate the comment. Instead, I would keep it only in origin.h. Hm. I agree that duplicating the comment isn't great, but I'm also not wild about forcing readers to jump to the macro definition to figure out why there is a length restriction. > + errdetail("Repilcation origin names must be no longer than %d bytes.", > + MAX_RONAME_LEN))); > > s/Repilcation/Replication/ Fixed. > +#define MAX_RONAME_LEN (512) > > It is just a cosmetic suggestion but I usually use parentheses when it is an > expression but don't include it for a single number. We use both styles, but the no-parentheses style does seem to be preferred. $ grep -E "^#define\s[A-Z_]+\s\([0-9]+\)$" src/* -rI | wc -l 23 $ grep -E "^#define\s[A-Z_]+\s[0-9]+$" src/* -rI | wc -l 861 > Should we document this maximum length? I've added a note. -- nathan --znuqeLo/iIPPYOto Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="v2-0001-Remove-pg_replication_origin-s-TOAST-table.patch" From 6762a3786b76379c82ccfa4c9da1812e928179b5 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 9 Apr 2025 14:00:31 -0500 Subject: [PATCH v2 1/1] Remove pg_replication_origin's TOAST table. --- doc/src/sgml/func.sgml | 1 + src/backend/catalog/catalog.c | 2 -- src/backend/replication/logical/origin.c | 12 ++++++++++++ src/include/catalog/pg_replication_origin.h | 2 -- src/include/replication/origin.h | 7 +++++++ src/test/regress/expected/misc_functions.out | 4 ++++ src/test/regress/expected/misc_sanity.out | 6 +++++- src/test/regress/sql/misc_functions.sql | 3 +++ src/test/regress/sql/misc_sanity.sql | 3 +++ 9 files changed, 35 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 1c5cfee25d1..a9c5c855524 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -29941,6 +29941,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset Creates a replication origin with the given external name, and returns the internal ID assigned to it. + The name must be no longer than 512 bytes. diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index a6edf614606..a7eb60dd2d2 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -315,8 +315,6 @@ IsSharedRelation(Oid relationId) relationId == PgDbRoleSettingToastIndex || relationId == PgParameterAclToastTable || relationId == PgParameterAclToastIndex || - relationId == PgReplicationOriginToastTable || - relationId == PgReplicationOriginToastIndex || relationId == PgShdescriptionToastTable || relationId == PgShdescriptionToastIndex || relationId == PgShseclabelToastTable || diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c index 6583dd497da..c17c0348c6e 100644 --- a/src/backend/replication/logical/origin.c +++ b/src/backend/replication/logical/origin.c @@ -264,6 +264,18 @@ replorigin_create(const char *roname) SysScanDesc scan; ScanKeyData key; + /* + * To avoid needing a TOAST table for pg_replication_origin, we restrict + * replication origin names to 512 bytes. This should be more than enough + * for all practical use. + */ + if (strlen(roname) > MAX_RONAME_LEN) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("replication origin name is too long"), + errdetail("Replication origin names must be no longer than %d bytes.", + MAX_RONAME_LEN))); + roname_d = CStringGetTextDatum(roname); Assert(IsTransactionState()); diff --git a/src/include/catalog/pg_replication_origin.h b/src/include/catalog/pg_replication_origin.h index deb43065fe9..7ade8bbda39 100644 --- a/src/include/catalog/pg_replication_origin.h +++ b/src/include/catalog/pg_replication_origin.h @@ -54,8 +54,6 @@ CATALOG(pg_replication_origin,6000,ReplicationOriginRelationId) BKI_SHARED_RELAT typedef FormData_pg_replication_origin *Form_pg_replication_origin; -DECLARE_TOAST_WITH_MACRO(pg_replication_origin, 4181, 4182, PgReplicationOriginToastTable, PgReplicationOriginToastIndex); - DECLARE_UNIQUE_INDEX_PKEY(pg_replication_origin_roiident_index, 6001, ReplicationOriginIdentIndex, pg_replication_origin, btree(roident oid_ops)); DECLARE_UNIQUE_INDEX(pg_replication_origin_roname_index, 6002, ReplicationOriginNameIndex, pg_replication_origin, btree(roname text_ops)); diff --git a/src/include/replication/origin.h b/src/include/replication/origin.h index 9cb2248fa9f..29724c0dcae 100644 --- a/src/include/replication/origin.h +++ b/src/include/replication/origin.h @@ -33,6 +33,13 @@ typedef struct xl_replorigin_drop #define InvalidRepOriginId 0 #define DoNotReplicateId PG_UINT16_MAX +/* + * To avoid needing a TOAST table for pg_replication_origin, we restrict + * replication origin names to 512 bytes. This should be more than enough for + * all practical use. + */ +#define MAX_RONAME_LEN 512 + extern PGDLLIMPORT RepOriginId replorigin_session_origin; extern PGDLLIMPORT XLogRecPtr replorigin_session_origin_lsn; extern PGDLLIMPORT TimestampTz replorigin_session_origin_timestamp; diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index d3f5d16a672..d28b69e50ad 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -914,3 +914,7 @@ SELECT test_relpath(); (1 row) +-- pg_replication_origin.roname length restriction +SELECT pg_replication_origin_create(repeat('0123456789abcdef', 33)); +ERROR: replication origin name is too long +DETAIL: Replication origin names must be no longer than 512 bytes. diff --git a/src/test/regress/expected/misc_sanity.out b/src/test/regress/expected/misc_sanity.out index b032a3f4761..0cb58311329 100644 --- a/src/test/regress/expected/misc_sanity.out +++ b/src/test/regress/expected/misc_sanity.out @@ -42,6 +42,9 @@ WHERE refclassid = 0 OR refobjid = 0 OR -- as user data by pg_upgrade, which would cause failures. -- 3. pg_authid, since its toast table cannot be accessed when it would be -- needed, i.e., during authentication before we've selected a database. +-- 4. pg_replication_origin, since its toast table would only be used for +-- replication origin names, which we can avoid with a reasonable length +-- restriction. SELECT relname, attname, atttypid::regtype FROM pg_class c JOIN pg_attribute a ON c.oid = attrelid WHERE c.oid < 16384 AND @@ -61,7 +64,8 @@ ORDER BY 1, 2; pg_class | relpartbound | pg_node_tree pg_largeobject | data | bytea pg_largeobject_metadata | lomacl | aclitem[] -(10 rows) + pg_replication_origin | roname | text +(11 rows) -- system catalogs without primary keys -- diff --git a/src/test/regress/sql/misc_functions.sql b/src/test/regress/sql/misc_functions.sql index aaebb298330..7122ff6133d 100644 --- a/src/test/regress/sql/misc_functions.sql +++ b/src/test/regress/sql/misc_functions.sql @@ -411,3 +411,6 @@ CREATE FUNCTION test_relpath() AS :'regresslib' LANGUAGE C; SELECT test_relpath(); + +-- pg_replication_origin.roname length restriction +SELECT pg_replication_origin_create(repeat('0123456789abcdef', 33)); diff --git a/src/test/regress/sql/misc_sanity.sql b/src/test/regress/sql/misc_sanity.sql index 135793871b4..545b2b48989 100644 --- a/src/test/regress/sql/misc_sanity.sql +++ b/src/test/regress/sql/misc_sanity.sql @@ -45,6 +45,9 @@ WHERE refclassid = 0 OR refobjid = 0 OR -- as user data by pg_upgrade, which would cause failures. -- 3. pg_authid, since its toast table cannot be accessed when it would be -- needed, i.e., during authentication before we've selected a database. +-- 4. pg_replication_origin, since its toast table would only be used for +-- replication origin names, which we can avoid with a reasonable length +-- restriction. SELECT relname, attname, atttypid::regtype FROM pg_class c JOIN pg_attribute a ON c.oid = attrelid -- 2.39.5 (Apple Git-154) --znuqeLo/iIPPYOto--