提交 1bd159e4 编写于 作者: T 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.
上级 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
*/ /* Ignore any junk columns or Var=Var columns */
for (j = 0; j < fk_rel->rd_att->constr->num_defval; j++) 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 == fix_opfuncids(dfl);
qkey.keypair[i][RI_KEYPAIR_FK_IDX]) tle->expr = (Expr *) dfl;
{
/*
* 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;
}
} }
} }
} }
...@@ -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 /* Ignore any junk columns or Var=Var columns */
* above that built the SET attrn=NULL list. if (tle->resdom->resjunk)
*/ continue;
if (match_type == RI_MATCH_TYPE_FULL || if (IsA(tle->expr, Var))
!ri_OneKeyEqual(pk_rel, i, old_row, continue;
new_row, &qkey, RI_KEYPAIR_PK_IDX))
dfl = build_column_default(fk_rel, tle->resdom->resno);
if (dfl)
{ {
/* fix_opfuncids(dfl);
* For each key attribute lookup the tuple tle->expr = (Expr *) dfl;
* 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;
}
}
} }
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册