public inbox for [email protected]
help / color / mirror / Atom feedFrom: Peter Eisentraut <[email protected]>
To: Amit Langote <[email protected]>
To: Junwang Zhao <[email protected]>
Cc: Chao Li <[email protected]>
Cc: Haibo Yan <[email protected]>
Cc: Pavel Stehule <[email protected]>
Cc: PostgreSQL-development <[email protected]>
Cc: Tomas Vondra <[email protected]>
Subject: Re: Eliminating SPI / SQL from some RI triggers - take 3
Date: Mon, 20 Apr 2026 22:50:29 +0200
Message-ID: <[email protected]> (raw)
In-Reply-To: <CA+HiwqF2Ma6R_QyjfPBvFreYbezFpGcwASJE0a2bM+Y0jvof+g@mail.gmail.com>
References: <CA+HiwqF4C0ws3cO+z5cLkPuvwnAwkSp7sfvgGj3yQ=Li6KNMqA@mail.gmail.com>
<CA+HiwqFwZ6WLRbY8R7VC7JVp5Jot6ktZOkr9wDxTjoK=W1SgdQ@mail.gmail.com>
<CA+HiwqF_Kz=R8juHJBiOATvabWSOugK4VaGOxoJ_n=E2c7UM9w@mail.gmail.com>
<CA+HiwqHCB7kcbspkhaLN9enoj5x=ehzhFM4PXDgWUUP8Px41GA@mail.gmail.com>
<[email protected]>
<CA+HiwqHpVtP485wEKuXdOkdoZWhvVvfFH40-og07Jp3MPx21eg@mail.gmail.com>
<CAEG8a3JWHkJSXe9nNcVK7wnYKUEqWuMGFDhy5BynB_9tEjmEUg@mail.gmail.com>
<CA+HiwqFjfumKrWy03q5M309xJJVYt0WgGfH6AZ8BjFhSwppwsQ@mail.gmail.com>
<CAEG8a3JjP1LaKSv-r3AMJLRyLMzENJrKshWsDvDouMPM_sizmA@mail.gmail.com>
<CA+HiwqFQ+ZA7hSOygv4uv_t75B3r0_gosjadetCsAEoaZwTu6g@mail.gmail.com>
<CA+HiwqHdB0r8z6Mut13BxpYNq2W-os+Arju4mcZbCyU9PeaVog@mail.gmail.com>
<CAEG8a3K5ayVNkCDnK9OtNb+4OY0chJtW6ObgEOSFjqyymQda8Q@mail.gmail.com>
<CA+HiwqGJYCgEs_F-LBtrRdx-Y969LMr-OVogjFXU6U-0q5bOwQ@mail.gmail.com>
<CA+HiwqF2Ma6R_QyjfPBvFreYbezFpGcwASJE0a2bM+Y0jvof+g@mail.gmail.com>
On 02.04.26 09:41, Amit Langote wrote:
> There's another case in which it is not ok to use FlushArray and that
> is if the index AM's amsearcharray is false (should be true in all
> cases because the unique index used for PK is always btree). Added an
> Assert to that effect next to where SK_SEARCHARRAY is set in
> ri_FastPathFlushArray rather than a runtime check in the dispatch
> condition.
>
> Patch updated. Also added a comment about invalidation requirement or
> lack thereof for RI_FastPathEntry, rename AfterTriggerBatchIsActive()
> to simply AfterTriggerIsActive(), fixed the comments in trigger.h
> describing the callback mechanism.
>
> Will push tomorrow morning (Friday) barring objections.
This commit contains a couple of calls
ri_populate_fastpath_metadata((RI_ConstraintInfo *) riinfo,
fk_rel, idx_rel);
where the cast casts away the const-ness of riinfo.
But this is kind of a lie, since the purpose of
ri_populate_fastpath_metadata() is to modify riinfo.
I think the right thing to do here is to unwind the const qualifiers up
the stack. See attached patch.
From 35f273c812aa4f1345a3c1a9eb1443e3c7439254 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Mon, 20 Apr 2026 22:40:05 +0200
Subject: [PATCH] Fix some const qualifier use in ri_triggers.c
---
src/backend/utils/adt/ri_triggers.c | 34 ++++++++++++++---------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index e060280fcd4..f63a7f0b580 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -297,9 +297,9 @@ static RI_CompareHashEntry *ri_HashCompareOp(Oid eq_opr, Oid typeid);
static void ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname,
int tgkind);
-static const RI_ConstraintInfo *ri_FetchConstraintInfo(Trigger *trigger,
- Relation trig_rel, bool rel_is_pk);
-static const RI_ConstraintInfo *ri_LoadConstraintInfo(Oid constraintOid);
+static RI_ConstraintInfo *ri_FetchConstraintInfo(Trigger *trigger,
+ Relation trig_rel, bool rel_is_pk);
+static RI_ConstraintInfo *ri_LoadConstraintInfo(Oid constraintOid);
static Oid get_ri_constraint_root(Oid constrOid);
static SPIPlanPtr ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes,
RI_QueryKey *qkey, Relation fk_rel, Relation pk_rel);
@@ -309,12 +309,12 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo,
TupleTableSlot *oldslot, TupleTableSlot *newslot,
bool is_restrict,
bool detectNewRows, int expect_OK);
-static void ri_FastPathCheck(const RI_ConstraintInfo *riinfo,
+static void ri_FastPathCheck(RI_ConstraintInfo *riinfo,
Relation fk_rel, TupleTableSlot *newslot);
-static void ri_FastPathBatchAdd(const RI_ConstraintInfo *riinfo,
+static void ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo,
Relation fk_rel, TupleTableSlot *newslot);
static void ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel,
- const RI_ConstraintInfo *riinfo);
+ RI_ConstraintInfo *riinfo);
static int ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot,
const RI_ConstraintInfo *riinfo, Relation fk_rel,
Snapshot snapshot, IndexScanDesc scandesc);
@@ -357,7 +357,7 @@ static void ri_FastPathTeardown(void);
static Datum
RI_FKey_check(TriggerData *trigdata)
{
- const RI_ConstraintInfo *riinfo;
+ RI_ConstraintInfo *riinfo;
Relation fk_rel;
Relation pk_rel;
TupleTableSlot *newslot;
@@ -2341,11 +2341,11 @@ ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
/*
* Fetch the RI_ConstraintInfo struct for the trigger's FK constraint.
*/
-static const RI_ConstraintInfo *
+static RI_ConstraintInfo *
ri_FetchConstraintInfo(Trigger *trigger, Relation trig_rel, bool rel_is_pk)
{
Oid constraintOid = trigger->tgconstraint;
- const RI_ConstraintInfo *riinfo;
+ RI_ConstraintInfo *riinfo;
/*
* Check that the FK constraint's OID is available; it might not be if
@@ -2395,7 +2395,7 @@ ri_FetchConstraintInfo(Trigger *trigger, Relation trig_rel, bool rel_is_pk)
/*
* Fetch or create the RI_ConstraintInfo struct for an FK constraint.
*/
-static const RI_ConstraintInfo *
+static RI_ConstraintInfo *
ri_LoadConstraintInfo(Oid constraintOid)
{
RI_ConstraintInfo *riinfo;
@@ -2777,7 +2777,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo,
* ri_FastPathBatchAdd().
*/
static void
-ri_FastPathCheck(const RI_ConstraintInfo *riinfo,
+ri_FastPathCheck(RI_ConstraintInfo *riinfo,
Relation fk_rel, TupleTableSlot *newslot)
{
Relation pk_rel;
@@ -2820,8 +2820,7 @@ ri_FastPathCheck(const RI_ConstraintInfo *riinfo,
{
/* Reload to ensure it's valid. */
riinfo = ri_LoadConstraintInfo(riinfo->constraint_id);
- ri_populate_fastpath_metadata((RI_ConstraintInfo *) riinfo,
- fk_rel, idx_rel);
+ ri_populate_fastpath_metadata(riinfo, fk_rel, idx_rel);
}
Assert(riinfo->fpmeta);
ri_ExtractValues(fk_rel, newslot, riinfo, false, pk_vals, pk_nulls);
@@ -2857,7 +2856,7 @@ ri_FastPathCheck(const RI_ConstraintInfo *riinfo,
* ri_FastPathEndBatch().
*/
static void
-ri_FastPathBatchAdd(const RI_ConstraintInfo *riinfo,
+ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo,
Relation fk_rel, TupleTableSlot *newslot)
{
RI_FastPathEntry *fpentry = ri_FastPathGetEntry(riinfo, fk_rel);
@@ -2884,7 +2883,7 @@ ri_FastPathBatchAdd(const RI_ConstraintInfo *riinfo,
*/
static void
ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel,
- const RI_ConstraintInfo *riinfo)
+ RI_ConstraintInfo *riinfo)
{
Relation pk_rel = fpentry->pk_rel;
Relation idx_rel = fpentry->idx_rel;
@@ -2941,8 +2940,7 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel,
{
/* Reload to ensure it's valid. */
riinfo = ri_LoadConstraintInfo(riinfo->constraint_id);
- ri_populate_fastpath_metadata((RI_ConstraintInfo *) riinfo,
- fk_rel, idx_rel);
+ ri_populate_fastpath_metadata(riinfo, fk_rel, idx_rel);
}
Assert(riinfo->fpmeta);
@@ -4147,7 +4145,7 @@ ri_FastPathEndBatch(void *arg)
if (entry->batch_count > 0)
{
Relation fk_rel = table_open(entry->fk_relid, AccessShareLock);
- const RI_ConstraintInfo *riinfo = ri_LoadConstraintInfo(entry->conoid);
+ RI_ConstraintInfo *riinfo = ri_LoadConstraintInfo(entry->conoid);
ri_FastPathBatchFlush(entry, fk_rel, riinfo);
table_close(fk_rel, NoLock);
--
2.53.0
Attachments:
[text/plain] 0001-Fix-some-const-qualifier-use-in-ri_triggers.c.patch (5.3K, 2-0001-Fix-some-const-qualifier-use-in-ri_triggers.c.patch)
download | inline diff:
From 35f273c812aa4f1345a3c1a9eb1443e3c7439254 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Mon, 20 Apr 2026 22:40:05 +0200
Subject: [PATCH] Fix some const qualifier use in ri_triggers.c
---
src/backend/utils/adt/ri_triggers.c | 34 ++++++++++++++---------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index e060280fcd4..f63a7f0b580 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -297,9 +297,9 @@ static RI_CompareHashEntry *ri_HashCompareOp(Oid eq_opr, Oid typeid);
static void ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname,
int tgkind);
-static const RI_ConstraintInfo *ri_FetchConstraintInfo(Trigger *trigger,
- Relation trig_rel, bool rel_is_pk);
-static const RI_ConstraintInfo *ri_LoadConstraintInfo(Oid constraintOid);
+static RI_ConstraintInfo *ri_FetchConstraintInfo(Trigger *trigger,
+ Relation trig_rel, bool rel_is_pk);
+static RI_ConstraintInfo *ri_LoadConstraintInfo(Oid constraintOid);
static Oid get_ri_constraint_root(Oid constrOid);
static SPIPlanPtr ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes,
RI_QueryKey *qkey, Relation fk_rel, Relation pk_rel);
@@ -309,12 +309,12 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo,
TupleTableSlot *oldslot, TupleTableSlot *newslot,
bool is_restrict,
bool detectNewRows, int expect_OK);
-static void ri_FastPathCheck(const RI_ConstraintInfo *riinfo,
+static void ri_FastPathCheck(RI_ConstraintInfo *riinfo,
Relation fk_rel, TupleTableSlot *newslot);
-static void ri_FastPathBatchAdd(const RI_ConstraintInfo *riinfo,
+static void ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo,
Relation fk_rel, TupleTableSlot *newslot);
static void ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel,
- const RI_ConstraintInfo *riinfo);
+ RI_ConstraintInfo *riinfo);
static int ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot,
const RI_ConstraintInfo *riinfo, Relation fk_rel,
Snapshot snapshot, IndexScanDesc scandesc);
@@ -357,7 +357,7 @@ static void ri_FastPathTeardown(void);
static Datum
RI_FKey_check(TriggerData *trigdata)
{
- const RI_ConstraintInfo *riinfo;
+ RI_ConstraintInfo *riinfo;
Relation fk_rel;
Relation pk_rel;
TupleTableSlot *newslot;
@@ -2341,11 +2341,11 @@ ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
/*
* Fetch the RI_ConstraintInfo struct for the trigger's FK constraint.
*/
-static const RI_ConstraintInfo *
+static RI_ConstraintInfo *
ri_FetchConstraintInfo(Trigger *trigger, Relation trig_rel, bool rel_is_pk)
{
Oid constraintOid = trigger->tgconstraint;
- const RI_ConstraintInfo *riinfo;
+ RI_ConstraintInfo *riinfo;
/*
* Check that the FK constraint's OID is available; it might not be if
@@ -2395,7 +2395,7 @@ ri_FetchConstraintInfo(Trigger *trigger, Relation trig_rel, bool rel_is_pk)
/*
* Fetch or create the RI_ConstraintInfo struct for an FK constraint.
*/
-static const RI_ConstraintInfo *
+static RI_ConstraintInfo *
ri_LoadConstraintInfo(Oid constraintOid)
{
RI_ConstraintInfo *riinfo;
@@ -2777,7 +2777,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo,
* ri_FastPathBatchAdd().
*/
static void
-ri_FastPathCheck(const RI_ConstraintInfo *riinfo,
+ri_FastPathCheck(RI_ConstraintInfo *riinfo,
Relation fk_rel, TupleTableSlot *newslot)
{
Relation pk_rel;
@@ -2820,8 +2820,7 @@ ri_FastPathCheck(const RI_ConstraintInfo *riinfo,
{
/* Reload to ensure it's valid. */
riinfo = ri_LoadConstraintInfo(riinfo->constraint_id);
- ri_populate_fastpath_metadata((RI_ConstraintInfo *) riinfo,
- fk_rel, idx_rel);
+ ri_populate_fastpath_metadata(riinfo, fk_rel, idx_rel);
}
Assert(riinfo->fpmeta);
ri_ExtractValues(fk_rel, newslot, riinfo, false, pk_vals, pk_nulls);
@@ -2857,7 +2856,7 @@ ri_FastPathCheck(const RI_ConstraintInfo *riinfo,
* ri_FastPathEndBatch().
*/
static void
-ri_FastPathBatchAdd(const RI_ConstraintInfo *riinfo,
+ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo,
Relation fk_rel, TupleTableSlot *newslot)
{
RI_FastPathEntry *fpentry = ri_FastPathGetEntry(riinfo, fk_rel);
@@ -2884,7 +2883,7 @@ ri_FastPathBatchAdd(const RI_ConstraintInfo *riinfo,
*/
static void
ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel,
- const RI_ConstraintInfo *riinfo)
+ RI_ConstraintInfo *riinfo)
{
Relation pk_rel = fpentry->pk_rel;
Relation idx_rel = fpentry->idx_rel;
@@ -2941,8 +2940,7 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel,
{
/* Reload to ensure it's valid. */
riinfo = ri_LoadConstraintInfo(riinfo->constraint_id);
- ri_populate_fastpath_metadata((RI_ConstraintInfo *) riinfo,
- fk_rel, idx_rel);
+ ri_populate_fastpath_metadata(riinfo, fk_rel, idx_rel);
}
Assert(riinfo->fpmeta);
@@ -4147,7 +4145,7 @@ ri_FastPathEndBatch(void *arg)
if (entry->batch_count > 0)
{
Relation fk_rel = table_open(entry->fk_relid, AccessShareLock);
- const RI_ConstraintInfo *riinfo = ri_LoadConstraintInfo(entry->conoid);
+ RI_ConstraintInfo *riinfo = ri_LoadConstraintInfo(entry->conoid);
ri_FastPathBatchFlush(entry, fk_rel, riinfo);
table_close(fk_rel, NoLock);
--
2.53.0
view thread (63+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
Subject: Re: Eliminating SPI / SQL from some RI triggers - take 3
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox