summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-03-27 19:25:40 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-03-27 19:25:40 +0000
commit1bd159e4e985083520c54693c69905c12657119e (patch)
treef9c66bfee9cf64657873c212b009a0602c23658e /src
parent15b9e2c5ff7ba51288932b095f3f9949104143d6 (diff)
Fix bogus coding of SET DEFAULT ri triggers ... or at least make it less
bogus than it was. Per bug report from Adrian Pop.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/ri_triggers.c129
1 files changed, 46 insertions, 83 deletions
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 0ef06cf7ecb..bc7c723ea25 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -17,7 +17,7 @@
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.47 2003/03/15 21:19:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.48 2003/03/27 19:25:40 tgl Exp $
*
* ----------
*/
@@ -37,6 +37,7 @@
#include "executor/spi_priv.h"
#include "optimizer/planmain.h"
#include "parser/parse_oper.h"
+#include "rewrite/rewriteHandler.h"
#include "utils/lsyscache.h"
#include "miscadmin.h"
@@ -2315,10 +2316,8 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
const char *qualsep;
Oid queryoids[RI_MAX_NUMKEYS];
Plan *spi_plan;
- AttrDefault *defval;
- TargetEntry *spi_qptle;
- int i,
- j;
+ int i;
+ List *l;
/* ----------
* The query string built is
@@ -2355,45 +2354,31 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
*/
qplan = SPI_prepare(querystr, qkey.nkeypairs, queryoids);
- /* ----------
- * Here now follows very ugly code depending on internals
- * of the SPI manager.
- *
- * EVIL EVIL EVIL (but must be - Jan)
+ /*
+ * Scan the plan's targetlist and replace the NULLs by
+ * appropriate column defaults, if any (if not, they stay
+ * NULL).
*
- * We replace the CONST NULL targetlist expressions
- * in the generated plan by (any) default values found
- * in the tuple constructor.
- * ----------
+ * XXX This is really ugly; it'd be better to use "UPDATE
+ * SET foo = DEFAULT", if we had it.
*/
spi_plan = (Plan *) lfirst(((_SPI_plan *) qplan)->ptlist);
- if (fk_rel->rd_att->constr != NULL)
- defval = fk_rel->rd_att->constr->defval;
- else
- defval = NULL;
- for (i = 0; i < qkey.nkeypairs && defval != NULL; i++)
+ foreach(l, spi_plan->targetlist)
{
- /*
- * For each key attribute lookup the tuple constructor
- * for a corresponding default value
- */
- for (j = 0; j < fk_rel->rd_att->constr->num_defval; j++)
+ TargetEntry *tle = (TargetEntry *) lfirst(l);
+ Node *dfl;
+
+ /* Ignore any junk columns or Var=Var columns */
+ if (tle->resdom->resjunk)
+ continue;
+ if (IsA(tle->expr, Var))
+ continue;
+
+ dfl = build_column_default(fk_rel, tle->resdom->resno);
+ if (dfl)
{
- if (defval[j].adnum ==
- qkey.keypair[i][RI_KEYPAIR_FK_IDX])
- {
- /*
- * That's the one - push the expression from
- * defval.adbin into the plan's targetlist
- */
- spi_qptle = (TargetEntry *)
- nth(defval[j].adnum - 1,
- spi_plan->targetlist);
- spi_qptle->expr = stringToNode(defval[j].adbin);
- fix_opfuncids((Node *) spi_qptle->expr);
-
- break;
- }
+ fix_opfuncids(dfl);
+ tle->expr = (Expr *) dfl;
}
}
}
@@ -2559,10 +2544,8 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
const char *qualsep;
Oid queryoids[RI_MAX_NUMKEYS];
Plan *spi_plan;
- AttrDefault *defval;
- TargetEntry *spi_qptle;
- int i,
- j;
+ int i;
+ List *l;
/* ----------
* The query string built is
@@ -2610,50 +2593,30 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
qplan = SPI_prepare(querystr, qkey.nkeypairs, queryoids);
/*
- * Now replace the CONST NULL targetlist expressions in
- * the generated plan by (any) default values found in the
- * tuple constructor.
+ * Scan the plan's targetlist and replace the NULLs by
+ * appropriate column defaults, if any (if not, they stay
+ * NULL).
+ *
+ * XXX This is really ugly; it'd be better to use "UPDATE
+ * SET foo = DEFAULT", if we had it.
*/
spi_plan = (Plan *) lfirst(((_SPI_plan *) qplan)->ptlist);
- if (fk_rel->rd_att->constr != NULL)
- defval = fk_rel->rd_att->constr->defval;
- else
- defval = NULL;
- for (i = 0; i < qkey.nkeypairs && defval != NULL; i++)
+ foreach(l, spi_plan->targetlist)
{
- /*
- * MATCH <unspecified> - only change columns
- * corresponding to changed columns in pk_rel's key.
- * This conditional must match the one in the loop
- * above that built the SET attrn=NULL list.
- */
- if (match_type == RI_MATCH_TYPE_FULL ||
- !ri_OneKeyEqual(pk_rel, i, old_row,
- new_row, &qkey, RI_KEYPAIR_PK_IDX))
+ TargetEntry *tle = (TargetEntry *) lfirst(l);
+ Node *dfl;
+
+ /* Ignore any junk columns or Var=Var columns */
+ if (tle->resdom->resjunk)
+ continue;
+ if (IsA(tle->expr, Var))
+ continue;
+
+ dfl = build_column_default(fk_rel, tle->resdom->resno);
+ if (dfl)
{
- /*
- * For each key attribute lookup the tuple
- * constructor for a corresponding default value
- */
- for (j = 0; j < fk_rel->rd_att->constr->num_defval; j++)
- {
- if (defval[j].adnum ==
- qkey.keypair[i][RI_KEYPAIR_FK_IDX])
- {
- /*
- * That's the one - push the expression
- * from defval.adbin into the plan's
- * targetlist
- */
- spi_qptle = (TargetEntry *)
- nth(defval[j].adnum - 1,
- spi_plan->targetlist);
- spi_qptle->expr = stringToNode(defval[j].adbin);
- fix_opfuncids((Node *) spi_qptle->expr);
-
- break;
- }
- }
+ fix_opfuncids(dfl);
+ tle->expr = (Expr *) dfl;
}
}
}