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.96) (envelope-from ) id 1vs3CC-002rcz-0r for pgsql-hackers@arkaria.postgresql.org; Mon, 16 Feb 2026 18:19:44 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vs3CA-004meV-10 for pgsql-hackers@arkaria.postgresql.org; Mon, 16 Feb 2026 18:19:42 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vs3C9-004meD-1e for pgsql-hackers@lists.postgresql.org; Mon, 16 Feb 2026 18:19:42 +0000 Received: from fout-a2-smtp.messagingengine.com ([103.168.172.145]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1vs3C6-000000013zb-22g8 for pgsql-hackers@lists.postgresql.org; Mon, 16 Feb 2026 18:19:41 +0000 Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailfout.phl.internal (Postfix) with ESMTP id 1C1E6EC058D; Mon, 16 Feb 2026 13:19:36 -0500 (EST) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-04.internal (MEProxy); Mon, 16 Feb 2026 13:19:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kurilemu.de; h= cc:cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to; s=fm2; t=1771265976; x= 1771352376; bh=7sw1gfqcDG80X/T+jxMn7zJXhCFg+jD3XwsGNWT7lZA=; b=K jXhHaiKiqxtYTZwu3p6c/K5s/sca2LJvWAme7nRTPgGv5GxKvMmnAn5y3x4W1p46 gqywAmEzPlxNsI8/fmaU0PyQkpXcOuWFBQErj2fKR1/b2MSnIEkXxffFLW5tXz2P XFhoh3uM5R2rkmbnJKSsiqXgpo96Gq2aCfjh8O74YwNSlWA/NQhvL9cvDEFgIO+7 V9vteeZABhW44RYPtnUDzE6mDLcw4n/qUu4jwmSNrfh0Uuym5N6Fsy/kFgC5CTmr wufH5XsWeNBjrn3qTrOtXr+foNx56R/HMQGmKGV0sUQ9sK+mQNlR13muqDR1cxHs hN4XzivshqRQAJ0MIUaeA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1771265976; x=1771352376; bh=7 sw1gfqcDG80X/T+jxMn7zJXhCFg+jD3XwsGNWT7lZA=; b=dsEU3cXrLvM+F+axc fTwn/wMCaM6VUyfIBJfLgmSyDSOIYOcb67OeGdFIF5rzPHehYn5AsLCq5hPjMmWm OF03/m0LRWpei+pFIys2DP+fl5rgmIzFGJNilnLQIFte76c/X70FqWTpGUTW5p0Q V1v/Md0UKjqZKCe+7HU8r9uJbc9hczMre6vnqkkRhOV1zCGPh0B8Scufc0ftkQ+X 3ykocsiW51sHgGjL4EyFae/Dy5rvMQ2WZqTBbhRSwWgbzQmFmL6aY3JJsLtjwNpx u9BJ6nmiLIzFI7DzPHpz4an0myCTdaCqxjugulpDUP6HhW1vhxU4atgAQSJwWPBZ jLDZg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddvudejheejucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepfffhvfevuffkgggtugfgjgesmhekreertddtjeenucfhrhhomheplmhlvhgrrhho ucfjvghrrhgvrhgruceorghlvhhhvghrrhgvsehkuhhrihhlvghmuhdruggvqeenucggtf frrghtthgvrhhnpeegudetudejheduveevgeehjeegleevveevvdeutdejtdekuefhheeh geevtdejteenucffohhmrghinhepvghnthgvrhhprhhishgvuggsrdgtohhmnecuvehluh hsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprghlvhhhvghrrhgv sehkuhhrihhlvghmuhdruggvpdhnsggprhgtphhtthhopedvpdhmohguvgepshhmthhpoh huthdprhgtphhtthhopehfrggsrhhiiihiohhmvghllhhosehgmhgrihhlrdgtohhmpdhr tghpthhtohepphhgshhqlhdqhhgrtghkvghrsheslhhishhtshdrphhoshhtghhrvghsqh hlrdhorhhg X-ME-Proxy: Feedback-ID: ie3de48e3:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 16 Feb 2026 13:19:35 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kurilemu.de; s=schmee; t=1771265973; bh=iR6vB/Nii0P9JZtd5JYZoCgCmCbhQevu5tizt0Cw8go=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=PyirOASVQ/fnXmFqbxk774vAQHnmunHW2gTxEG6nCFaHVy0xlv7uTKICWFt+FPXV/ O+id/nw6zz5xPytP0Ps/XBt5w62VTl9Srrc6S46F2Zy5YIMZhVYISSqGlj0urZo+L4 zVl/DRoqt1TZpacrdzyXJx+xDu3Ox+QTYk5lOu0vZZ5MBA48FP8dl+wPq9Q7brJJmN lLuW2ODta4MdV3SLqFikEWrdx1ZlnxicPkKPj8ntbErT8ZusWvN0RgmzSZP0uzJGdA 8kO265QVqrIAGAzGybhGoQYwlt/p+0u42w1BHFv4dyLTEeH0OZUoIHBiGXQHNF3pAt LtXJWGqe4BkSQ== Received: by schmee.kurilemu.internal (Postfix, from userid 1000) id 73A3A7A; Mon, 16 Feb 2026 19:19:33 +0100 (CET) Date: Mon, 16 Feb 2026 19:19:33 +0100 From: =?utf-8?Q?=C3=81lvaro?= Herrera To: =?utf-8?B?RmFicsOtemlv?= de Royes Mello Cc: Pg Hackers Subject: Re: make ExecInsertIndexTuples arguments less bad Message-ID: <202602161805.jwp2f4s5svmp@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="iqj6mfwrrhuzgzze" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --iqj6mfwrrhuzgzze Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Hello Fabrízio, hackers, On 2026-Feb-11, Fabrízio de Royes Mello wrote: > On Wed, Feb 11, 2026 at 4:07 PM Álvaro Herrera wrote: > > > The arguments to ExecInsertIndexTuples() are rather unhelpful to read; > > patching them is messy and hard to follow. How about we reuse the > > pattern we used in commit f831d4accda0 to make them less bad? > > I think the code is much nicer to read this way. > > Much better. LGTM! Thanks for looking! However, I had second thoughts about this formulation. Mainly, the fact that one of the output arguments is part of the macro is kinda icky. So I decided that a simpler, less innovative option is to just use a bits32 argument to carry the input booleans, and let the output boolean be a separate argument (which I also moved to appear last in the argument list, as we normally do). This also means the list of indexes continues to be its own argument. But, as I said, this is less innovative, which I think is mostly good. And it definitely reads better than currently. There might be places in executor.h to reuse the f831d4accda0 thingy, but this is probably not it. Thanks, -- Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/ "Los dioses no protegen a los insensatos. Éstos reciben protección de otros insensatos mejor dotados" (Luis Wu, Mundo Anillo) --iqj6mfwrrhuzgzze Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="0001-Use-bitmask-for-ExecInsertIndexTuples-options.patch" From f98ee25bd47f1e03ce421032198819f3d94103ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Mon, 16 Feb 2026 18:49:53 +0100 Subject: [PATCH] Use bitmask for ExecInsertIndexTuples options ... instead of passing a bunch of separate booleans. --- src/backend/commands/copyfrom.c | 11 ++++----- src/backend/executor/execIndexing.c | 33 +++++++++++++------------- src/backend/executor/execReplication.c | 24 ++++++++++++------- src/backend/executor/nodeModifyTable.c | 20 +++++++++------- src/include/executor/executor.h | 11 +++++---- 5 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c index 25ee20b23db..ecb78b8adb9 100644 --- a/src/backend/commands/copyfrom.c +++ b/src/backend/commands/copyfrom.c @@ -572,8 +572,8 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo, cstate->cur_lineno = buffer->linenos[i]; recheckIndexes = ExecInsertIndexTuples(resultRelInfo, - buffer->slots[i], estate, false, - false, NULL, NIL, false); + buffer->slots[i], estate, NIL, 0, + NULL); ExecARInsertTriggers(estate, resultRelInfo, slots[i], recheckIndexes, cstate->transition_capture); @@ -1431,11 +1431,8 @@ CopyFrom(CopyFromState cstate) recheckIndexes = ExecInsertIndexTuples(resultRelInfo, myslot, estate, - false, - false, - NULL, - NIL, - false); + NIL, 0, + NULL); } /* AFTER ROW INSERT Triggers */ diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c index f0ba7eac87d..5fb79159930 100644 --- a/src/backend/executor/execIndexing.c +++ b/src/backend/executor/execIndexing.c @@ -276,18 +276,18 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo) * into all the relations indexing the result relation * when a heap tuple is inserted into the result relation. * - * When 'update' is true and 'onlySummarizing' is false, + * When EIIT_IS_UPDATE is set and EIIT_ONLY_SUMMARIZING isn't, * executor is performing an UPDATE that could not use an * optimization like heapam's HOT (in more general terms a * call to table_tuple_update() took place and set * 'update_indexes' to TU_All). Receiving this hint makes * us consider if we should pass down the 'indexUnchanged' * hint in turn. That's something that we figure out for - * each index_insert() call iff 'update' is true. - * (When 'update' is false we already know not to pass the + * each index_insert() call iff EIIT_IS_UPDATE is set. + * (When that flag is not set we already know not to pass the * hint to any index.) * - * If onlySummarizing is set, an equivalent optimization to + * If EIIT_ONLY_SUMMARIZING is set, an equivalent optimization to * HOT has been applied and any updated columns are indexed * only by summarizing indexes (or in more general terms a * call to table_tuple_update() took place and set @@ -298,23 +298,21 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo) * Unique and exclusion constraints are enforced at the same * time. This returns a list of index OIDs for any unique or * exclusion constraints that are deferred and that had - * potential (unconfirmed) conflicts. (if noDupErr == true, + * potential (unconfirmed) conflicts. (if EIIT_NO_DUPE_ERROR, * the same is done for non-deferred constraints, but report * if conflict was speculative or deferred conflict to caller) * - * If 'arbiterIndexes' is nonempty, noDupErr applies only to - * those indexes. NIL means noDupErr applies to all indexes. + * If 'arbiterIndexes' is nonempty, EIIT_NO_DUPE_ERROR applies only to + * those indexes. NIL means EIIT_NO_DUPE_ERROR applies to all indexes. * ---------------------------------------------------------------- */ List * ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, - bool update, - bool noDupErr, - bool *specConflict, List *arbiterIndexes, - bool onlySummarizing) + bits32 flags, + bool *specConflict) { ItemPointer tupleid = &slot->tts_tid; List *result = NIL; @@ -374,7 +372,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, * Skip processing of non-summarizing indexes if we only update * summarizing indexes */ - if (onlySummarizing && !indexInfo->ii_Summarizing) + if ((flags & EIIT_ONLY_SUMMARIZING) && !indexInfo->ii_Summarizing) continue; /* Check for partial index */ @@ -409,7 +407,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, isnull); /* Check whether to apply noDupErr to this index */ - applyNoDupErr = noDupErr && + applyNoDupErr = (flags & EIIT_NO_DUPE_ERROR) && (arbiterIndexes == NIL || list_member_oid(arbiterIndexes, indexRelation->rd_index->indexrelid)); @@ -441,10 +439,11 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, * index. If we're being called as part of an UPDATE statement, * consider if the 'indexUnchanged' = true hint should be passed. */ - indexUnchanged = update && index_unchanged_by_update(resultRelInfo, - estate, - indexInfo, - indexRelation); + indexUnchanged = ((flags & EIIT_IS_UPDATE) && + index_unchanged_by_update(resultRelInfo, + estate, + indexInfo, + indexRelation)); satisfiesConstraint = index_insert(indexRelation, /* index relation */ diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index 743b1ee2b28..cf22775871d 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -846,11 +846,14 @@ ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo, conflictindexes = resultRelInfo->ri_onConflictArbiterIndexes; if (resultRelInfo->ri_NumIndices > 0) + { + bits32 flags = conflictindexes != NIL ? EIIT_NO_DUPE_ERROR : 0; + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, - slot, estate, false, - conflictindexes ? true : false, - &conflict, - conflictindexes, false); + slot, estate, + conflictindexes, flags, + &conflict); + } /* * Checks the conflict indexes to fetch the conflicting local row and @@ -943,11 +946,16 @@ ExecSimpleRelationUpdate(ResultRelInfo *resultRelInfo, conflictindexes = resultRelInfo->ri_onConflictArbiterIndexes; if (resultRelInfo->ri_NumIndices > 0 && (update_indexes != TU_None)) + { + bits32 flags = EIIT_IS_UPDATE; + + flags |= conflictindexes != NIL ? EIIT_NO_DUPE_ERROR : 0; + flags |= update_indexes == TU_Summarizing ? EIIT_ONLY_SUMMARIZING : 0; recheckIndexes = ExecInsertIndexTuples(resultRelInfo, - slot, estate, true, - conflictindexes ? true : false, - &conflict, conflictindexes, - (update_indexes == TU_Summarizing)); + slot, estate, + conflictindexes, flags, + &conflict); + } /* * Refer to the comments above the call to CheckAndReportConflict() in diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 6802fc13e95..5dbf866a1b9 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1226,10 +1226,10 @@ ExecInsert(ModifyTableContext *context, /* insert index entries for tuple */ recheckIndexes = ExecInsertIndexTuples(resultRelInfo, - slot, estate, false, true, - &specConflict, + slot, estate, arbiterIndexes, - false); + EIIT_NO_DUPE_ERROR, + &specConflict); /* adjust the tuple's state accordingly */ table_tuple_complete_speculative(resultRelationDesc, slot, @@ -1267,9 +1267,8 @@ ExecInsert(ModifyTableContext *context, /* insert index entries for tuple */ if (resultRelInfo->ri_NumIndices > 0) recheckIndexes = ExecInsertIndexTuples(resultRelInfo, - slot, estate, false, - false, NULL, NIL, - false); + slot, estate, NIL, 0, + NULL); } } @@ -2356,11 +2355,14 @@ ExecUpdateEpilogue(ModifyTableContext *context, UpdateContext *updateCxt, /* insert index entries for tuple if necessary */ if (resultRelInfo->ri_NumIndices > 0 && (updateCxt->updateIndexes != TU_None)) + { + bits32 flags = EIIT_IS_UPDATE; + + flags |= updateCxt->updateIndexes == TU_Summarizing ? EIIT_ONLY_SUMMARIZING : 0; recheckIndexes = ExecInsertIndexTuples(resultRelInfo, slot, context->estate, - true, false, - NULL, NIL, - (updateCxt->updateIndexes == TU_Summarizing)); + NIL, flags, NULL); + } /* AFTER ROW UPDATE Triggers */ ExecARUpdateTriggers(context->estate, resultRelInfo, diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 55a7d930d26..e788c5c7aee 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -739,12 +739,15 @@ extern Bitmapset *ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate); */ extern void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative); extern void ExecCloseIndices(ResultRelInfo *resultRelInfo); + +/* flags for ExecInsertIndexTuples */ +#define EIIT_IS_UPDATE (1<<0) +#define EIIT_NO_DUPE_ERROR (1<<1) +#define EIIT_ONLY_SUMMARIZING (1<<2) extern List *ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, - bool update, - bool noDupErr, - bool *specConflict, List *arbiterIndexes, - bool onlySummarizing); + List *arbiterIndexes, bits32 options, + bool *specConflict); extern bool ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, ItemPointer conflictTid, -- 2.47.3 --iqj6mfwrrhuzgzze--