Re: postgres crashing on a seemingly good query - Mailing list pgsql-hackers

From Tom Lane
Subject Re: postgres crashing on a seemingly good query
Date
Msg-id 21198.1108841722@sss.pgh.pa.us
Whole thread Raw
In response to postgres crashing on a seemingly good query  (Abhijit Menon-Sen <ams@oryx.com>)
Responses Re: postgres crashing on a seemingly good query
List pgsql-hackers
Abhijit Menon-Sen <ams@oryx.com> writes:
> Summary: I can crash 7.4-CVS and 8.0/HEAD by sending what appears to be
> a valid query.

Good catch.  I've applied the attached patch (this is against 8.0/CVS
tip but applies with some fuzz to 7.4).
        regards, tom lane

*** src/backend/parser/analyze.c.orig    Fri Dec 31 17:45:54 2004
--- src/backend/parser/analyze.c    Sat Feb 19 13:57:51 2005
***************
*** 506,511 ****
--- 506,513 ----                     List **extras_before, List **extras_after) {     Query       *qry =
makeNode(Query);
+     Query       *selectQuery = NULL;
+     bool        copy_up_hack = false;     List       *sub_rtable;     List       *sub_namespace;     List
*icolumns;
***************
*** 561,567 ****          * be able to see.          */         ParseState *sub_pstate = make_parsestate(pstate);
-         Query       *selectQuery;         RangeTblEntry *rte;         RangeTblRef *rtr; 
--- 563,568 ----
***************
*** 608,614 ****         Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));         pstate->p_joinlist =
lappend(pstate->p_joinlist,rtr); 
 
!         /*          * Generate a targetlist for the INSERT that selects all the          * non-resjunk columns from
thesubquery.  (We need this to be          * separate from the subquery's tlist because we may add columns,
 
--- 609,615 ----         Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));         pstate->p_joinlist =
lappend(pstate->p_joinlist,rtr); 
 
!         /*----------          * Generate a targetlist for the INSERT that selects all the          * non-resjunk
columnsfrom the subquery.  (We need this to be          * separate from the subquery's tlist because we may add
columns,
***************
*** 618,625 ****          * are copied up as-is rather than being referenced as subquery          * outputs.  This is
toensure that when we try to coerce them to          * the target column's datatype, the right things happen (see
 
!          * special cases in coerce_type).  Otherwise, this fails: INSERT
!          * INTO foo SELECT 'bar', ... FROM baz          */         qry->targetList = NIL;         foreach(tl,
selectQuery->targetList)
--- 619,627 ----          * are copied up as-is rather than being referenced as subquery          * outputs.  This is
toensure that when we try to coerce them to          * the target column's datatype, the right things happen (see
 
!          * special cases in coerce_type).  Otherwise, this fails:
!          *        INSERT INTO foo SELECT 'bar', ... FROM baz
!          *----------          */         qry->targetList = NIL;         foreach(tl, selectQuery->targetList)
***************
*** 631,639 ****             if (resnode->resjunk)                 continue;             if (tle->expr &&
!                 (IsA(tle->expr, Const) ||IsA(tle->expr, Param)) &&                 exprType((Node *) tle->expr) ==
UNKNOWNOID)                expr = tle->expr;             else                 expr = (Expr *) makeVar(rtr->rtindex,
                                   resnode->resno,
 
--- 633,644 ----             if (resnode->resjunk)                 continue;             if (tle->expr &&
!                 (IsA(tle->expr, Const) || IsA(tle->expr, Param)) &&                 exprType((Node *) tle->expr) ==
UNKNOWNOID)
+             {                 expr = tle->expr;
+                 copy_up_hack = true;
+             }             else                 expr = (Expr *) makeVar(rtr->rtindex,
      resnode->resno,
 
***************
*** 702,707 ****
--- 707,734 ----         ereport(ERROR,                 (errcode(ERRCODE_SYNTAX_ERROR),              errmsg("INSERT has
moretarget columns than expressions")));
 
+ 
+     /*
+      * If we copied up any unknown Params (see HACK above) then their
+      * resolved types need to be propagated into the Resdom nodes of
+      * the sub-INSERT's tlist.  One hack begets another :-(
+      */
+     if (copy_up_hack)
+     {
+         foreach(tl, selectQuery->targetList)
+         {
+             TargetEntry *tle = (TargetEntry *) lfirst(tl);
+             Resdom       *resnode = tle->resdom;
+ 
+             if (resnode->resjunk)
+                 continue;
+             if (resnode->restype == UNKNOWNOID)
+             {
+                 resnode->restype = exprType((Node *) tle->expr);
+                 resnode->restypmod = exprTypmod((Node *) tle->expr);
+             }
+         }
+     }      /* done building the range table and jointree */     qry->rtable = pstate->p_rtable;


pgsql-hackers by date:

Previous
From: Jaime Casanova
Date:
Subject: Re: Data loss, vacuum, transaction wrap-around
Next
From: lsunley@mb.sympatico.ca
Date:
Subject: Re: Data loss, vacuum, transaction wrap-around