diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 0ef06cf7ecb5315a956069afb505730ed736f1dc..bc7c723ea2513bad17fa0569eebb26030a25ec65 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 - 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; } } }