Skip to content

Instantly share code, notes, and snippets.

@jeltz
Created January 21, 2018 16:20
Show Gist options
  • Save jeltz/dfb41570af802f64faad841667151615 to your computer and use it in GitHub Desktop.
Save jeltz/dfb41570af802f64faad841667151615 to your computer and use it in GitHub Desktop.
commit 11eef04f83d6995c9e64654f99f0154f6f422348
Author: Andreas Karlsson <andreas@proxel.se>
Date: Sun Oct 29 01:35:34 2017 +0200
PoC
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index ed11c7a265..166d6c6970 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -2392,15 +2392,7 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
{
quoteOneName(fkattname,
RIAttName(fk_rel, riinfo->fk_attnums[i]));
- if (riinfo->has_array)
- if (riinfo->fk_reftypes[i] == FKCONSTR_REF_EACH_ELEMENT)
- appendStringInfo(&querybuf, "%sfk.ak%d %s", sep, i + 1,
- fkattname);
- else
- appendStringInfo(&querybuf, "%sfk.k%d %s", sep, i + 1,
- fkattname);
- else
- appendStringInfo(&querybuf, "%sfk.%s", sep, fkattname);
+ appendStringInfo(&querybuf, "%sfk.%s", sep, fkattname);
sep = ", ";
}
@@ -2409,24 +2401,21 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
if (riinfo->has_array)
{
- sep = "";
- appendStringInfo(&querybuf,
- " FROM (SELECT ");
+ appendStringInfo(&querybuf, " FROM ONLY %s fk", fkrelname);
for (i = 0; i < riinfo->nkeys; i++)
{
+ if (riinfo->fk_reftypes[i] != FKCONSTR_REF_EACH_ELEMENT)
+ continue;
+
quoteOneName(fkattname,
RIAttName(fk_rel, riinfo->fk_attnums[i]));
- if (riinfo->fk_reftypes[i] == FKCONSTR_REF_EACH_ELEMENT)
- appendStringInfo(&querybuf, "%spg_catalog.unnest(%s) k%d, %s ak%d",
- sep, fkattname, i + 1, fkattname, i + 1);
- else
- appendStringInfo(&querybuf, "%s%s k%d", sep, fkattname,
- i + 1);
- sep = ", ";
+ appendStringInfo(&querybuf,
+ " CROSS JOIN LATERAL pg_catalog.unnest(fk.%s) a (e)",
+ fkattname);
}
appendStringInfo(&querybuf,
- " FROM ONLY %s) fk LEFT OUTER JOIN ONLY %s pk ON",
- fkrelname, pkrelname);
+ " LEFT OUTER JOIN ONLY %s pk ON",
+ pkrelname);
}
else
appendStringInfo(&querybuf,
@@ -2442,18 +2431,22 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]);
Oid pk_coll = RIAttCollation(pk_rel, riinfo->pk_attnums[i]);
Oid fk_coll = RIAttCollation(fk_rel, riinfo->fk_attnums[i]);
+ char *tmp;
quoteOneName(pkattname + 3,
RIAttName(pk_rel, riinfo->pk_attnums[i]));
- if (riinfo->has_array)
- sprintf(fkattname + 3, "k%d", i + 1);
+ if (riinfo->fk_reftypes[i] == FKCONSTR_REF_EACH_ELEMENT)
+ tmp = "a.e";
else
+ {
quoteOneName(fkattname + 3,
RIAttName(fk_rel, riinfo->fk_attnums[i]));
+ tmp = fkattname;
+ }
ri_GenerateQual(&querybuf, sep,
pkattname, pk_type,
riinfo->pf_eq_oprs[i],
- fkattname, fk_type,
+ tmp, fk_type,
FKCONSTR_REF_PLAIN);
if (pk_coll != fk_coll)
ri_GenerateQualCollation(&querybuf, pk_coll);
@@ -2470,13 +2463,15 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
sep = "";
for (i = 0; i < riinfo->nkeys; i++)
{
- if (riinfo->has_array)
- sprintf(fkattname, "k%d", i + 1);
+ if (riinfo->fk_reftypes[i] == FKCONSTR_REF_EACH_ELEMENT)
+ appendStringInfo(&querybuf, "%sa.e IS NOT NULL", sep);
else
+ {
quoteOneName(fkattname, RIAttName(fk_rel, riinfo->fk_attnums[i]));
- appendStringInfo(&querybuf,
- "%sfk.%s IS NOT NULL",
- sep, fkattname);
+ appendStringInfo(&querybuf,
+ "%sfk.%s IS NOT NULL",
+ sep, fkattname);
+ }
switch (riinfo->confmatchtype)
{
case FKCONSTR_MATCH_SIMPLE:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment