mirror of
https://github.com/postgres/postgres.git
synced 2025-11-22 12:22:45 +03:00
Restructure handling of inheritance queries so that they work with outer
joins, and clean things up a good deal at the same time. Append plan node no longer hacks on rangetable at runtime --- instead, all child tables are given their own RT entries during planning. Concept of multiple target tables pushed up into execMain, replacing bug-prone implementation within nodeAppend. Planner now supports generating Append plans for inheritance sets either at the top of the plan (the old way) or at the bottom. Expanding at the bottom is appropriate for tables used as sources, since they may appear inside an outer join; but we must still expand at the top when the target of an UPDATE or DELETE is an inheritance set, because we actually need a different targetlist and junkfilter for each target table in that case. Fortunately a target table can't be inside an outer join... Bizarre mutual recursion between union_planner and prepunion.c is gone --- in fact, union_planner doesn't really have much to do with union queries anymore, so I renamed it grouping_planner.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: execnodes.h,v 1.52 2000/10/26 21:38:12 tgl Exp $
|
||||
* $Id: execnodes.h,v 1.53 2000/11/12 00:37:01 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -52,31 +52,6 @@ typedef struct IndexInfo
|
||||
bool ii_Unique;
|
||||
} IndexInfo;
|
||||
|
||||
/* ----------------
|
||||
* RelationInfo information
|
||||
*
|
||||
* whenever we update an existing relation, we have to
|
||||
* update indices on the relation. The RelationInfo class
|
||||
* is used to hold all the information on result relations,
|
||||
* including indices.. -cim 10/15/89
|
||||
*
|
||||
* RangeTableIndex result relation's range table index
|
||||
* RelationDesc relation descriptor for result relation
|
||||
* NumIndices number indices existing on result relation
|
||||
* IndexRelationDescs array of relation descriptors for indices
|
||||
* IndexRelationInfo array of key/attr info for indices
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct RelationInfo
|
||||
{
|
||||
NodeTag type;
|
||||
Index ri_RangeTableIndex;
|
||||
Relation ri_RelationDesc;
|
||||
int ri_NumIndices;
|
||||
RelationPtr ri_IndexRelationDescs;
|
||||
IndexInfo **ri_IndexRelationInfo;
|
||||
} RelationInfo;
|
||||
|
||||
/* ----------------
|
||||
* ExprContext
|
||||
*
|
||||
@@ -116,8 +91,6 @@ typedef struct ExprContext
|
||||
/* Values to substitute for Aggref nodes in expression */
|
||||
Datum *ecxt_aggvalues; /* precomputed values for Aggref nodes */
|
||||
bool *ecxt_aggnulls; /* null flags for Aggref nodes */
|
||||
/* Range table that Vars in expression refer to --- seldom needed */
|
||||
List *ecxt_range_table;
|
||||
} ExprContext;
|
||||
|
||||
/*
|
||||
@@ -210,6 +183,35 @@ typedef struct JunkFilter
|
||||
AttrNumber *jf_cleanMap;
|
||||
} JunkFilter;
|
||||
|
||||
/* ----------------
|
||||
* ResultRelInfo information
|
||||
*
|
||||
* whenever we update an existing relation, we have to
|
||||
* update indices on the relation. The ResultRelInfo class
|
||||
* is used to hold all the information on result relations,
|
||||
* including indices.. -cim 10/15/89
|
||||
*
|
||||
* RangeTableIndex result relation's range table index
|
||||
* RelationDesc relation descriptor for result relation
|
||||
* NumIndices # of indices existing on result relation
|
||||
* IndexRelationDescs array of relation descriptors for indices
|
||||
* IndexRelationInfo array of key/attr info for indices
|
||||
* ConstraintExprs array of constraint-checking expressions
|
||||
* junkFilter for removing junk attributes from tuples
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct ResultRelInfo
|
||||
{
|
||||
NodeTag type;
|
||||
Index ri_RangeTableIndex;
|
||||
Relation ri_RelationDesc;
|
||||
int ri_NumIndices;
|
||||
RelationPtr ri_IndexRelationDescs;
|
||||
IndexInfo **ri_IndexRelationInfo;
|
||||
List **ri_ConstraintExprs;
|
||||
JunkFilter *ri_junkFilter;
|
||||
} ResultRelInfo;
|
||||
|
||||
/* ----------------
|
||||
* EState information
|
||||
*
|
||||
@@ -217,7 +219,7 @@ typedef struct JunkFilter
|
||||
*
|
||||
* range_table array of scan relation information
|
||||
*
|
||||
* result_relation_information for update queries
|
||||
* result_relation information for insert/update/delete queries
|
||||
*
|
||||
* into_relation_descriptor relation being retrieved "into"
|
||||
*
|
||||
@@ -227,10 +229,6 @@ typedef struct JunkFilter
|
||||
* tupleTable this is a pointer to an array
|
||||
* of pointers to tuples used by
|
||||
* the executor at any given moment.
|
||||
*
|
||||
* junkFilter contains information used to
|
||||
* extract junk attributes from a tuple.
|
||||
* (see JunkFilter above)
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct EState
|
||||
@@ -239,23 +237,24 @@ typedef struct EState
|
||||
ScanDirection es_direction;
|
||||
Snapshot es_snapshot;
|
||||
List *es_range_table;
|
||||
RelationInfo *es_result_relation_info;
|
||||
ResultRelInfo *es_result_relations; /* array of ResultRelInfos */
|
||||
int es_num_result_relations; /* length of array */
|
||||
ResultRelInfo *es_result_relation_info; /* currently active array elt */
|
||||
JunkFilter *es_junkFilter; /* currently active junk filter */
|
||||
Relation es_into_relation_descriptor;
|
||||
ParamListInfo es_param_list_info;
|
||||
ParamExecData *es_param_exec_vals; /* this is for subselects */
|
||||
TupleTable es_tupleTable;
|
||||
JunkFilter *es_junkFilter;
|
||||
uint32 es_processed; /* # of tuples processed */
|
||||
Oid es_lastoid; /* last oid processed (by INSERT) */
|
||||
List *es_rowMark; /* not good place, but there is no other */
|
||||
MemoryContext es_query_cxt; /* per-query context in which EState lives */
|
||||
/* this ExprContext is for per-output-tuple operations, such as
|
||||
/*
|
||||
* this ExprContext is for per-output-tuple operations, such as
|
||||
* constraint checks and index-value computations. It can be reset
|
||||
* for each output tuple. Note that it will be created only if needed.
|
||||
*/
|
||||
ExprContext *es_per_tuple_exprcontext;
|
||||
/* this field is storage space for ExecConstraints(): */
|
||||
List **es_result_relation_constraints;
|
||||
/* Below is to re-evaluate plan qual in READ COMMITTED mode */
|
||||
struct Plan *es_origPlan;
|
||||
Pointer es_evalPlanQual;
|
||||
@@ -341,15 +340,9 @@ typedef struct ResultState
|
||||
/* ----------------
|
||||
* AppendState information
|
||||
*
|
||||
* append nodes have this field "unionplans" which is this
|
||||
* list of plans to execute in sequence.. these variables
|
||||
* keep track of things..
|
||||
*
|
||||
* whichplan which plan is being executed
|
||||
* whichplan which plan is being executed (0 .. n-1)
|
||||
* nplans how many plans are in the list
|
||||
* initialized array of ExecInitNode() results
|
||||
* result_relation_info_list array of each subplan's result relation info
|
||||
* junkFilter_list array of each subplan's junk filter
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct AppendState
|
||||
@@ -358,8 +351,6 @@ typedef struct AppendState
|
||||
int as_whichplan;
|
||||
int as_nplans;
|
||||
bool *as_initialized;
|
||||
List *as_result_relation_info_list;
|
||||
List *as_junkFilter_list;
|
||||
} AppendState;
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: nodes.h,v 1.82 2000/11/05 22:50:21 vadim Exp $
|
||||
* $Id: nodes.h,v 1.83 2000/11/12 00:37:01 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -83,11 +83,12 @@ typedef enum NodeTag
|
||||
T_NestPath,
|
||||
T_MergePath,
|
||||
T_HashPath,
|
||||
T_TidPath,
|
||||
T_AppendPath,
|
||||
T_PathKeyItem,
|
||||
T_RestrictInfo,
|
||||
T_JoinInfo,
|
||||
T_Stream,
|
||||
T_TidPath,
|
||||
T_IndexOptInfo,
|
||||
|
||||
/*---------------------
|
||||
@@ -95,7 +96,7 @@ typedef enum NodeTag
|
||||
*---------------------
|
||||
*/
|
||||
T_IndexInfo = 300,
|
||||
T_RelationInfo,
|
||||
T_ResultRelInfo,
|
||||
T_TupleCount,
|
||||
T_TupleTableSlot,
|
||||
T_ExprContext,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parsenodes.h,v 1.119 2000/11/05 22:50:21 vadim Exp $
|
||||
* $Id: parsenodes.h,v 1.120 2000/11/12 00:37:01 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -70,6 +70,16 @@ typedef struct Query
|
||||
Node *setOperations; /* set-operation tree if this is top level
|
||||
* of a UNION/INTERSECT/EXCEPT query */
|
||||
|
||||
/*
|
||||
* If the resultRelation turns out to be the parent of an inheritance
|
||||
* tree, the planner will add all the child tables to the rtable and
|
||||
* store a list of the rtindexes of all the result relations here.
|
||||
* This is done at plan time, not parse time, since we don't want to
|
||||
* commit to the exact set of child tables at parse time. This field
|
||||
* ought to go in some sort of TopPlan plan node, not in the Query.
|
||||
*/
|
||||
List *resultRelations; /* integer list of RT indexes, or NIL */
|
||||
|
||||
/* internal to planner */
|
||||
List *base_rel_list; /* list of base-relation RelOptInfos */
|
||||
List *join_rel_list; /* list of join-relation RelOptInfos */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: plannodes.h,v 1.45 2000/10/26 21:38:12 tgl Exp $
|
||||
* $Id: plannodes.h,v 1.46 2000/11/12 00:37:01 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -134,8 +134,10 @@ typedef struct Plan
|
||||
|
||||
|
||||
/* ----------------
|
||||
* result node -
|
||||
* returns tuples from outer plan that satisfy the qualifications
|
||||
* Result node -
|
||||
* If no outer plan, evaluate a variable-free targetlist.
|
||||
* If outer plan, return tuples from outer plan that satisfy
|
||||
* given quals (we can also do a level of projection)
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct Result
|
||||
@@ -146,21 +148,21 @@ typedef struct Result
|
||||
} Result;
|
||||
|
||||
/* ----------------
|
||||
* append node
|
||||
* Append node -
|
||||
* Generate the concatenation of the results of sub-plans.
|
||||
*
|
||||
* Append nodes can modify the query's rtable during execution.
|
||||
* If inheritrelid > 0, then the RTE with index inheritrelid is replaced
|
||||
* by the i'th element of inheritrtable to execute the i'th subplan.
|
||||
* We assume that this RTE is not used in any other part of the
|
||||
* query plan tree, else confusion may result...
|
||||
* Append nodes are sometimes used to switch between several result relations
|
||||
* (when the target of an UPDATE or DELETE is an inheritance set). Such a
|
||||
* node will have isTarget true. The Append executor is then responsible
|
||||
* for updating the executor state to point at the correct target relation
|
||||
* whenever it switches subplans.
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct Append
|
||||
{
|
||||
Plan plan;
|
||||
List *appendplans;
|
||||
Index inheritrelid;
|
||||
List *inheritrtable;
|
||||
bool isTarget;
|
||||
AppendState *appendstate;
|
||||
} Append;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: relation.h,v 1.49 2000/09/29 18:21:39 tgl Exp $
|
||||
* $Id: relation.h,v 1.50 2000/11/12 00:37:01 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -82,6 +82,14 @@ typedef enum CostSelector
|
||||
* upon creation of the RelOptInfo object; they are filled in when
|
||||
* set_base_rel_pathlist processes the object.
|
||||
*
|
||||
* Note: if a base relation is the root of an inheritance tree
|
||||
* (SELECT FROM foo*) it is still considered a base rel. We will
|
||||
* generate a list of candidate Paths for accessing that table itself,
|
||||
* and also generate baserel RelOptInfo nodes for each child table,
|
||||
* with their own candidate Path lists. Then, an AppendPath is built
|
||||
* from the cheapest Path for each of these tables, and set to be the
|
||||
* only available Path for the inheritance baserel.
|
||||
*
|
||||
* * The presence of the remaining fields depends on the restrictions
|
||||
* and joins that the relation participates in:
|
||||
*
|
||||
@@ -313,6 +321,9 @@ typedef struct IndexPath
|
||||
double rows; /* estimated number of result tuples */
|
||||
} IndexPath;
|
||||
|
||||
/*
|
||||
* TidPath represents a scan by TID
|
||||
*/
|
||||
typedef struct TidPath
|
||||
{
|
||||
Path path;
|
||||
@@ -320,6 +331,17 @@ typedef struct TidPath
|
||||
Relids unjoined_relids;/* some rels not yet part of my Path */
|
||||
} TidPath;
|
||||
|
||||
/*
|
||||
* AppendPath represents an Append plan, ie, successive execution of
|
||||
* several member plans. Currently it is only used to handle expansion
|
||||
* of inheritance trees.
|
||||
*/
|
||||
typedef struct AppendPath
|
||||
{
|
||||
Path path;
|
||||
List *subpaths; /* list of component Paths */
|
||||
} AppendPath;
|
||||
|
||||
/*
|
||||
* All join-type paths share these fields.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user