Commit 1bd159e4 authored by Tom Lane's avatar Tom Lane

Fix bogus coding of SET DEFAULT ri triggers ... or at least make it less

bogus than it was.  Per bug report from Adrian Pop.
parent 15b9e2c5
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
* *
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * 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 @@ ...@@ -37,6 +37,7 @@
#include "executor/spi_priv.h" #include "executor/spi_priv.h"
#include "optimizer/planmain.h" #include "optimizer/planmain.h"
#include "parser/parse_oper.h" #include "parser/parse_oper.h"
#include "rewrite/rewriteHandler.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "miscadmin.h" #include "miscadmin.h"
...@@ -2315,10 +2316,8 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS) ...@@ -2315,10 +2316,8 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
const char *qualsep; const char *qualsep;
Oid queryoids[RI_MAX_NUMKEYS]; Oid queryoids[RI_MAX_NUMKEYS];
Plan *spi_plan; Plan *spi_plan;
AttrDefault *defval; int i;
TargetEntry *spi_qptle; List *l;
int i,
j;
/* ---------- /* ----------
* The query string built is * The query string built is
...@@ -2355,45 +2354,31 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS) ...@@ -2355,45 +2354,31 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
*/ */
qplan = SPI_prepare(querystr, qkey.nkeypairs, queryoids); qplan = SPI_prepare(querystr, qkey.nkeypairs, queryoids);
/* ---------- /*
* Here now follows very ugly code depending on internals * Scan the plan's targetlist and replace the NULLs by
* of the SPI manager. * appropriate column defaults, if any (if not, they stay
* * NULL).
* EVIL EVIL EVIL (but must be - Jan)
* *
* We replace the CONST NULL targetlist expressions * XXX This is really ugly; it'd be better to use "UPDATE
* in the generated plan by (any) default values found * SET foo = DEFAULT", if we had it.
* in the tuple constructor.
* ----------
*/ */
spi_plan = (Plan *) lfirst(((_SPI_plan *) qplan)->ptlist); spi_plan = (Plan *) lfirst(((_SPI_plan *) qplan)->ptlist);
if (fk_rel->rd_att->constr != NULL) foreach(l, spi_plan->targetlist)
defval = fk_rel->rd_att->constr->defval;
else
defval = NULL;
for (i = 0; i < qkey.nkeypairs && defval != NULL; i++)
{ {
/* TargetEntry *tle = (TargetEntry *) lfirst(l);
* For each key attribute lookup the tuple constructor Node *dfl;
* 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; /* 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)
{
fix_opfuncids(dfl);
tle->expr = (Expr *) dfl;
} }
} }
} }
...@@ -2559,10 +2544,8 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS) ...@@ -2559,10 +2544,8 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
const char *qualsep; const char *qualsep;
Oid queryoids[RI_MAX_NUMKEYS]; Oid queryoids[RI_MAX_NUMKEYS];
Plan *spi_plan; Plan *spi_plan;
AttrDefault *defval; int i;
TargetEntry *spi_qptle; List *l;
int i,
j;
/* ---------- /* ----------
* The query string built is * The query string built is
...@@ -2610,50 +2593,30 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS) ...@@ -2610,50 +2593,30 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
qplan = SPI_prepare(querystr, qkey.nkeypairs, queryoids); qplan = SPI_prepare(querystr, qkey.nkeypairs, queryoids);
/* /*
* Now replace the CONST NULL targetlist expressions in * Scan the plan's targetlist and replace the NULLs by
* the generated plan by (any) default values found in the * appropriate column defaults, if any (if not, they stay
* tuple constructor. * 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); spi_plan = (Plan *) lfirst(((_SPI_plan *) qplan)->ptlist);
if (fk_rel->rd_att->constr != NULL) foreach(l, spi_plan->targetlist)
defval = fk_rel->rd_att->constr->defval;
else
defval = NULL;
for (i = 0; i < qkey.nkeypairs && defval != NULL; i++)
{ {
/* TargetEntry *tle = (TargetEntry *) lfirst(l);
* MATCH <unspecified> - only change columns Node *dfl;
* 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))
{
/*
* 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; /* 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)
{
fix_opfuncids(dfl);
tle->expr = (Expr *) dfl;
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment