]> granicus.if.org Git - postgresql/commitdiff
Fix bogus coding of SET DEFAULT ri triggers ... or at least make it less
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 Mar 2003 19:25:40 +0000 (19:25 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 Mar 2003 19:25:40 +0000 (19:25 +0000)
bogus than it was.  Per bug report from Adrian Pop.

src/backend/utils/adt/ri_triggers.c

index 0ef06cf7ecb5315a956069afb505730ed736f1dc..bc7c723ea2513bad17fa0569eebb26030a25ec65 100644 (file)
@@ -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;
                                        }
                                }
                        }