diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2004-03-02 18:56:28 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2004-03-02 18:56:28 +0000 |
commit | 819bfac66ae3b0f567f278c734bb47e54d6e9bb4 (patch) | |
tree | bec56fdff5b229e5d8b2ba8e7d1c362ca298e112 /src/backend/executor/execAmi.c | |
parent | aff13a97148d227ebd4dd9986285a5e5b23a0595 (diff) | |
download | postgresql-819bfac66ae3b0f567f278c734bb47e54d6e9bb4.tar.gz postgresql-819bfac66ae3b0f567f278c734bb47e54d6e9bb4.zip |
Junkfilter logic to force a projection step during SELECT INTO was too
simplistic; it recognized SELECT * FROM but not SELECT * FROM LIMIT.
Per bug report from Jeff Bohmer.
Diffstat (limited to 'src/backend/executor/execAmi.c')
-rw-r--r-- | src/backend/executor/execAmi.c | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index 703709cee07..ca7797a37ed 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.75.4.1 2003/12/18 20:21:53 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.75.4.2 2004/03/02 18:56:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -348,3 +348,68 @@ ExecSupportsBackwardScan(Plan *node) 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; +} |