]> granicus.if.org Git - postgresql/blobdiff - src/include/nodes/relation.h
Desultory de-FastList-ification. RelOptInfo.reltargetlist is back to
[postgresql] / src / include / nodes / relation.h
index d3fb2231f1e99be2a4201207106158a6767d9555..91114fb03b76d54eaee381b1d5de8998fa5afad8 100644 (file)
@@ -4,10 +4,10 @@
  *       Definitions for planner's internal data structures.
  *
  *
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: relation.h,v 1.75 2003/01/12 22:35:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.95 2004/06/01 03:03:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #define RELATION_H
 
 #include "access/sdir.h"
+#include "nodes/bitmapset.h"
 #include "nodes/parsenodes.h"
 
+
 /*
  * Relids
- *             List of relation identifiers (indexes into the rangetable).
- *
- *             Note: these are lists of integers, not Nodes.
+ *             Set of relation identifiers (indexes into the rangetable).
  */
 
-typedef List *Relids;
+typedef Bitmapset *Relids;
 
 /*
  * When looking for a "cheapest path", this enum specifies whether we want
@@ -50,7 +50,7 @@ typedef struct QualCost
  *             Per-relation information for planning/optimization
  *
  * For planning purposes, a "base rel" is either a plain relation (a table)
- * or the output of a sub-SELECT that appears in the range table.
+ * or the output of a sub-SELECT or function that appears in the range table.
  * In either case it is uniquely identified by an RT index.  A "joinrel"
  * is the joining of two or more base rels.  A joinrel is identified by
  * the set of RT indexes for its component baserels.  We create RelOptInfo
@@ -63,14 +63,10 @@ typedef struct QualCost
  *
  * We also have "other rels", which are like base rels in that they refer to
  * single RT indexes; but they are not part of the join tree, and are stored
- * in other_rel_list not base_rel_list.  An otherrel is created for each
- * join RTE as an aid in processing Vars that refer to the join's outputs,
- * but it serves no other purpose in planning. It is important not to
- * confuse this otherrel with the joinrel that represents the matching set
- * of base relations.
- *
- * A second category of otherrels are those made for child relations of an
- * inheritance scan (SELECT FROM foo*).  The parent table's RTE and
+ * in other_rel_list not base_rel_list.
+ *
+ * Currently the only kind of otherrels are those made for child relations
+ * of an inheritance scan (SELECT FROM foo*).  The parent table's RTE and
  * corresponding baserel represent the whole result of the inheritance scan.
  * The planner creates separate RTEs and associated RelOptInfos for each child
  * table (including the parent table, in its capacity as a member of the
@@ -80,29 +76,41 @@ typedef struct QualCost
  * the inheritance set; then the parent baserel is given an Append plan
  * comprising the best plans for the individual child tables.
  *
+ * At one time we also made otherrels to represent join RTEs, for use in
+ * handling join alias Vars.  Currently this is not needed because all join
+ * alias Vars are expanded to non-aliased form during preprocess_expression.
+ *
  * Parts of this data structure are specific to various scan and join
  * mechanisms. It didn't seem worth creating new node types for them.
  *
- *             relids - List of base-relation identifiers; it is a base relation
+ *             relids - Set of base-relation identifiers; it is a base relation
  *                             if there is just one, a join relation if more than one
  *             rows - estimated number of tuples in the relation after restriction
  *                        clauses have been applied (ie, output rows of a plan for it)
  *             width - avg. number of bytes per tuple in the relation after the
  *                             appropriate projections have been done (ie, output width)
- *             targetlist - List of TargetEntry nodes for the attributes we need
- *                                      to output from this relation
+ *             reltargetlist - List of Var nodes for the attributes we need to
+ *                                             output from this relation (in no particular order)
  *             pathlist - List of Path nodes, one for each potentially useful
  *                                method of generating the relation
  *             cheapest_startup_path - the pathlist member with lowest startup cost
  *                                                             (regardless of its ordering)
  *             cheapest_total_path - the pathlist member with lowest total cost
  *                                                       (regardless of its ordering)
- *             pruneable - flag to let the planner know whether it can prune the
- *                                     pathlist of this RelOptInfo or not.
+ *             cheapest_unique_path - for caching cheapest path to produce unique
+ *                                                        (no duplicates) output from relation
  *
  * If the relation is a base relation it will have these fields set:
  *
+ *             relid - RTE index (this is redundant with the relids field, but
+ *                             is provided for convenience of access)
  *             rtekind - distinguishes plain relation, subquery, or function RTE
+ *             min_attr, max_attr - range of valid AttrNumbers for rel
+ *             attr_needed - array of bitmapsets indicating the highest joinrel
+ *                             in which each attribute is needed; if bit 0 is set then
+ *                             the attribute is needed as part of final targetlist
+ *             attr_widths - cache space for per-attribute width estimates;
+ *                                       zero means not computed yet
  *             indexlist - list of IndexOptInfo nodes for relation's indexes
  *                                     (always NIL if it's not a table)
  *             pages - number of disk pages in relation (zero if not a table)
@@ -114,15 +122,7 @@ typedef struct QualCost
  *             set_base_rel_pathlist processes the object.
  *
  *             For otherrels that are inheritance children, these fields are filled
- *             in just as for a baserel.  In otherrels for join RTEs, these fields
- *             are empty --- the only useful field of a join otherrel is its
- *             outerjoinset.
- *
- * If the relation is a join relation it will have these fields set:
- *
- *             joinrti - RT index of corresponding JOIN RTE, if any; 0 if none
- *             joinrteids - List of RT indexes of JOIN RTEs included in this join
- *                                      (including joinrti)
+ *             in just as for a baserel.
  *
  * The presence of the remaining fields depends on the restrictions
  * and joins that the relation participates in:
@@ -133,13 +133,12 @@ typedef struct QualCost
  *             baserestrictcost - Estimated cost of evaluating the baserestrictinfo
  *                                     clauses at a single tuple (only used for base rels)
  *             outerjoinset - For a base rel: if the rel appears within the nullable
- *                                     side of an outer join, the list of all relids
- *                                     participating in the highest such outer join; else NIL.
- *                                     For a join otherrel: the list of all baserel relids
- *                                     syntactically within the join.  Otherwise, unused.
+ *                                     side of an outer join, the set of all relids
+ *                                     participating in the highest such outer join; else NULL.
+ *                                     Otherwise, unused.
  *             joininfo  - List of JoinInfo nodes, containing info about each join
  *                                     clause in which this relation participates
- *             index_outer_relids - only used for base rels; list of outer relids
+ *             index_outer_relids - only used for base rels; set of outer relids
  *                                     that participate in indexable joinclauses for this rel
  *             index_inner_paths - only used for base rels; list of InnerIndexscanInfo
  *                                     nodes showing best indexpaths for various subsets of
@@ -170,7 +169,6 @@ typedef enum RelOptKind
 {
        RELOPT_BASEREL,
        RELOPT_JOINREL,
-       RELOPT_OTHER_JOIN_REL,
        RELOPT_OTHER_CHILD_REL
 } RelOptKind;
 
@@ -181,48 +179,49 @@ typedef struct RelOptInfo
        RelOptKind      reloptkind;
 
        /* all relations included in this RelOptInfo */
-       Relids          relids;                 /* integer list of base relids (rangetable
-                                                                * indexes) */
+       Relids          relids;                 /* set of base relids (rangetable indexes) */
 
        /* size estimates generated by planner */
        double          rows;                   /* estimated number of result tuples */
        int                     width;                  /* estimated avg width of result tuples */
 
        /* materialization information */
-       List       *targetlist;
+       List       *reltargetlist;      /* needed Vars */
        List       *pathlist;           /* Path structures */
        struct Path *cheapest_startup_path;
        struct Path *cheapest_total_path;
-       bool            pruneable;
+       struct Path *cheapest_unique_path;
 
        /* information about a base rel (not set for join rels!) */
+       Index           relid;
        RTEKind         rtekind;                /* RELATION, SUBQUERY, or FUNCTION */
+       AttrNumber      min_attr;               /* smallest attrno of rel (often <0) */
+       AttrNumber      max_attr;               /* largest attrno of rel */
+       Relids     *attr_needed;        /* array indexed [min_attr .. max_attr] */
+       int32      *attr_widths;        /* array indexed [min_attr .. max_attr] */
        List       *indexlist;
        long            pages;
        double          tuples;
        struct Plan *subplan;           /* if subquery */
 
-       /* information about a join rel (not set for base rels!) */
-       Index           joinrti;
-       List       *joinrteids;
-
        /* used by various scans and joins: */
        List       *baserestrictinfo;           /* RestrictInfo structures (if
                                                                                 * base rel) */
        QualCost        baserestrictcost;               /* cost of evaluating the above */
-       Relids          outerjoinset;   /* integer list of base relids */
+       Relids          outerjoinset;   /* set of base relids */
        List       *joininfo;           /* JoinInfo structures */
 
        /* cached info about inner indexscan paths for relation: */
        Relids          index_outer_relids;             /* other relids in indexable join
                                                                                 * clauses */
        List       *index_inner_paths;          /* InnerIndexscanInfo nodes */
+
        /*
-        * Inner indexscans are not in the main pathlist because they are
-        * not usable except in specific join contexts.  We use the
+        * Inner indexscans are not in the main pathlist because they are not
+        * usable except in specific join contexts.  We use the
         * index_inner_paths list just to avoid recomputing the best inner
-        * indexscan repeatedly for similar outer relations.  See comments
-        * for InnerIndexscanInfo.
+        * indexscan repeatedly for similar outer relations.  See comments for
+        * InnerIndexscanInfo.
         */
 } RelOptInfo;
 
@@ -234,15 +233,17 @@ typedef struct RelOptInfo
  *             and indexes, but that created confusion without actually doing anything
  *             useful.  So now we have a separate IndexOptInfo struct for indexes.
  *
- *             ncolumns and nkeys are the same except for a functional index,
- *             wherein ncolumns is 1 (the single function output) while nkeys
- *             is the number of table columns passed to the function. classlist[]
- *             and ordering[] have ncolumns entries, while indexkeys[] has nkeys
- *             entries.
+ *             classlist[], indexkeys[], and ordering[] have ncolumns entries.
+ *             Zeroes in the indexkeys[] array indicate index columns that are
+ *             expressions; there is one element in indexprs for each such column.
+ *
+ *             Note: for historical reasons, the classlist and ordering arrays have
+ *             an extra entry that is always zero.  Some code scans until it sees a
+ *             zero entry, rather than looking at ncolumns.
  *
- *             Note: for historical reasons, the arrays classlist, indexkeys and
- *             ordering have an extra entry that is always zero.  Some code scans
- *             until it sees a zero rather than looking at ncolumns or nkeys.
+ *             The indexprs and indpred expressions have been run through
+ *             prepqual.c and eval_const_expressions() for ease of matching to
+ *             WHERE clauses.  indpred is in implicit-AND form.
  */
 
 typedef struct IndexOptInfo
@@ -257,16 +258,18 @@ typedef struct IndexOptInfo
 
        /* index descriptor information */
        int                     ncolumns;               /* number of columns in index */
-       int                     nkeys;                  /* number of keys used by index */
        Oid                *classlist;          /* OIDs of operator classes for columns */
-       int                *indexkeys;          /* column numbers of index's keys */
+       int                *indexkeys;          /* column numbers of index's keys, or 0 */
        Oid                *ordering;           /* OIDs of sort operators for each column */
        Oid                     relam;                  /* OID of the access method (in pg_am) */
 
        RegProcedure amcostestimate;    /* OID of the access method's cost fcn */
 
-       Oid                     indproc;                /* OID of func if functional index, else 0 */
+       List       *indexprs;           /* expressions for non-simple index
+                                                                * columns */
        List       *indpred;            /* predicate if a partial index, else NIL */
+
+       bool            predOK;                 /* true if predicate matches query */
        bool            unique;                 /* true if a unique index */
 
        /* cached info about inner indexscan paths for index */
@@ -275,15 +278,6 @@ typedef struct IndexOptInfo
 } IndexOptInfo;
 
 
-/*
- * A Var is considered to belong to a relation if it's either from one
- * of the actual base rels making up the relation, or it's a join alias
- * var that is included in the relation.
- */
-#define VARISRELMEMBER(varno,rel) (intMember((varno), (rel)->relids) || \
-                                                                  intMember((varno), (rel)->joinrteids))
-
-
 /*
  * PathKeys
  *
@@ -305,9 +299,8 @@ typedef struct PathKeyItem
 
        /*
         * key typically points to a Var node, ie a relation attribute, but it
-        * can also point to a FuncExpr clause representing the value indexed by a
-        * functional index.  Someday we might allow arbitrary expressions as
-        * path keys, so don't assume more than you must.
+        * can also point to an arbitrary expression representing the value
+        * indexed by an index expression.
         */
 } PathKeyItem;
 
@@ -325,6 +318,8 @@ typedef struct Path
 {
        NodeTag         type;
 
+       NodeTag         pathtype;               /* tag identifying scan/join method */
+
        RelOptInfo *parent;                     /* the relation this path can build */
 
        /* estimated execution costs for path (see costsize.c for more info) */
@@ -333,8 +328,6 @@ typedef struct Path
        Cost            total_cost;             /* total cost (assuming all tuples
                                                                 * fetched) */
 
-       NodeTag         pathtype;               /* tag identifying scan/join method */
-
        List       *pathkeys;           /* sort ordering of path's output */
        /* pathkeys is a List of Lists of PathKeyItem nodes; see above */
 } Path;
@@ -348,14 +341,24 @@ typedef struct Path
  *
  * 'indexinfo' is a list of IndexOptInfo nodes, one per scan to be performed.
  *
- * 'indexqual' is a list of index qualifications, also one per scan.
- * Each entry in 'indexqual' is a sublist of qualification expressions with
- * implicit AND semantics across the sublist items.  Only expressions that
- * are usable as indexquals (as determined by indxpath.c) may appear here.
- * NOTE that the semantics of the top-level list in 'indexqual' is OR
+ * 'indexclauses' is a list of index qualifications, also one per scan.
+ * Each entry in 'indexclauses' is a sublist of qualification clauses to be
+ * used for that scan, with implicit AND semantics across the sublist items.
+ * NOTE that the semantics of the top-level list in 'indexclauses' is OR
  * combination, while the sublists are implicitly AND combinations!
- * Also note that indexquals lists do not contain RestrictInfo nodes,
- * just bare clause expressions.
+ *
+ * 'indexquals' has the same structure as 'indexclauses', but it contains
+ * the actual indexqual conditions that can be used with the index(es).
+ * In simple cases this is identical to 'indexclauses', but when special
+ * indexable operators appear in 'indexclauses', they are replaced by the
+ * derived indexscannable conditions in 'indexquals'.
+ *
+ * Both 'indexclauses' and 'indexquals' are lists of sublists of RestrictInfo
+ * nodes.  (Before 7.5, we kept bare operator expressions in these lists, but
+ * storing RestrictInfos is more efficient since selectivities can be cached.)
+ *
+ * 'isjoininner' is TRUE if the path is a nestloop inner scan (that is,
+ * some of the index conditions are join rather than restriction clauses).
  *
  * 'indexscandir' is one of:
  *             ForwardScanDirection: forward scan of an ordered index
@@ -376,13 +379,18 @@ typedef struct IndexPath
 {
        Path            path;
        List       *indexinfo;
-       List       *indexqual;
+       List       *indexclauses;
+       List       *indexquals;
+       bool            isjoininner;
        ScanDirection indexscandir;
        double          rows;                   /* estimated number of result tuples */
 } IndexPath;
 
 /*
  * TidPath represents a scan by TID
+ *
+ * tideval is an implicitly OR'ed list of quals of the form CTID = something.
+ * Note they are bare quals, not RestrictInfos.
  */
 typedef struct TidPath
 {
@@ -406,6 +414,8 @@ typedef struct AppendPath
  * variable-free targetlist or to gate execution of a subplan with a
  * one-time (variable-free) qual condition.  Note that in the former case
  * path.parent will be NULL; in the latter case it is copied from the subpath.
+ *
+ * Note that constantqual is a list of bare clauses, not RestrictInfos.
  */
 typedef struct ResultPath
 {
@@ -426,6 +436,34 @@ typedef struct MaterialPath
        Path       *subpath;
 } MaterialPath;
 
+/*
+ * UniquePath represents elimination of distinct rows from the output of
+ * its subpath.
+ *
+ * This is unlike the other Path nodes in that it can actually generate
+ * different plans: either hash-based or sort-based implementation, or a
+ * no-op if the input path can be proven distinct already.  The decision
+ * is sufficiently localized that it's not worth having separate Path node
+ * types.  (Note: in the no-op case, we could eliminate the UniquePath node
+ * entirely and just return the subpath; but it's convenient to have a
+ * UniquePath in the path tree to signal upper-level routines that the input
+ * is known distinct.)
+ */
+typedef enum
+{
+       UNIQUE_PATH_NOOP,                       /* input is known unique already */
+       UNIQUE_PATH_HASH,                       /* use hashing */
+       UNIQUE_PATH_SORT                        /* use sorting */
+} UniquePathMethod;
+
+typedef struct UniquePath
+{
+       Path            path;
+       Path       *subpath;
+       UniquePathMethod umethod;
+       double          rows;                   /* estimated number of result tuples */
+} UniquePath;
+
 /*
  * All join-type paths share these fields.
  */
@@ -457,9 +495,7 @@ typedef JoinPath NestPath;
  * A mergejoin path has these fields.
  *
  * path_mergeclauses lists the clauses (in the form of RestrictInfos)
- * that will be used in the merge.     (Before 7.0, this was a list of bare
- * clause expressions, but we can save on list memory and cost_qual_eval
- * work by leaving it in the form of a RestrictInfo list.)
+ * that will be used in the merge.
  *
  * Note that the mergeclauses are a subset of the parent relation's
  * restriction-clause list.  Any join clauses that are not mergejoinable
@@ -547,13 +583,17 @@ typedef struct HashPath
  * When we do form the outer join's joinrel, we still need to distinguish
  * those quals that are actually in that join's JOIN/ON condition from those
  * that appeared higher in the tree and were pushed down to the join rel
- * because they used no other rels.  That's what the ispusheddown flag is for;
- * it tells us that a qual came from a point above the join of the specific
- * set of base rels that it uses (or that the JoinInfo structures claim it
- * uses).  A clause that originally came from WHERE will *always* have its
- * ispusheddown flag set; a clause that came from an INNER JOIN condition,
- * but doesn't use all the rels being joined, will also have ispusheddown set
- * because it will get attached to some lower joinrel.
+ * because they used no other rels.  That's what the is_pushed_down flag is
+ * for; it tells us that a qual came from a point above the join of the
+ * specific set of base rels that it uses (or that the JoinInfo structures
+ * claim it uses).  A clause that originally came from WHERE will *always*
+ * have its is_pushed_down flag set; a clause that came from an INNER JOIN
+ * condition, but doesn't use all the rels being joined, will also have
+ * is_pushed_down set because it will get attached to some lower joinrel.
+ *
+ * We also store a valid_everywhere flag, which says that the clause is not
+ * affected by any lower-level outer join, and therefore any conditions it
+ * asserts can be presumed true throughout the plan tree.
  *
  * In general, the referenced clause might be arbitrarily complex.     The
  * kinds of clauses we can handle as indexscan quals, mergejoin clauses,
@@ -565,6 +605,12 @@ typedef struct HashPath
  * qual-expression-evaluation code.  (But we are still entitled to count
  * their selectivity when estimating the result tuple count, if we
  * can guess what it is...)
+ *
+ * When the referenced clause is an OR clause, we generate a modified copy
+ * in which additional RestrictInfo nodes are inserted below the top-level
+ * OR/AND structure.  This is a convenience for OR indexscan processing:
+ * indexquals taken from either the top level or an OR subclause will have
+ * associated RestrictInfo nodes.
  */
 
 typedef struct RestrictInfo
@@ -573,13 +619,30 @@ typedef struct RestrictInfo
 
        Expr       *clause;                     /* the represented clause of WHERE or JOIN */
 
-       bool            ispusheddown;   /* TRUE if clause was pushed down in level */
+       bool            is_pushed_down; /* TRUE if clause was pushed down in level */
+
+       bool            valid_everywhere;       /* TRUE if valid on every level */
+
+       /*
+        * This flag is set true if the clause looks potentially useful as a
+        * merge or hash join clause, that is if it is a binary opclause with
+        * nonoverlapping sets of relids referenced in the left and right sides.
+        * (Whether the operator is actually merge or hash joinable isn't
+        * checked, however.)
+        */
+       bool            can_join;
+
+       /* The set of relids (varnos) referenced in the clause: */
+       Relids          clause_relids;
+
+       /* These fields are set for any binary opclause: */
+       Relids          left_relids;    /* relids in left side of clause */
+       Relids          right_relids;   /* relids in right side of clause */
 
-       /* only used if clause is an OR clause: */
-       List       *subclauseindices;           /* indexes matching subclauses */
-       /* subclauseindices is a List of Lists of IndexOptInfos */
+       /* This field is NULL unless clause is an OR clause: */
+       Expr       *orclause;           /* modified clause with RestrictInfos */
 
-       /* cache space for costs (currently only used for join clauses) */
+       /* cache space for cost and selectivity */
        QualCost        eval_cost;              /* eval cost of clause; -1 if not yet set */
        Selectivity this_selec;         /* selectivity; -1 if not yet set */
 
@@ -634,7 +697,7 @@ typedef struct JoinInfo
  * relation includes all other relids appearing in those joinclauses.
  * The set of usable joinclauses, and thus the best inner indexscan,
  * thus varies depending on which outer relation we consider; so we have
- * to recompute the best such path for every join.  To avoid lots of
+ * to recompute the best such path for every join.     To avoid lots of
  * redundant computation, we cache the results of such searches.  For
  * each index we compute the set of possible otherrelids (all relids
  * appearing in joinquals that could become indexquals for this index).
@@ -660,7 +723,29 @@ typedef struct InnerIndexscanInfo
        Relids          other_relids;   /* a set of relevant other relids */
        bool            isouterjoin;    /* true if join is outer */
        /* Best path for this lookup key: */
-       Path       *best_innerpath;     /* best inner indexscan, or NULL if none */
+       Path       *best_innerpath; /* best inner indexscan, or NULL if none */
 } InnerIndexscanInfo;
 
+/*
+ * IN clause info.
+ *
+ * When we convert top-level IN quals into join operations, we must restrict
+ * the order of joining and use special join methods at some join points.
+ * We record information about each such IN clause in an InClauseInfo struct.
+ * These structs are kept in the Query node's in_info_list.
+ */
+
+typedef struct InClauseInfo
+{
+       NodeTag         type;
+       Relids          lefthand;               /* base relids in lefthand expressions */
+       Relids          righthand;              /* base relids coming from the subselect */
+       List       *sub_targetlist; /* targetlist of original RHS subquery */
+
+       /*
+        * Note: sub_targetlist is just a list of Vars or expressions; it does
+        * not contain TargetEntry nodes.
+        */
+} InClauseInfo;
+
 #endif   /* RELATION_H */