public inbox for [email protected]
help / color / mirror / Atom feedFrom: Antonin Houska <[email protected]>
Subject: [PATCH 2/5] Changed ri_GenerateQual() so it generates the whole qualifier.
Date: Fri, 5 Jun 2020 16:42:34 +0200
This way we can use the function to reduce the amount of copy&pasted code a
bit.
---
src/backend/utils/adt/ri_triggers.c | 435 ++++++++++++++--------------
1 file changed, 216 insertions(+), 219 deletions(-)
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 6220872126..f08a83067b 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -180,11 +180,31 @@ static Datum ri_restrict(TriggerData *trigdata, bool is_no_action);
static Datum ri_set(TriggerData *trigdata, bool is_set_null);
static void quoteOneName(char *buffer, const char *name);
static void quoteRelationName(char *buffer, Relation rel);
-static void ri_GenerateQual(StringInfo buf,
- const char *sep,
- const char *leftop, Oid leftoptype,
- Oid opoid,
- const char *rightop, Oid rightoptype);
+static char *ri_ColNameQuoted(const char *tabname, const char *attname);
+
+/*
+ * Use one of these values to tell ri_GenerateQual() where the parameter
+ * markers ($1, $2, ...) should appear in the qualifier.
+ */
+typedef enum GenQualParams
+{
+ GQ_PARAMS_NONE, /* No parameters, only attribute names. */
+ GQ_PARAMS_LEFT, /* The left side of the qual contains
+ * parameters. */
+ GQ_PARAMS_RIGHT, /* The right side of the qual contains
+ * parameters. */
+} GenQualParams;
+static void ri_GenerateQual(StringInfo buf, char *sep, int nkeys,
+ const char *ltabname, Relation lrel,
+ const int16 *lattnums,
+ const char *rtabname, Relation rrel,
+ const int16 *rattnums, const Oid *eq_oprs,
+ GenQualParams params, Oid *paramtypes);
+static void ri_GenerateQualComponent(StringInfo buf,
+ const char *sep,
+ const char *leftop, Oid leftoptype,
+ Oid opoid,
+ const char *rightop, Oid rightoptype);
static void ri_GenerateQualCollation(StringInfo buf, Oid collation);
static int ri_NullCheck(TupleDesc tupdesc, TupleTableSlot *slot,
const RI_ConstraintInfo *riinfo, bool rel_is_pk);
@@ -343,9 +363,6 @@ RI_FKey_check(TriggerData *trigdata)
{
StringInfoData querybuf;
char pkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
- char paramname[16];
- const char *querysep;
Oid queryoids[RI_MAX_NUMKEYS];
const char *pk_only;
@@ -361,25 +378,14 @@ RI_FKey_check(TriggerData *trigdata)
pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
quoteRelationName(pkrelname, pk_rel);
- appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x",
+ appendStringInfo(&querybuf, "SELECT 1 FROM %s%s p WHERE ",
pk_only, pkrelname);
- querysep = "WHERE";
- for (int i = 0; i < riinfo->nkeys; i++)
- {
- Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
- Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]);
-
- quoteOneName(attname,
- RIAttName(pk_rel, riinfo->pk_attnums[i]));
- sprintf(paramname, "$%d", i + 1);
- ri_GenerateQual(&querybuf, querysep,
- attname, pk_type,
- riinfo->pf_eq_oprs[i],
- paramname, fk_type);
- querysep = "AND";
- queryoids[i] = fk_type;
- }
- appendStringInfoString(&querybuf, " FOR KEY SHARE OF x");
+ ri_GenerateQual(&querybuf, "AND", riinfo->nkeys,
+ NULL, pk_rel, riinfo->pk_attnums,
+ NULL, fk_rel, riinfo->fk_attnums,
+ riinfo->pf_eq_oprs,
+ GQ_PARAMS_RIGHT, queryoids);
+ appendStringInfoString(&querybuf, " FOR KEY SHARE OF p");
/* Prepare and save the plan */
qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids,
@@ -476,9 +482,6 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
{
StringInfoData querybuf;
char pkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
- char paramname[16];
- const char *querysep;
const char *pk_only;
Oid queryoids[RI_MAX_NUMKEYS];
@@ -494,23 +497,15 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
quoteRelationName(pkrelname, pk_rel);
- appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x",
+ appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x WHERE ",
pk_only, pkrelname);
- querysep = "WHERE";
- for (int i = 0; i < riinfo->nkeys; i++)
- {
- Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
- quoteOneName(attname,
- RIAttName(pk_rel, riinfo->pk_attnums[i]));
- sprintf(paramname, "$%d", i + 1);
- ri_GenerateQual(&querybuf, querysep,
- attname, pk_type,
- riinfo->pp_eq_oprs[i],
- paramname, pk_type);
- querysep = "AND";
- queryoids[i] = pk_type;
- }
+ ri_GenerateQual(&querybuf, "AND", riinfo->nkeys,
+ NULL, pk_rel, riinfo->pk_attnums,
+ NULL, fk_rel, riinfo->fk_attnums,
+ riinfo->pf_eq_oprs,
+ GQ_PARAMS_RIGHT,
+ queryoids);
appendStringInfoString(&querybuf, " FOR KEY SHARE OF x");
/* Prepare and save the plan */
@@ -663,9 +658,6 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
{
StringInfoData querybuf;
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
- char paramname[16];
- const char *querysep;
Oid queryoids[RI_MAX_NUMKEYS];
const char *fk_only;
@@ -681,28 +673,16 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
quoteRelationName(fkrelname, fk_rel);
- appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x",
+ appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x WHERE ",
fk_only, fkrelname);
- querysep = "WHERE";
- for (int i = 0; i < riinfo->nkeys; i++)
- {
- Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
- 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]);
- quoteOneName(attname,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
- sprintf(paramname, "$%d", i + 1);
- ri_GenerateQual(&querybuf, querysep,
- paramname, pk_type,
- riinfo->pf_eq_oprs[i],
- attname, fk_type);
- if (pk_coll != fk_coll && !get_collation_isdeterministic(pk_coll))
- ri_GenerateQualCollation(&querybuf, pk_coll);
- querysep = "AND";
- queryoids[i] = pk_type;
- }
+ ri_GenerateQual(&querybuf, "AND", riinfo->nkeys,
+ NULL, pk_rel, riinfo->pk_attnums,
+ NULL, fk_rel, riinfo->fk_attnums,
+ riinfo->pf_eq_oprs,
+ GQ_PARAMS_LEFT,
+ queryoids);
+
appendStringInfoString(&querybuf, " FOR KEY SHARE OF x");
/* Prepare and save the plan */
@@ -775,9 +755,6 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
{
StringInfoData querybuf;
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
- char paramname[16];
- const char *querysep;
Oid queryoids[RI_MAX_NUMKEYS];
const char *fk_only;
@@ -792,28 +769,15 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
quoteRelationName(fkrelname, fk_rel);
- appendStringInfo(&querybuf, "DELETE FROM %s%s",
- fk_only, fkrelname);
- querysep = "WHERE";
- for (int i = 0; i < riinfo->nkeys; i++)
- {
- Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
- 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]);
- quoteOneName(attname,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
- sprintf(paramname, "$%d", i + 1);
- ri_GenerateQual(&querybuf, querysep,
- paramname, pk_type,
- riinfo->pf_eq_oprs[i],
- attname, fk_type);
- if (pk_coll != fk_coll && !get_collation_isdeterministic(pk_coll))
- ri_GenerateQualCollation(&querybuf, pk_coll);
- querysep = "AND";
- queryoids[i] = pk_type;
- }
+ appendStringInfo(&querybuf, "DELETE FROM %s%s WHERE ", fk_only,
+ fkrelname);
+ ri_GenerateQual(&querybuf, "AND", riinfo->nkeys,
+ NULL, pk_rel, riinfo->pk_attnums,
+ NULL, fk_rel, riinfo->fk_attnums,
+ riinfo->pf_eq_oprs,
+ GQ_PARAMS_LEFT,
+ queryoids);
/* Prepare and save the plan */
qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids,
@@ -924,10 +888,10 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
"%s %s = $%d",
querysep, attname, i + 1);
sprintf(paramname, "$%d", j + 1);
- ri_GenerateQual(&qualbuf, qualsep,
- paramname, pk_type,
- riinfo->pf_eq_oprs[i],
- attname, fk_type);
+ ri_GenerateQualComponent(&qualbuf, qualsep,
+ paramname, pk_type,
+ riinfo->pf_eq_oprs[i],
+ attname, fk_type);
if (pk_coll != fk_coll && !get_collation_isdeterministic(pk_coll))
ri_GenerateQualCollation(&querybuf, pk_coll);
querysep = ",";
@@ -1064,12 +1028,7 @@ ri_set(TriggerData *trigdata, bool is_set_null)
if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL)
{
StringInfoData querybuf;
- StringInfoData qualbuf;
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
- char paramname[16];
- const char *querysep;
- const char *qualsep;
Oid queryoids[RI_MAX_NUMKEYS];
const char *fk_only;
@@ -1082,39 +1041,32 @@ ri_set(TriggerData *trigdata, bool is_set_null)
* ----------
*/
initStringInfo(&querybuf);
- initStringInfo(&qualbuf);
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
quoteRelationName(fkrelname, fk_rel);
appendStringInfo(&querybuf, "UPDATE %s%s SET",
fk_only, fkrelname);
- querysep = "";
- qualsep = "WHERE";
+
for (int i = 0; i < riinfo->nkeys; i++)
{
- Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
- 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 attname[MAX_QUOTED_NAME_LEN];
+ const char *sep = i > 0 ? "," : "";
quoteOneName(attname,
RIAttName(fk_rel, riinfo->fk_attnums[i]));
+
appendStringInfo(&querybuf,
"%s %s = %s",
- querysep, attname,
+ sep, attname,
is_set_null ? "NULL" : "DEFAULT");
- sprintf(paramname, "$%d", i + 1);
- ri_GenerateQual(&qualbuf, qualsep,
- paramname, pk_type,
- riinfo->pf_eq_oprs[i],
- attname, fk_type);
- if (pk_coll != fk_coll && !get_collation_isdeterministic(pk_coll))
- ri_GenerateQualCollation(&querybuf, pk_coll);
- querysep = ",";
- qualsep = "AND";
- queryoids[i] = pk_type;
}
- appendBinaryStringInfo(&querybuf, qualbuf.data, qualbuf.len);
+
+ appendStringInfo(&querybuf, " WHERE ");
+ ri_GenerateQual(&querybuf, "AND", riinfo->nkeys,
+ NULL, pk_rel, riinfo->pk_attnums,
+ NULL, fk_rel, riinfo->fk_attnums,
+ riinfo->pf_eq_oprs,
+ GQ_PARAMS_LEFT, queryoids);
/* Prepare and save the plan */
qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids,
@@ -1402,31 +1354,14 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
appendStringInfo(&querybuf,
- " FROM %s%s fk LEFT OUTER JOIN %s%s pk ON",
+ " FROM %s%s fk LEFT OUTER JOIN %s%s pk ON (",
fk_only, fkrelname, pk_only, pkrelname);
- strcpy(pkattname, "pk.");
- strcpy(fkattname, "fk.");
- sep = "(";
- for (int i = 0; i < riinfo->nkeys; i++)
- {
- Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
- 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]);
-
- quoteOneName(pkattname + 3,
- RIAttName(pk_rel, riinfo->pk_attnums[i]));
- quoteOneName(fkattname + 3,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
- ri_GenerateQual(&querybuf, sep,
- pkattname, pk_type,
- riinfo->pf_eq_oprs[i],
- fkattname, fk_type);
- if (pk_coll != fk_coll)
- ri_GenerateQualCollation(&querybuf, pk_coll);
- sep = "AND";
- }
+ ri_GenerateQual(&querybuf, "AND", riinfo->nkeys,
+ "pk", pk_rel, riinfo->pk_attnums,
+ "fk", fk_rel, riinfo->fk_attnums,
+ riinfo->pf_eq_oprs,
+ GQ_PARAMS_NONE, NULL);
/*
* It's sufficient to test any one pk attribute for null to detect a join
@@ -1584,7 +1519,6 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
char *constraintDef;
char pkrelname[MAX_QUOTED_REL_NAME_LEN];
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char pkattname[MAX_QUOTED_NAME_LEN + 3];
char fkattname[MAX_QUOTED_NAME_LEN + 3];
const char *sep;
const char *fk_only;
@@ -1633,30 +1567,14 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
appendStringInfo(&querybuf,
- " FROM %s%s fk JOIN %s pk ON",
+ " FROM %s%s fk JOIN %s pk ON (",
fk_only, fkrelname, pkrelname);
- strcpy(pkattname, "pk.");
- strcpy(fkattname, "fk.");
- sep = "(";
- for (i = 0; i < riinfo->nkeys; i++)
- {
- Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
- 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]);
-
- quoteOneName(pkattname + 3,
- RIAttName(pk_rel, riinfo->pk_attnums[i]));
- quoteOneName(fkattname + 3,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
- ri_GenerateQual(&querybuf, sep,
- pkattname, pk_type,
- riinfo->pf_eq_oprs[i],
- fkattname, fk_type);
- if (pk_coll != fk_coll)
- ri_GenerateQualCollation(&querybuf, pk_coll);
- sep = "AND";
- }
+
+ ri_GenerateQual(&querybuf, "AND", riinfo->nkeys,
+ "pk", pk_rel, riinfo->pk_attnums,
+ "fk", fk_rel, riinfo->fk_attnums,
+ riinfo->pf_eq_oprs,
+ GQ_PARAMS_NONE, NULL);
/*
* Start the WHERE clause with the partition constraint (except if this is
@@ -1820,7 +1738,63 @@ quoteRelationName(char *buffer, Relation rel)
}
/*
- * ri_GenerateQual --- generate a WHERE clause equating two variables
+ * ri_GenerateQual --- generate WHERE/ON clause.
+ *
+ * Note: to avoid unnecessary explicit casts, make sure that the left and
+ * right operands match eq_oprs expect (ie don't swap the left and right
+ * operands accidentally).
+ */
+static void
+ri_GenerateQual(StringInfo buf, char *sep, int nkeys,
+ const char *ltabname, Relation lrel,
+ const int16 *lattnums,
+ const char *rtabname, Relation rrel,
+ const int16 *rattnums,
+ const Oid *eq_oprs,
+ GenQualParams params,
+ Oid *paramtypes)
+{
+ for (int i = 0; i < nkeys; i++)
+ {
+ Oid ltype = RIAttType(lrel, lattnums[i]);
+ Oid rtype = RIAttType(rrel, rattnums[i]);
+ Oid lcoll = RIAttCollation(lrel, lattnums[i]);
+ Oid rcoll = RIAttCollation(rrel, rattnums[i]);
+ char paramname[16];
+ char *latt,
+ *ratt;
+ char *sep_current = i > 0 ? sep : NULL;
+
+ if (params != GQ_PARAMS_NONE)
+ sprintf(paramname, "$%d", i + 1);
+
+ if (params == GQ_PARAMS_LEFT)
+ {
+ latt = paramname;
+ paramtypes[i] = ltype;
+ }
+ else
+ latt = ri_ColNameQuoted(ltabname, RIAttName(lrel, lattnums[i]));
+
+ if (params == GQ_PARAMS_RIGHT)
+ {
+ ratt = paramname;
+ paramtypes[i] = rtype;
+ }
+ else
+ ratt = ri_ColNameQuoted(rtabname, RIAttName(rrel, rattnums[i]));
+
+ ri_GenerateQualComponent(buf, sep_current, latt, ltype, eq_oprs[i],
+ ratt, rtype);
+
+ if (lcoll != rcoll)
+ ri_GenerateQualCollation(buf, lcoll);
+ }
+}
+
+/*
+ * ri_GenerateQual --- generate a component of WHERE/ON clause equating two
+ * variables, to be AND-ed to the other components.
*
* This basically appends " sep leftop op rightop" to buf, adding casts
* and schema qualification as needed to ensure that the parser will select
@@ -1828,17 +1802,86 @@ quoteRelationName(char *buffer, Relation rel)
* if they aren't variables or parameters.
*/
static void
-ri_GenerateQual(StringInfo buf,
- const char *sep,
- const char *leftop, Oid leftoptype,
- Oid opoid,
- const char *rightop, Oid rightoptype)
+ri_GenerateQualComponent(StringInfo buf,
+ const char *sep,
+ const char *leftop, Oid leftoptype,
+ Oid opoid,
+ const char *rightop, Oid rightoptype)
{
- appendStringInfo(buf, " %s ", sep);
+ if (sep)
+ appendStringInfo(buf, " %s ", sep);
generate_operator_clause(buf, leftop, leftoptype, opoid,
rightop, rightoptype);
}
+/*
+ * ri_ColNameQuoted() --- return column name, with both table and column name
+ * quoted.
+ */
+static char *
+ri_ColNameQuoted(const char *tabname, const char *attname)
+{
+ char quoted[MAX_QUOTED_NAME_LEN];
+ StringInfo result = makeStringInfo();
+
+ if (tabname && strlen(tabname) > 0)
+ {
+ quoteOneName(quoted, tabname);
+ appendStringInfo(result, "%s.", quoted);
+ }
+
+ quoteOneName(quoted, attname);
+ appendStringInfoString(result, quoted);
+
+ return result->data;
+}
+
+/*
+ * Check that RI trigger function was called in expected context
+ */
+static void
+ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
+{
+ TriggerData *trigdata = (TriggerData *) fcinfo->context;
+
+ if (!CALLED_AS_TRIGGER(fcinfo))
+ ereport(ERROR,
+ (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
+ errmsg("function \"%s\" was not called by trigger manager", funcname)));
+
+ /*
+ * Check proper event
+ */
+ if (!TRIGGER_FIRED_AFTER(trigdata->tg_event) ||
+ !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
+ ereport(ERROR,
+ (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
+ errmsg("function \"%s\" must be fired AFTER ROW", funcname)));
+
+ switch (tgkind)
+ {
+ case RI_TRIGTYPE_INSERT:
+ if (!TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
+ ereport(ERROR,
+ (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
+ errmsg("function \"%s\" must be fired for INSERT", funcname)));
+ break;
+ case RI_TRIGTYPE_UPDATE:
+ if (!TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ ereport(ERROR,
+ (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
+ errmsg("function \"%s\" must be fired for UPDATE", funcname)));
+ break;
+
+ case RI_TRIGTYPE_DELETE:
+ if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
+ ereport(ERROR,
+ (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
+ errmsg("function \"%s\" must be fired for DELETE", funcname)));
+ break;
+ }
+}
+
/*
* ri_GenerateQualCollation --- add a COLLATE spec to a WHERE clause
*
@@ -1909,52 +1952,6 @@ ri_BuildQueryKey(RI_QueryKey *key, const RI_ConstraintInfo *riinfo,
key->constr_queryno = constr_queryno;
}
-/*
- * Check that RI trigger function was called in expected context
- */
-static void
-ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
-{
- TriggerData *trigdata = (TriggerData *) fcinfo->context;
-
- if (!CALLED_AS_TRIGGER(fcinfo))
- ereport(ERROR,
- (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
- errmsg("function \"%s\" was not called by trigger manager", funcname)));
-
- /*
- * Check proper event
- */
- if (!TRIGGER_FIRED_AFTER(trigdata->tg_event) ||
- !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
- ereport(ERROR,
- (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
- errmsg("function \"%s\" must be fired AFTER ROW", funcname)));
-
- switch (tgkind)
- {
- case RI_TRIGTYPE_INSERT:
- if (!TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
- ereport(ERROR,
- (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
- errmsg("function \"%s\" must be fired for INSERT", funcname)));
- break;
- case RI_TRIGTYPE_UPDATE:
- if (!TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
- ereport(ERROR,
- (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
- errmsg("function \"%s\" must be fired for UPDATE", funcname)));
- break;
- case RI_TRIGTYPE_DELETE:
- if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
- ereport(ERROR,
- (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
- errmsg("function \"%s\" must be fired for DELETE", funcname)));
- break;
- }
-}
-
-
/*
* Fetch the RI_ConstraintInfo struct for the trigger's FK constraint.
*/
--
2.20.1
--=-=-=
Content-Type: text/x-diff
Content-Disposition: attachment;
filename=v02-0003-Return-early-from-ri_NullCheck-if-possible.patch
view thread (69+ 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]
Subject: Re: [PATCH 2/5] Changed ri_GenerateQual() so it generates the whole qualifier.
In-Reply-To: <no-message-id-1865465@localhost>
* 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