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 1snoy0-006H1G-Ek for pgsql-hackers@arkaria.postgresql.org; Tue, 10 Sep 2024 00:42:49 +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 1snoy0-003gqS-6A for pgsql-hackers@arkaria.postgresql.org; Tue, 10 Sep 2024 00:42:48 +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 1snoxz-003gqK-JG for pgsql-hackers@lists.postgresql.org; Tue, 10 Sep 2024 00:42:47 +0000 Received: from fhigh2-smtp.messagingengine.com ([103.168.172.153]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1snoxv-000NtZ-29 for pgsql-hackers@lists.postgresql.org; Tue, 10 Sep 2024 00:42:46 +0000 Received: from phl-compute-10.internal (phl-compute-10.phl.internal [10.202.2.50]) by mailfhigh.phl.internal (Postfix) with ESMTP id 5BB6A11401F7; Mon, 9 Sep 2024 20:42:42 -0400 (EDT) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-10.internal (MEProxy); Mon, 09 Sep 2024 20:42:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paquier.xyz; h= cc:cc:content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1725928962; x=1726015362; bh=Ta52bAw5Sd 7/vd4jsYT7D6daARoCGotv4yvYZfegULA=; b=Fgwdv1GCUEj9RN4TZ9dUBVBqhU ohKO/ESIVnLDuTb+TZAGeumHeXT6AazQTKqardBtZ+9fI+GOfNDVdaFcVMFBunlE vkZauRnTBDqi79lSSW6PGlN/swFSz9ZPgdbw2EmpBoenrV9566MJ+Ozlir3BfUoa u+uNSSZJzzocpkDHiuRHsD2xWv0qjb8WbW2wag2WEAG2JUtLrzkVB0XB9rnVeQQR O/cxWmz/X7mPk+8qMq6LBYMH25tIh4UdYWu6rvIRoSYEbRSUm7xmqKfx5vT876S+ CItXxMrx8YfyA5Bw5T6ZtFejiIaYZxX/zT1FfkOsyjEfN/IlR2K0eMwCuQ4Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1725928962; x=1726015362; bh=Ta52bAw5Sd7/vd4jsYT7D6daARoC Gotv4yvYZfegULA=; b=hdwInP7IYz85/H90TcgdLgwfbPrCgQu2gTHZHBb8E9v5 OTDYNMwF4ECBFE9KSuhhpZNMeNnAFhLXldBh9aBnaCYlPNtxbKNIT/M9wsrmZ2ba 33iujKWoTX+gNQEuV3KXNLzDbnKDlIvuL+DWQwn3pIeFioKmLj/XjBW4RFZxHPwL AoE9tFxni3AYqF6VR7Sp/3p9/+vsNUzl+aTzfZ8CEwcQmuuIqAHM7NZzWL5RECgM dfCU9QhWojGzeDSTx7rHsdL6hDuddDLP4U/1TZEDJtMfX3btC2fxkiZloezfKQMW 3T6ZEFAOCRHhhsatJ+n4xfRY60iZCB2FjyMzuP7MVw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeftddrudeikedgfeelucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnegfrhhlucfvnfffucdljedtmdenucfjughrpeffhffvvefukfhf gggtuggjsehgtderredttddvnecuhfhrohhmpefoihgthhgrvghlucfrrghquhhivghruc eomhhitghhrggvlhesphgrqhhuihgvrhdrgiihiieqnecuggftrfgrthhtvghrnhepteel ieefudffhffhtdetleeggeegfffhkeeuveetiefgudduvedutefggeeivdejnecuvehluh hsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepmhhitghhrggvlhes phgrqhhuihgvrhdrgiihiidpnhgspghrtghpthhtohepfedpmhhouggvpehsmhhtphhouh htpdhrtghpthhtohepnhgrthhhrghnuggsohhsshgrrhhtsehgmhgrihhlrdgtohhmpdhr tghpthhtohepuggrvhhiugdrghdrjhhohhhnshhtohhnsehgmhgrihhlrdgtohhmpdhrtg hpthhtohepphhgshhqlhdqhhgrtghkvghrsheslhhishhtshdrphhoshhtghhrvghsqhhl rdhorhhg X-ME-Proxy: Feedback-ID: i0fe9450f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 9 Sep 2024 20:42:40 -0400 (EDT) Date: Tue, 10 Sep 2024 09:42:31 +0900 From: Michael Paquier To: Nathan Bossart Cc: "David G. Johnston" , Postgres hackers Subject: Re: Partitioned tables and [un]loggedness Message-ID: References: MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="1KXSUGJFxbVPzu8f" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --1KXSUGJFxbVPzu8f Content-Type: multipart/mixed; boundary="0fH5TnRkT8TtdaIX" Content-Disposition: inline --0fH5TnRkT8TtdaIX Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, Sep 09, 2024 at 03:56:14PM +0900, Michael Paquier wrote: > How about inventing a new ATT_PARTITIONED_TABLE and make a clean split > between both relkinds? I'd guess that blocking both SET LOGGED and > UNLOGGED for partitioned tables is the best move, even if it is > possible to block only one or the other, of course. I gave it a try, and while it is much more invasive, it is also much more consistent with the rest of the file. Thoughts? -- Michael --0fH5TnRkT8TtdaIX Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v4-0001-Introduce-ATT_PARTITIONED_TABLE-in-tablecmds.c.patch" Content-Transfer-Encoding: quoted-printable =46rom fefb821c033784a01c39d99d477982ded1aebf40 Mon Sep 17 00:00:00 2001 =46rom: Michael Paquier Date: Tue, 10 Sep 2024 09:16:43 +0900 Subject: [PATCH v4 1/2] Introduce ATT_PARTITIONED_TABLE in tablecmds.c --- src/backend/commands/tablecmds.c | 92 +++++++++++++++++--------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablec= mds.c index b3cc6f8f69..f6a6e3e148 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -330,6 +330,7 @@ struct DropRelationCallbackState #define ATT_FOREIGN_TABLE 0x0020 #define ATT_PARTITIONED_INDEX 0x0040 #define ATT_SEQUENCE 0x0080 +#define ATT_PARTITIONED_TABLE 0x0100 =20 /* * ForeignTruncateInfo @@ -4777,7 +4778,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd = *cmd, { case AT_AddColumn: /* ADD COLUMN */ ATSimplePermissions(cmd->subtype, rel, - ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE); + ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREI= GN_TABLE); ATPrepAddColumn(wqueue, rel, recurse, recursing, false, cmd, lockmode, context); /* Recursion occurs during execution phase */ @@ -4798,7 +4799,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd = *cmd, * substitutes default values into INSERTs before it expands * rules. */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_FOREI= GN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_VIEW | ATT_FOREIGN_TABLE); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context); /* No command-specific prep needed */ pass =3D cmd->def ? AT_PASS_ADD_OTHERCONSTR : AT_PASS_DROP; @@ -4806,19 +4807,19 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCm= d *cmd, case AT_CookedColumnDefault: /* add a pre-cooked default */ /* This is currently used only in CREATE TABLE */ /* (so the permission check really isn't necessary) */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); /* This command never recurses */ pass =3D AT_PASS_ADD_OTHERCONSTR; break; case AT_AddIdentity: - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_FOREI= GN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_VIEW | ATT_FOREIGN_TABLE); /* Set up recursion for phase 2; no other prep needed */ if (recurse) cmd->recurse =3D true; pass =3D AT_PASS_ADD_OTHERCONSTR; break; case AT_SetIdentity: - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_FOREI= GN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_VIEW | ATT_FOREIGN_TABLE); /* Set up recursion for phase 2; no other prep needed */ if (recurse) cmd->recurse =3D true; @@ -4826,82 +4827,82 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCm= d *cmd, pass =3D AT_PASS_MISC; break; case AT_DropIdentity: - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_FOREI= GN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_VIEW | ATT_FOREIGN_TABLE); /* Set up recursion for phase 2; no other prep needed */ if (recurse) cmd->recurse =3D true; pass =3D AT_PASS_DROP; break; case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); ATPrepDropNotNull(rel, recurse, recursing); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context); pass =3D AT_PASS_DROP; break; case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); /* Need command-specific recursion decision */ ATPrepSetNotNull(wqueue, rel, cmd, recurse, recursing, lockmode, context); pass =3D AT_PASS_COL_ATTRS; break; case AT_CheckNotNull: /* check column is already marked NOT NULL */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context); /* No command-specific prep needed */ pass =3D AT_PASS_COL_ATTRS; break; case AT_SetExpression: /* ALTER COLUMN SET EXPRESSION */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context); pass =3D AT_PASS_SET_EXPRESSION; break; case AT_DropExpression: /* ALTER COLUMN DROP EXPRESSION */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context); ATPrepDropExpression(rel, cmd, recurse, recursing, lockmode); pass =3D AT_PASS_DROP; break; case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW | ATT_IN= DEX | ATT_PARTITIONED_INDEX | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_MATVIEW | ATT_INDEX | ATT_PARTITIONED_INDEX | ATT_FOREIGN_TABLE); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context); /* No command-specific prep needed */ pass =3D AT_PASS_MISC; break; case AT_SetOptions: /* ALTER COLUMN SET ( options ) */ case AT_ResetOptions: /* ALTER COLUMN RESET ( options ) */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW | ATT_FO= REIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_MATVIEW | ATT_FOREIGN_TABLE); /* This command never recurses */ pass =3D AT_PASS_MISC; break; case AT_SetStorage: /* ALTER COLUMN SET STORAGE */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW | ATT_FO= REIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_MATVIEW | ATT_FOREIGN_TABLE); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context); /* No command-specific prep needed */ pass =3D AT_PASS_MISC; break; case AT_SetCompression: /* ALTER COLUMN SET COMPRESSION */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_MATVIEW); /* This command never recurses */ /* No command-specific prep needed */ pass =3D AT_PASS_MISC; break; case AT_DropColumn: /* DROP COLUMN */ ATSimplePermissions(cmd->subtype, rel, - ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE); + ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREI= GN_TABLE); ATPrepDropColumn(wqueue, rel, recurse, recursing, cmd, lockmode, context); /* Recursion occurs during execution phase */ pass =3D AT_PASS_DROP; break; case AT_AddIndex: /* ADD INDEX */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E); /* This command never recurses */ /* No command-specific prep needed */ pass =3D AT_PASS_ADD_INDEX; break; case AT_AddConstraint: /* ADD CONSTRAINT */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); /* Recursion occurs during execution phase */ /* No command-specific prep needed except saving recurse flag */ if (recurse) @@ -4909,13 +4910,13 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCm= d *cmd, pass =3D AT_PASS_ADD_CONSTR; break; case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E); /* This command never recurses */ /* No command-specific prep needed */ pass =3D AT_PASS_ADD_INDEXCONSTR; break; case AT_DropConstraint: /* DROP CONSTRAINT */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); ATCheckPartitionsNotInUse(rel, lockmode); /* Other recursion occurs during execution phase */ /* No command-specific prep needed except saving recurse flag */ @@ -4925,7 +4926,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd = *cmd, break; case AT_AlterColumnType: /* ALTER COLUMN TYPE */ ATSimplePermissions(cmd->subtype, rel, - ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE); + ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREI= GN_TABLE); /* See comments for ATPrepAlterColumnType */ cmd =3D ATParseTransformCmd(wqueue, tab, rel, cmd, recurse, lockmode, AT_PASS_UNSET, context); @@ -4948,14 +4949,14 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCm= d *cmd, break; case AT_ClusterOn: /* CLUSTER ON */ case AT_DropCluster: /* SET WITHOUT CLUSTER */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_MATVIEW); /* These commands never recurse */ /* No command-specific prep needed */ pass =3D AT_PASS_MISC; break; case AT_SetLogged: /* SET LOGGED */ case AT_SetUnLogged: /* SET UNLOGGED */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_SEQUENCE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_SEQUENCE); if (tab->chgPersistence) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -4964,11 +4965,11 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCm= d *cmd, pass =3D AT_PASS_MISC; break; case AT_DropOids: /* SET WITHOUT OIDS */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); pass =3D AT_PASS_DROP; break; case AT_SetAccessMethod: /* SET ACCESS METHOD */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_MATVIEW); =20 /* check if another access method change was already requested */ if (tab->chgAccessMethod) @@ -4980,7 +4981,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd = *cmd, pass =3D AT_PASS_MISC; /* does not matter; no work in Phase 2 */ break; case AT_SetTableSpace: /* SET TABLESPACE */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW | ATT_IN= DEX | + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_MATVIEW | ATT_INDEX | ATT_PARTITIONED_INDEX); /* This command never recurses */ ATPrepSetTableSpace(tab, rel, cmd->name, lockmode); @@ -4989,30 +4990,30 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCm= d *cmd, case AT_SetRelOptions: /* SET (...) */ case AT_ResetRelOptions: /* RESET (...) */ case AT_ReplaceRelOptions: /* reset them all, then set just these */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_VIEW | ATT_MATVI= EW | ATT_INDEX); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_VIEW | ATT_MATVIEW | ATT_INDEX); /* This command never recurses */ /* No command-specific prep needed */ pass =3D AT_PASS_MISC; break; case AT_AddInherit: /* INHERIT */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); /* This command never recurses */ ATPrepAddInherit(rel); pass =3D AT_PASS_MISC; break; case AT_DropInherit: /* NO INHERIT */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); /* This command never recurses */ /* No command-specific prep needed */ pass =3D AT_PASS_MISC; break; case AT_AlterConstraint: /* ALTER CONSTRAINT */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E); /* Recursion occurs during execution phase */ pass =3D AT_PASS_MISC; break; case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); /* Recursion occurs during execution phase */ /* No command-specific prep needed except saving recurse flag */ if (recurse) @@ -5020,7 +5021,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd = *cmd, pass =3D AT_PASS_MISC; break; case AT_ReplicaIdentity: /* REPLICA IDENTITY ... */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_MATVIEW); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_MATVIEW); pass =3D AT_PASS_MISC; /* This command never recurses */ /* No command-specific prep needed */ @@ -5033,7 +5034,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd = *cmd, case AT_DisableTrig: /* DISABLE TRIGGER variants */ case AT_DisableTrigAll: case AT_DisableTrigUser: - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); /* Set up recursion for phase 2; no other prep needed */ if (recurse) cmd->recurse =3D true; @@ -5049,7 +5050,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd = *cmd, case AT_DisableRowSecurity: case AT_ForceRowSecurity: case AT_NoForceRowSecurity: - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E); /* These commands never recurse */ /* No command-specific prep needed */ pass =3D AT_PASS_MISC; @@ -5060,17 +5061,17 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCm= d *cmd, pass =3D AT_PASS_MISC; break; case AT_AttachPartition: - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_INDE= X); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_PARTITIONED_INDEX); /* No command-specific prep needed */ pass =3D AT_PASS_MISC; break; case AT_DetachPartition: - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E); /* No command-specific prep needed */ pass =3D AT_PASS_MISC; break; case AT_DetachPartitionFinalize: - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E); /* No command-specific prep needed */ pass =3D AT_PASS_MISC; break; @@ -6486,9 +6487,11 @@ ATSimplePermissions(AlterTableType cmdtype, Relation= rel, int allowed_targets) switch (rel->rd_rel->relkind) { case RELKIND_RELATION: - case RELKIND_PARTITIONED_TABLE: actual_target =3D ATT_TABLE; break; + case RELKIND_PARTITIONED_TABLE: + actual_target =3D ATT_PARTITIONED_TABLE; + break; case RELKIND_VIEW: actual_target =3D ATT_VIEW; break; @@ -6982,7 +6985,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab,= Relation rel, =20 /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) - ATSimplePermissions((*cmd)->subtype, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions((*cmd)->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TA= BLE | ATT_FOREIGN_TABLE); =20 if (rel->rd_rel->relispartition && !recursing) ereport(ERROR, @@ -8906,7 +8909,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const c= har *colName, =20 /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) - ATSimplePermissions(AT_DropColumn, rel, ATT_TABLE | ATT_FOREIGN_TABLE); + ATSimplePermissions(AT_DropColumn, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_FOREIGN_TABLE); =20 /* Initialize addrs on the first invocation */ Assert(!recursing || addrs !=3D NULL); @@ -9395,7 +9398,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo = *tab, Relation rel, =20 /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) - ATSimplePermissions(AT_AddConstraint, rel, ATT_TABLE | ATT_FOREIGN_TABLE= ); + ATSimplePermissions(AT_AddConstraint, rel, ATT_TABLE | ATT_PARTITIONED_T= ABLE | ATT_FOREIGN_TABLE); =20 /* * Call AddRelationNewConstraints to do the work, making sure it works on @@ -12400,7 +12403,7 @@ ATExecDropConstraint(Relation rel, const char *cons= trName, =20 /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) - ATSimplePermissions(AT_DropConstraint, rel, ATT_TABLE | ATT_FOREIGN_TABL= E); + ATSimplePermissions(AT_DropConstraint, rel, ATT_TABLE | ATT_PARTITIONED_= TABLE | ATT_FOREIGN_TABLE); =20 conrel =3D table_open(ConstraintRelationId, RowExclusiveLock); =20 @@ -15481,7 +15484,7 @@ ATExecAddInherit(Relation child_rel, RangeVar *pare= nt, LOCKMODE lockmode) * Must be owner of both parent and child -- child was checked by * ATSimplePermissions call in ATPrepCmd */ - ATSimplePermissions(AT_AddInherit, parent_rel, ATT_TABLE | ATT_FOREIGN_TA= BLE); + ATSimplePermissions(AT_AddInherit, parent_rel, ATT_TABLE | ATT_PARTITIONE= D_TABLE | ATT_FOREIGN_TABLE); =20 /* Permanent rels cannot inherit from temporary ones */ if (parent_rel->rd_rel->relpersistence =3D=3D RELPERSISTENCE_TEMP && @@ -18326,7 +18329,8 @@ ATExecAttachPartition(List **wqueue, Relation rel, = PartitionCmd *cmd, * Must be owner of both parent and source table -- parent was checked by * ATSimplePermissions call in ATPrepCmd */ - ATSimplePermissions(AT_AttachPartition, attachrel, ATT_TABLE | ATT_FOREIG= N_TABLE); + ATSimplePermissions(AT_AttachPartition, attachrel, + ATT_TABLE | ATT_PARTITIONED_TABLE | ATT_FOREIGN_TABLE); =20 /* A partition can only have one parent */ if (attachrel->rd_rel->relispartition) --=20 2.45.2 --0fH5TnRkT8TtdaIX Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v4-0002-Remove-support-for-ALTER-TABLE-.-SET-UN-LOGGED-on.patch" Content-Transfer-Encoding: quoted-printable =46rom 996a52b7d49607ddd62bbe0534718bcba894ea9a Mon Sep 17 00:00:00 2001 =46rom: Michael Paquier Date: Tue, 10 Sep 2024 09:35:00 +0900 Subject: [PATCH v4 2/2] Remove support for ALTER TABLE .. SET [UN]LOGGED on partitioned tables --- src/backend/commands/tablecmds.c | 8 +++++++- src/bin/pg_dump/pg_dump.c | 7 ++++++- src/bin/pgbench/pgbench.c | 2 +- src/test/regress/expected/create_table.out | 10 ++++++++++ src/test/regress/sql/create_table.sql | 6 ++++++ doc/src/sgml/ref/alter_table.sgml | 4 ++++ doc/src/sgml/ref/create_table.sgml | 4 ++++ 7 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablec= mds.c index f6a6e3e148..f5d7f2b9f8 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -729,6 +729,12 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid own= erId, else partitioned =3D false; =20 + if (relkind =3D=3D RELKIND_PARTITIONED_TABLE && + stmt->relation->relpersistence =3D=3D RELPERSISTENCE_UNLOGGED) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("partitioned tables cannot be unlogged"))); + /* * Look up the namespace in which we are supposed to create the relation, * check we have permission to create there, lock it against concurrent @@ -4956,7 +4962,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd = *cmd, break; case AT_SetLogged: /* SET LOGGED */ case AT_SetUnLogged: /* SET UNLOGGED */ - ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_PARTITIONED_TABL= E | ATT_SEQUENCE); + ATSimplePermissions(cmd->subtype, rel, ATT_TABLE | ATT_SEQUENCE); if (tab->chgPersistence) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 546e7e4ce1..c207436f93 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -15899,8 +15899,13 @@ dumpTableSchema(Archive *fout, const TableInfo *tb= info) binary_upgrade_set_pg_class_oids(fout, q, tbinfo->dobj.catId.oid); =20 + /* + * PostgreSQL 18 has disabled UNLOGGED for partitioned tables, so + * ignore it when dumping if it was set in this case. + */ appendPQExpBuffer(q, "CREATE %s%s %s", - tbinfo->relpersistence =3D=3D RELPERSISTENCE_UNLOGGED ? + tbinfo->relpersistence =3D=3D RELPERSISTENCE_UNLOGGED && + tbinfo->relkind !=3D RELKIND_PARTITIONED_TABLE ? "UNLOGGED " : "", reltypename, qualrelname); diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 61618f2e18..dc4d7408cd 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -4865,7 +4865,7 @@ initCreateTables(PGconn *con) =20 /* Construct new create table statement. */ printfPQExpBuffer(&query, "create%s table %s(%s)", - unlogged_tables ? " unlogged" : "", + unlogged_tables && partition_method =3D=3D PART_NONE ? " unlogged"= : "", ddl->table, (scale >=3D SCALE_32BIT_THRESHOLD) ? ddl->bigcols : ddl->smcols); =20 diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/= expected/create_table.out index 284a7fb85c..c45e02d42f 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -50,6 +50,16 @@ ERROR: cannot create temporary relation in non-temporar= y schema LINE 1: CREATE TEMP TABLE public.temp_to_perm (a int primary key); ^ DROP TABLE unlogged1, public.unlogged2; +CREATE UNLOGGED TABLE unlogged1 (a int) PARTITION BY RANGE (a); -- fail +ERROR: partitioned tables cannot be unlogged +CREATE TABLE unlogged1 (a int) PARTITION BY RANGE (a); -- ok +ALTER TABLE unlogged1 SET LOGGED; -- fails +ERROR: ALTER action SET LOGGED cannot be performed on relation "unlogged1" +DETAIL: This operation is not supported for partitioned tables. +ALTER TABLE unlogged1 SET UNLOGGED; -- fails +ERROR: ALTER action SET UNLOGGED cannot be performed on relation "unlogge= d1" +DETAIL: This operation is not supported for partitioned tables. +DROP TABLE unlogged1; CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind =3D 'r'; CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind =3D 'r'; ERROR: relation "as_select1" already exists diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/c= reate_table.sql index 1fd4cbfa7e..37a227148e 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -30,6 +30,12 @@ CREATE TEMP TABLE pg_temp.doubly_temp (a int primary key= ); -- also OK CREATE TEMP TABLE public.temp_to_perm (a int primary key); -- not OK DROP TABLE unlogged1, public.unlogged2; =20 +CREATE UNLOGGED TABLE unlogged1 (a int) PARTITION BY RANGE (a); -- fail +CREATE TABLE unlogged1 (a int) PARTITION BY RANGE (a); -- ok +ALTER TABLE unlogged1 SET LOGGED; -- fails +ALTER TABLE unlogged1 SET UNLOGGED; -- fails +DROP TABLE unlogged1; + CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind =3D 'r'; CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind =3D 'r'; CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relk= ind =3D 'r'; diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_tab= le.sgml index 1a49f321cf..19f29a0470 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -795,6 +795,10 @@ WITH ( MODULUS numeri= c_literal, REM (for identity or serial columns). However, it is also possible to change the persistence of such sequences separately. + + + This form is not supported for partitioned tables. + =20 diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_t= able.sgml index 93b3f664f2..65715b13b8 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -220,6 +220,10 @@ WITH ( MODULUS numeri= c_literal, REM If this is specified, any sequences created together with the unlogg= ed table (for identity or serial columns) are also created as unlogged. + + + This form is not supported for partitioned tables. + =20 --=20 2.45.2 --0fH5TnRkT8TtdaIX-- --1KXSUGJFxbVPzu8f Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEG72nH6vTowiyblFKnvQgOdbyQH0FAmbflfcACgkQnvQgOdby QH0jWQ//dCnUw/UBUk/6OhtTp+qdrnDIj5C853m2fgVcoxOf7fU+00uEyYBHC6KU zo99eEpGLGorZCn0z6fQuuIZgnBgeC9vrjTGgAV/egsdODSkUbqv2HL6uWUgdaJW Nt5KvZ9/iaG+enlLBSRwZZ5ZAA4RcCOI2d2fSUDHbfhUXWAnAWZ0yhSRJgB+mpxM fgPa7DqXc0W6lvE1XU3HbzUsAF6v6xzuFNz0UsAtBqkdzLVvijo2KkRoS3t+9OBp L0BNSTu9V0S7ThtbSWSDGzIQVd80+CBgPLPx7LjyPoY1mOtGVlz+4c94F0PHUQlw ELquI0El5s/DUEkWyuvFhxPvkxLCRrdmzJs91Jz/OnMpX5/PKRG75NlKxcixqbGF kKWnJuNhUDD77FuhvL2Kz5cAlhkt3VeszzWAs4ZwXFOawf3XG9/YR8psuJ19RIDQ qJr9jTaoXyEE0ATdawC4QDh/vcfa++XHxhKIXvWNXi5DAbQPfGXOdtj+ouRicvMF HIDiVBFP41DgQudTWFQD+jSfkpbgI2R4qVOvleW6BJqxD0vPxDm40h9gtFzybyeY NsD4rLIR8gCUKvXccHnqXUruHDaA924wcoR/DGSi8HNnNzCGFyKHkVjPCakC/lCX c2F8HadIDKJ5uIuDamdEBv8XKmjmF8uM3v0COXlhi9mj97kVtiQ= =uie6 -----END PGP SIGNATURE----- --1KXSUGJFxbVPzu8f--