Stephan Szabo <[EMAIL PROTECTED]> writes:
> That's because the set default uses a pretty ugly hack.  It plans the
> query with =NULL and then replaces the NULL with the default value's
> stored plan info.  My first guess is that it's something with this that's
> causing the crash.

I've applied the attached patch (for 7.3, cvs tip is a bit different)
to fix this problem.

                        regards, tom lane


*** src/backend/utils/adt/ri_triggers.c.orig    Thu Oct  3 17:06:23 2002
--- src/backend/utils/adt/ri_triggers.c Thu Mar 27 11:28:36 2003
***************
*** 35,41 ****
--- 35,43 ----
  #include "catalog/pg_operator.h"
  #include "commands/trigger.h"
  #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"
  
***************
*** 2672,2681 ****
                                const char *qualsep;
                                Oid                     queryoids[RI_MAX_NUMKEYS];
                                Plan       *spi_plan;
!                               AttrDefault *defval;
!                               TargetEntry *spi_qptle;
!                               int                     i,
!                                                       j;
  
                                /* ----------
                                 * The query string built is
--- 2674,2681 ----
                                const char *qualsep;
                                Oid                     queryoids[RI_MAX_NUMKEYS];
                                Plan       *spi_plan;
!                               int                     i;
!                               List       *l;
  
                                /* ----------
                                 * The query string built is
***************
*** 2712,2755 ****
                                 */
                                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)
                                 *
!                                * We replace the CONST NULL targetlist expressions
!                                * in the generated plan by (any) default values found
!                                * in the tuple constructor.
!                                * ----------
                                 */
                                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++)
                                {
!                                       /*
!                                        * 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);
  
!                                                       break;
!                                               }
                                        }
                                }
                        }
--- 2712,2742 ----
                                 */
                                qplan = SPI_prepare(querystr, qkey.nkeypairs, 
queryoids);
  
!                               /*
!                                * 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);
!                               foreach(l, spi_plan->targetlist)
                                {
!                                       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)
!                                       {
!                                               fix_opids(dfl);
!                                               tle->expr = dfl;
                                        }
                                }
                        }
***************
*** 2947,2956 ****
                                const char *qualsep;
                                Oid                     queryoids[RI_MAX_NUMKEYS];
                                Plan       *spi_plan;
!                               AttrDefault *defval;
!                               TargetEntry *spi_qptle;
!                               int                     i,
!                                                       j;
  
                                /* ----------
                                 * The query string built is
--- 2934,2941 ----
                                const char *qualsep;
                                Oid                     queryoids[RI_MAX_NUMKEYS];
                                Plan       *spi_plan;
!                               int                     i;
!                               List       *l;
  
                                /* ----------
                                 * The query string built is
***************
*** 2998,3046 ****
                                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.
                                 */
                                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++)
                                {
!                                       /*
!                                        * 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))
                                        {
!                                               /*
!                                                * 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);
! 
!                                                               break;
!                                                       }
!                                               }
                                        }
                                }
                        }
--- 2983,3012 ----
                                qplan = SPI_prepare(querystr, qkey.nkeypairs, 
queryoids);
  
                                /*
!                                * 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);
!                               foreach(l, spi_plan->targetlist)
                                {
!                                       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)
                                        {
!                                               fix_opids(dfl);
!                                               tle->expr = dfl;
                                        }
                                }
                        }


---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]

Reply via email to