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: