1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-15 02:22:24 +03:00

Restructure building of join relation targetlists so that a join plan

node emits only those vars that are actually needed above it in the
plan tree.  (There were comments in the code suggesting that this was
done at some point in the dim past, but for a long time we have just
made join nodes emit everything that either input emitted.)  Aside from
being marginally more efficient, this fixes the problem noted by Peter
Eisentraut where a join above an IN-implemented-as-join might fail,
because the subplan targetlist constructed in the latter case didn't
meet the expectation of including everything.
Along the way, fix some places that were O(N^2) in the targetlist
length.  This is not all the trouble spots for wide queries by any
means, but it's a step forward.
This commit is contained in:
Tom Lane
2003-06-29 23:05:05 +00:00
parent cf883ea95c
commit 835bb975d8
16 changed files with 334 additions and 221 deletions

View File

@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.83 2003/05/28 16:03:56 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.84 2003/06/29 23:05:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,6 +26,7 @@
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/plancat.h"
#include "optimizer/tlist.h"
#include "parser/parsetree.h"
#include "rewrite/rewriteManip.h"
#include "utils/builtins.h"
@@ -44,7 +45,8 @@
* Given the Oid of the relation, return the following info into fields
* of the RelOptInfo struct:
*
* varlist list of physical columns (expressed as Vars)
* min_attr lowest valid AttrNumber
* max_attr highest valid AttrNumber
* indexlist list of IndexOptInfos for relation's indexes
* pages number of pages
* tuples number of tuples
@@ -52,49 +54,15 @@
void
get_relation_info(Oid relationObjectId, RelOptInfo *rel)
{
Relation relation;
Index varno = rel->relid;
Relation relation;
bool hasindex;
List *varlist = NIL;
List *indexinfos = NIL;
int attrno,
numattrs;
relation = heap_open(relationObjectId, AccessShareLock);
/*
* Make list of physical Vars. But if there are any dropped columns,
* punt and set varlist to NIL. (XXX Ideally we would like to include
* dropped columns so that the varlist models the physical tuples
* of the relation. However this creates problems for ExecTypeFromTL,
* which may be asked to build a tupdesc for a tlist that includes vars
* of no-longer-existent types. In theory we could dig out the required
* info from the pg_attribute entries of the relation, but that data is
* not readily available to ExecTypeFromTL. For now, punt and don't
* apply the physical-tlist optimization when there are dropped cols.)
*/
numattrs = RelationGetNumberOfAttributes(relation);
for (attrno = 1; attrno <= numattrs; attrno++)
{
Form_pg_attribute att_tup = relation->rd_att->attrs[attrno - 1];
if (att_tup->attisdropped)
{
/* found a dropped col, so punt */
varlist = NIL;
break;
}
varlist = lappend(varlist,
makeVar(varno,
attrno,
att_tup->atttypid,
att_tup->atttypmod,
0));
}
rel->varlist = varlist;
rel->min_attr = FirstLowInvalidHeapAttributeNumber + 1;
rel->max_attr = RelationGetNumberOfAttributes(relation);
/*
* Make list of indexes. Ignore indexes on system catalogs if told to.
@@ -199,6 +167,65 @@ get_relation_info(Oid relationObjectId, RelOptInfo *rel)
heap_close(relation, AccessShareLock);
}
/*
* build_physical_tlist
*
* Build a targetlist consisting of exactly the relation's user attributes,
* in order. The executor can special-case such tlists to avoid a projection
* step at runtime, so we use such tlists preferentially for scan nodes.
*
* Exception: if there are any dropped columns, we punt and return NIL.
* Ideally we would like to handle the dropped-column case too. However this
* creates problems for ExecTypeFromTL, which may be asked to build a tupdesc
* for a tlist that includes vars of no-longer-existent types. In theory we
* could dig out the required info from the pg_attribute entries of the
* relation, but that data is not readily available to ExecTypeFromTL.
* For now, we don't apply the physical-tlist optimization when there are
* dropped cols.
*/
List *
build_physical_tlist(Query *root, RelOptInfo *rel)
{
Index varno = rel->relid;
RangeTblEntry *rte = rt_fetch(varno, root->rtable);
Relation relation;
FastList tlist;
int attrno,
numattrs;
FastListInit(&tlist);
Assert(rte->rtekind == RTE_RELATION);
relation = heap_open(rte->relid, AccessShareLock);
numattrs = RelationGetNumberOfAttributes(relation);
for (attrno = 1; attrno <= numattrs; attrno++)
{
Form_pg_attribute att_tup = relation->rd_att->attrs[attrno - 1];
if (att_tup->attisdropped)
{
/* found a dropped col, so punt */
FastListInit(&tlist);
break;
}
FastAppend(&tlist,
create_tl_element(makeVar(varno,
attrno,
att_tup->atttypid,
att_tup->atttypmod,
0),
attrno));
}
heap_close(relation, AccessShareLock);
return FastListValue(&tlist);
}
/*
* restriction_selectivity
*