Re: backend crash with certain statements/tables - Mailing list pgsql-bugs
From | Tom Lane |
---|---|
Subject | Re: backend crash with certain statements/tables |
Date | |
Msg-id | 1675.1078253829@sss.pgh.pa.us Whole thread Raw |
In response to | Re: backend crash with certain statements/tables (Jeff Bohmer <bohmer@visionlink.org>) |
Responses |
Re: backend crash with certain statements/tables
|
List | pgsql-bugs |
Jeff Bohmer <bohmer@visionlink.org> writes: > Great! I'd like to try out the patch when it's ready. Here ya go. regards, tom lane Index: src/backend/executor/execAmi.c =================================================================== RCS file: /cvsroot/pgsql-server/src/backend/executor/execAmi.c,v retrieving revision 1.75.4.1 diff -c -r1.75.4.1 execAmi.c *** src/backend/executor/execAmi.c 18 Dec 2003 20:21:53 -0000 1.75.4.1 --- src/backend/executor/execAmi.c 2 Mar 2004 18:52:18 -0000 *************** *** 348,350 **** --- 348,415 ---- return false; } } + + /* + * ExecMayReturnRawTuples + * Check whether a plan tree may return "raw" disk tuples (that is, + * pointers to original data in disk buffers, as opposed to temporary + * tuples constructed by projection steps). In the case of Append, + * some subplans may return raw tuples and others projected tuples; + * we return "true" if any of the returned tuples could be raw. + * + * This must be passed an already-initialized planstate tree, because we + * need to look at the results of ExecAssignScanProjectionInfo(). + */ + bool + ExecMayReturnRawTuples(PlanState *node) + { + /* + * At a table scan node, we check whether ExecAssignScanProjectionInfo + * decided to do projection or not. Most non-scan nodes always project + * and so we can return "false" immediately. For nodes that don't + * project but just pass up input tuples, we have to recursively + * examine the input plan node. + * + * Note: Hash and Material are listed here because they sometimes + * return an original input tuple, not a copy. But Sort and SetOp + * never return an original tuple, so they can be treated like + * projecting nodes. + */ + switch (nodeTag(node)) + { + /* Table scan nodes */ + case T_SeqScanState: + case T_IndexScanState: + case T_TidScanState: + case T_SubqueryScanState: + case T_FunctionScanState: + if (node->ps_ProjInfo == NULL) + return true; + break; + + /* Non-projecting nodes */ + case T_HashState: + case T_MaterialState: + case T_UniqueState: + case T_LimitState: + return ExecMayReturnRawTuples(node->lefttree); + + case T_AppendState: + { + AppendState *appendstate = (AppendState *) node; + int j; + + for (j = 0; j < appendstate->as_nplans; j++) + { + if (ExecMayReturnRawTuples(appendstate->appendplans[j])) + return true; + } + break; + } + + /* All projecting node types come here */ + default: + break; + } + return false; + } Index: src/backend/executor/execMain.c =================================================================== RCS file: /cvsroot/pgsql-server/src/backend/executor/execMain.c,v retrieving revision 1.220.2.1 diff -c -r1.220.2.1 execMain.c *** src/backend/executor/execMain.c 22 Jan 2004 02:23:35 -0000 1.220.2.1 --- src/backend/executor/execMain.c 2 Mar 2004 18:52:18 -0000 *************** *** 665,674 **** /* * Initialize the junk filter if needed. SELECT and INSERT queries * need a filter if there are any junk attrs in the tlist. INSERT and ! * SELECT INTO also need a filter if the top plan node is a scan node ! * that's not doing projection (else we'll be scribbling on the scan ! * tuple!) UPDATE and DELETE always need a filter, since there's ! * always a junk 'ctid' attribute present --- no need to look first. */ { bool junk_filter_needed = false; --- 665,674 ---- /* * Initialize the junk filter if needed. SELECT and INSERT queries * need a filter if there are any junk attrs in the tlist. INSERT and ! * SELECT INTO also need a filter if the plan may return raw disk tuples ! * (else heap_insert will be scribbling on the source relation!). ! * UPDATE and DELETE always need a filter, since there's always a junk ! * 'ctid' attribute present --- no need to look first. */ { bool junk_filter_needed = false; *************** *** 689,706 **** } } if (!junk_filter_needed && ! (operation == CMD_INSERT || do_select_into)) ! { ! if (IsA(planstate, SeqScanState) || ! IsA(planstate, IndexScanState) || ! IsA(planstate, TidScanState) || ! IsA(planstate, SubqueryScanState) || ! IsA(planstate, FunctionScanState)) ! { ! if (planstate->ps_ProjInfo == NULL) ! junk_filter_needed = true; ! } ! } break; case CMD_UPDATE: case CMD_DELETE: --- 689,697 ---- } } if (!junk_filter_needed && ! (operation == CMD_INSERT || do_select_into) && ! ExecMayReturnRawTuples(planstate)) ! junk_filter_needed = true; break; case CMD_UPDATE: case CMD_DELETE: Index: src/include/executor/executor.h =================================================================== RCS file: /cvsroot/pgsql-server/src/include/executor/executor.h,v retrieving revision 1.102.2.2 diff -c -r1.102.2.2 executor.h *** src/include/executor/executor.h 22 Jan 2004 02:23:35 -0000 1.102.2.2 --- src/include/executor/executor.h 2 Mar 2004 18:52:19 -0000 *************** *** 36,41 **** --- 36,42 ---- extern void ExecRestrPos(PlanState *node); extern bool ExecSupportsMarkRestore(NodeTag plantype); extern bool ExecSupportsBackwardScan(Plan *node); + extern bool ExecMayReturnRawTuples(PlanState *node); /* * prototypes from functions in execGrouping.c
pgsql-bugs by date: