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: