aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-09-29 18:21:41 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-09-29 18:21:41 +0000
commit3a94e789f5c9537d804210be3cb26f7fb08e3b9e (patch)
treef1eac12405e3c0ded881d7dd7e59cec35b30c335 /src/include
parent6f64c2e54a0b14154a335249f4dca91a39c61c50 (diff)
downloadpostgresql-3a94e789f5c9537d804210be3cb26f7fb08e3b9e.tar.gz
postgresql-3a94e789f5c9537d804210be3cb26f7fb08e3b9e.zip
Subselects in FROM clause, per ISO syntax: FROM (SELECT ...) [AS] alias.
(Don't forget that an alias is required.) Views reimplemented as expanding to subselect-in-FROM. Grouping, aggregates, DISTINCT in views actually work now (he says optimistically). No UNION support in subselects/views yet, but I have some ideas about that. Rule-related permissions checking moved out of rewriter and into executor. INITDB REQUIRED!
Diffstat (limited to 'src/include')
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/executor/nodeSubqueryscan.h25
-rw-r--r--src/include/nodes/execnodes.h20
-rw-r--r--src/include/nodes/nodes.h7
-rw-r--r--src/include/nodes/parsenodes.h57
-rw-r--r--src/include/nodes/pg_list.h20
-rw-r--r--src/include/nodes/plannodes.h23
-rw-r--r--src/include/nodes/primnodes.h52
-rw-r--r--src/include/nodes/relation.h78
-rw-r--r--src/include/optimizer/clauses.h8
-rw-r--r--src/include/optimizer/pathnode.h10
-rw-r--r--src/include/optimizer/paths.h5
-rw-r--r--src/include/optimizer/plancat.h8
-rw-r--r--src/include/optimizer/planmain.h5
-rw-r--r--src/include/parser/parse_agg.h4
-rw-r--r--src/include/parser/parse_node.h5
-rw-r--r--src/include/parser/parse_relation.h10
-rw-r--r--src/include/rewrite/locks.h24
-rw-r--r--src/include/rewrite/rewriteManip.h9
-rw-r--r--src/include/rewrite/rewriteSupport.h5
20 files changed, 254 insertions, 125 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index ab9ee67703c..c64b5a9a9de 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: catversion.h,v 1.47 2000/09/19 18:18:01 petere Exp $
+ * $Id: catversion.h,v 1.48 2000/09/29 18:21:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200009191
+#define CATALOG_VERSION_NO 200009281
#endif
diff --git a/src/include/executor/nodeSubqueryscan.h b/src/include/executor/nodeSubqueryscan.h
new file mode 100644
index 00000000000..c582384b8c3
--- /dev/null
+++ b/src/include/executor/nodeSubqueryscan.h
@@ -0,0 +1,25 @@
+/*-------------------------------------------------------------------------
+ *
+ * nodeSubqueryscan.h
+ *
+ *
+ *
+ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $Id: nodeSubqueryscan.h,v 1.1 2000/09/29 18:21:38 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef NODESUBQUERYSCAN_H
+#define NODESUBQUERYSCAN_H
+
+#include "nodes/plannodes.h"
+
+extern TupleTableSlot *ExecSubqueryScan(SubqueryScan *node);
+extern void ExecEndSubqueryScan(SubqueryScan *node);
+extern bool ExecInitSubqueryScan(SubqueryScan *node, EState *estate, Plan *parent);
+extern int ExecCountSlotsSubqueryScan(SubqueryScan *node);
+extern void ExecSubqueryReScan(SubqueryScan *node, ExprContext *exprCtxt, Plan *parent);
+
+#endif /* NODESUBQUERYSCAN_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 83ed6c5234b..65d35a2977e 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -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.49 2000/09/12 21:07:10 tgl Exp $
+ * $Id: execnodes.h,v 1.50 2000/09/29 18:21:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -453,6 +453,24 @@ typedef struct TidScanState
HeapTupleData tss_htup;
} TidScanState;
+/* ----------------
+ * SubqueryScanState information
+ *
+ * SubqueryScanState is used for scanning a sub-query in the range table.
+ * The sub-query will have its own EState, which we save here.
+ * ScanTupleSlot references the current output tuple of the sub-query.
+ *
+ * SubQueryDesc queryDesc for sub-query
+ * SubEState exec state for sub-query
+ * ----------------
+ */
+typedef struct SubqueryScanState
+{
+ CommonScanState csstate; /* its first field is NodeTag */
+ struct QueryDesc *sss_SubQueryDesc;
+ EState *sss_SubEState;
+} SubqueryScanState;
+
/* ----------------------------------------------------------------
* Join State Information
* ----------------------------------------------------------------
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index f3929d8b2c6..c72516477dc 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -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.76 2000/09/12 21:07:10 tgl Exp $
+ * $Id: nodes.h,v 1.77 2000/09/29 18:21:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -49,6 +49,7 @@ typedef enum NodeTag
T_Group,
T_SubPlan,
T_TidScan,
+ T_SubqueryScan,
/*---------------------
* TAGS FOR PRIMITIVE NODES (primnodes.h)
@@ -69,6 +70,7 @@ typedef enum NodeTag
T_Iter,
T_RelabelType,
T_RangeTblRef,
+ T_FromExpr,
T_JoinExpr,
/*---------------------
@@ -118,6 +120,7 @@ typedef enum NodeTag
T_UniqueState,
T_HashState,
T_TidScanState,
+ T_SubqueryScanState,
/*---------------------
* TAGS FOR MEMORY NODES (memnodes.h)
@@ -222,7 +225,7 @@ typedef enum NodeTag
T_oldJoinExprXXX, /* not used anymore; this tag# is available */
T_CaseExpr,
T_CaseWhen,
- T_RowMark,
+ T_RowMarkXXX, /* not used anymore; this tag# is available */
T_FkConstraint,
/*---------------------
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 440a7609d83..ab805406eca 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -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.113 2000/09/12 21:07:10 tgl Exp $
+ * $Id: parsenodes.h,v 1.114 2000/09/29 18:21:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,11 +50,12 @@ typedef struct Query
bool hasSubLinks; /* has subquery SubLink */
List *rtable; /* list of range table entries */
- List *jointree; /* table join tree (from the FROM clause) */
+ FromExpr *jointree; /* table join tree (FROM and WHERE clauses) */
List *targetList; /* target list (of TargetEntry) */
- Node *qual; /* qualifications applied to tuples */
- List *rowMark; /* list of RowMark entries */
+
+ List *rowMarks; /* integer list of RT indexes of relations
+ * that are selected FOR UPDATE */
List *distinctClause; /* a list of SortClause's */
@@ -1087,7 +1088,7 @@ typedef struct RangeSubselect
{
NodeTag type;
Node *subquery; /* the untransformed sub-select clause */
- Attr *name; /* optional table alias & column aliases */
+ Attr *name; /* table alias & optional column aliases */
} RangeSubselect;
/*
@@ -1141,15 +1142,22 @@ typedef struct TargetEntry
* RangeTblEntry -
* A range table is a List of RangeTblEntry nodes.
*
- * Some of the following are only used in one of
- * the parsing, optimizing, execution stages.
+ * Currently we use the same node type for both plain relation references
+ * and sub-selects in the FROM clause. It might be cleaner to abstract
+ * the common fields into a "superclass" nodetype.
*
* alias is an Attr node representing the AS alias-clause attached to the
* FROM expression, or NULL if no clause.
*
* eref is the table reference name and column reference names (either
- * real or aliases). This is filled in during parse analysis. Note that
- * system columns (OID etc) are not included in the column list.
+ * real or aliases). Note that system columns (OID etc) are not included
+ * in the column list.
+ * eref->relname is required to be present, and should generally be used
+ * to identify the RTE for error messages etc.
+ *
+ * inh is TRUE for relation references that should be expanded to include
+ * inheritance children, if the rel has any. This *must* be FALSE for
+ * subquery RTEs.
*
* inFromCl marks those range variables that are listed in the FROM clause.
* In SQL, the query can only refer to range variables listed in the
@@ -1160,18 +1168,37 @@ typedef struct TargetEntry
* implicitly-added RTE shouldn't change the namespace for unqualified
* column names processed later, and it also shouldn't affect the
* expansion of '*'.
+ *
+ * checkForRead, checkForWrite, and checkAsUser control run-time access
+ * permissions checks. A rel will be checked for read or write access
+ * (or both, or neither) per checkForRead and checkForWrite. If
+ * checkAsUser is not InvalidOid, then do the permissions checks using
+ * the access rights of that user, not the current effective user ID.
+ * (This allows rules to act as setuid gateways.)
*--------------------
*/
typedef struct RangeTblEntry
{
NodeTag type;
+ /*
+ * Fields valid for a plain relation RTE (else NULL/zero):
+ */
char *relname; /* real name of the relation */
Oid relid; /* OID of the relation */
+ /*
+ * Fields valid for a subquery RTE (else NULL):
+ */
+ Query *subquery; /* the sub-query */
+ /*
+ * Fields valid in all RTEs:
+ */
Attr *alias; /* user-written alias clause, if any */
Attr *eref; /* expanded reference names */
bool inh; /* inheritance requested? */
bool inFromCl; /* present in FROM clause */
- bool skipAcl; /* skip ACL check in executor */
+ bool checkForRead; /* check rel for read access */
+ bool checkForWrite; /* check rel for write access */
+ Oid checkAsUser; /* if not zero, check access as this user */
} RangeTblEntry;
/*
@@ -1206,14 +1233,4 @@ typedef struct SortClause
*/
typedef SortClause GroupClause;
-#define ROW_MARK_FOR_UPDATE (1 << 0)
-#define ROW_ACL_FOR_UPDATE (1 << 1)
-
-typedef struct RowMark
-{
- NodeTag type;
- Index rti; /* index in Query->rtable */
- bits8 info; /* as above */
-} RowMark;
-
#endif /* PARSENODES_H */
diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h
index 4e0bcfc7053..953f6edebee 100644
--- a/src/include/nodes/pg_list.h
+++ b/src/include/nodes/pg_list.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_list.h,v 1.19 2000/09/12 21:07:10 tgl Exp $
+ * $Id: pg_list.h,v 1.20 2000/09/29 18:21:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -92,6 +92,18 @@ typedef struct List
#define foreach(_elt_,_list_) \
for(_elt_=(_list_); _elt_!=NIL; _elt_=lnext(_elt_))
+/*
+ * Convenience macros for building fixed-length lists
+ */
+#define makeList1(x1) lcons(x1, NIL)
+#define makeList2(x1,x2) lcons(x1, makeList1(x2))
+#define makeList3(x1,x2,x3) lcons(x1, makeList2(x2,x3))
+#define makeList4(x1,x2,x3,x4) lcons(x1, makeList3(x2,x3,x4))
+
+#define makeListi1(x1) lconsi(x1, NIL)
+#define makeListi2(x1,x2) lconsi(x1, makeListi1(x2))
+#define makeListi3(x1,x2,x3) lconsi(x1, makeListi2(x2,x3))
+#define makeListi4(x1,x2,x3,x4) lconsi(x1, makeListi3(x2,x3,x4))
/*
* function prototypes in nodes/list.c
@@ -106,11 +118,11 @@ extern bool intMember(int datum, List *list);
extern Value *makeInteger(long i);
extern Value *makeFloat(char *numericStr);
extern Value *makeString(char *str);
-extern List *makeList(void *elem,...);
extern List *lappend(List *list, void *datum);
extern List *lappendi(List *list, int datum);
extern List *lremove(void *elem, List *list);
extern List *LispRemove(void *elem, List *list);
+extern List *lremovei(int elem, List *list);
extern List *ltruncate(int n, List *list);
extern void *nth(int n, List *l);
@@ -120,8 +132,8 @@ extern void set_nth(List *l, int n, void *elem);
extern List *set_difference(List *list1, List *list2);
extern List *set_differencei(List *list1, List *list2);
extern List *lreverse(List *l);
-extern List *LispUnion(List *list1, List *list2);
-extern List *LispUnioni(List *list1, List *list2);
+extern List *set_union(List *list1, List *list2);
+extern List *set_unioni(List *list1, List *list2);
extern bool sameseti(List *list1, List *list2);
extern bool nonoverlap_setsi(List *list1, List *list2);
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index cf93b9dee17..ca5727f0152 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -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.42 2000/09/12 21:07:10 tgl Exp $
+ * $Id: plannodes.h,v 1.43 2000/09/29 18:21:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,6 +31,7 @@
*
* Scan *** CommonScanState scanstate;
* IndexScan IndexScanState indxstate;
+ * SubqueryScan SubqueryScanState subquerystate;
*
* (*** nodes which inherit Scan also inherit scanstate)
*
@@ -202,6 +203,26 @@ typedef struct TidScan
TidScanState *tidstate;
} TidScan;
+/* ----------------
+ * subquery scan node
+ *
+ * SubqueryScan is for scanning the output of a sub-query in the range table.
+ * We need a special plan node above the sub-query's plan as a place to switch
+ * execution contexts. Although we are not scanning a physical relation,
+ * we make this a descendant of Scan anyway for code-sharing purposes.
+ *
+ * Note: we store the sub-plan in the type-specific subplan field, not in
+ * the generic lefttree field as you might expect. This is because we do
+ * not want plan-tree-traversal routines to recurse into the subplan without
+ * knowing that they are changing Query contexts.
+ * ----------------
+ */
+typedef struct SubqueryScan
+{
+ Scan scan;
+ Plan *subplan;
+} SubqueryScan;
+
/*
* ==========
* Join nodes
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index bc17773642c..62b65fee8b0 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: primnodes.h,v 1.48 2000/09/12 21:07:10 tgl Exp $
+ * $Id: primnodes.h,v 1.49 2000/09/29 18:21:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -495,24 +495,32 @@ typedef struct RelabelType
*
* The leaves of a join tree structure are RangeTblRef nodes. Above
* these, JoinExpr nodes can appear to denote a specific kind of join
- * or qualified join. A join tree can also contain List nodes --- a list
- * implies an unqualified cross-product join of its members. The planner
- * is allowed to combine the elements of a list using whatever join order
- * seems good to it. At present, JoinExpr nodes are always joined in
- * exactly the order implied by the tree structure (except the planner
- * may choose to swap inner and outer members of a join pair).
- *
- * NOTE: currently, the planner only supports a List at the top level of
- * a join tree. Should generalize this to allow Lists at lower levels.
+ * or qualified join. Also, FromExpr nodes can appear to denote an
+ * ordinary cross-product join ("FROM foo, bar, baz WHERE ...").
+ * FromExpr is like a JoinExpr of jointype JOIN_INNER, except that it
+ * may have any number of child nodes, not just two. Also, there is an
+ * implementation-defined difference: the planner is allowed to join the
+ * children of a FromExpr using whatever join order seems good to it.
+ * At present, JoinExpr nodes are always joined in exactly the order
+ * implied by the jointree structure (except the planner may choose to
+ * swap inner and outer members of a join pair).
+ *
+ * NOTE: the top level of a Query's jointree is always a FromExpr.
+ * Even if the jointree contains no rels, there will be a FromExpr.
*
* NOTE: the qualification expressions present in JoinExpr nodes are
- * *in addition to* the query's main WHERE clause. For outer joins there
- * is a real semantic difference between a join qual and a WHERE clause,
- * though if all joins are inner joins they are interchangeable.
+ * *in addition to* the query's main WHERE clause, which appears as the
+ * qual of the top-level FromExpr. The reason for associating quals with
+ * specific nodes in the jointree is that the position of a qual is critical
+ * when outer joins are present. (If we enforce a qual too soon or too late,
+ * that may cause the outer join to produce the wrong set of NULL-extended
+ * rows.) If all joins are inner joins then all the qual positions are
+ * semantically interchangeable.
*
* NOTE: in the raw output of gram.y, a join tree contains RangeVar and
* RangeSubselect nodes, which are both replaced by RangeTblRef nodes
- * during the parse analysis phase.
+ * during the parse analysis phase. Also, the top-level FromExpr is added
+ * during parse analysis; the grammar regards FROM and WHERE as separate.
* ----------------------------------------------------------------
*/
@@ -561,4 +569,20 @@ typedef struct JoinExpr
List *colvars; /* output column nodes (list of expressions) */
} JoinExpr;
+/*----------
+ * FromExpr - represents a FROM ... WHERE ... construct
+ *
+ * This is both more flexible than a JoinExpr (it can have any number of
+ * children, including zero) and less so --- we don't need to deal with
+ * aliases and so on. The output column set is implicitly just the union
+ * of the outputs of the children.
+ *----------
+ */
+typedef struct FromExpr
+{
+ NodeTag type;
+ List *fromlist; /* List of join subtrees */
+ Node *quals; /* qualifiers on join, if any */
+} FromExpr;
+
#endif /* PRIMNODES_H */
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 767e2e114e0..1c864f2e721 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -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.48 2000/09/12 21:07:10 tgl Exp $
+ * $Id: relation.h,v 1.49 2000/09/29 18:21:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,10 +35,20 @@ typedef enum CostSelector
STARTUP_COST, TOTAL_COST
} CostSelector;
-/*
+/*----------
* RelOptInfo
* 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.
+ * 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.
+ *
+ * Note that there is only one joinrel for any given set of component
+ * baserels, no matter what order we assemble them in; so an unordered
+ * set is the right datatype to identify it with.
+ *
* Parts of this data structure are specific to various scan and join
* mechanisms. It didn't seem worth creating new node types for them.
*
@@ -61,9 +71,16 @@ typedef enum CostSelector
*
* * If the relation is a base relation it will have these fields set:
*
- * indexed - true if the relation has secondary indices
- * pages - number of disk pages in relation
+ * issubquery - true if baserel is a subquery RTE rather than a table
+ * indexed - true if the relation has secondary indices (always false
+ * if it's a subquery)
+ * pages - number of disk pages in relation (zero if a subquery)
* tuples - number of tuples in relation (not considering restrictions)
+ * subplan - plan for subquery (NULL if it's a plain table)
+ *
+ * Note: for a subquery, tuples and subplan are not set immediately
+ * upon creation of the RelOptInfo object; they are filled in when
+ * set_base_rel_pathlist processes the object.
*
* * The presence of the remaining fields depends on the restrictions
* and joins that the relation participates in:
@@ -101,6 +118,7 @@ typedef enum CostSelector
* outerjoinset is used to ensure correct placement of WHERE clauses that
* apply to outer-joined relations; we must not apply such WHERE clauses
* until after the outer join is performed.
+ *----------
*/
typedef struct RelOptInfo
@@ -122,10 +140,12 @@ typedef struct RelOptInfo
struct Path *cheapest_total_path;
bool pruneable;
- /* statistics from pg_class (only valid if it's a base rel!) */
+ /* information about a base rel (not set for join rels!) */
+ bool issubquery;
bool indexed;
long pages;
double tuples;
+ struct Plan *subplan;
/* used by various scans and joins: */
List *baserestrictinfo; /* RestrictInfo structures (if
@@ -272,7 +292,8 @@ typedef struct Path
* included in the outer joinrel in order to make a usable join.
*
* 'alljoinquals' is also used only for inner paths of nestloop joins.
- * This flag is TRUE iff all the indexquals came from JOIN/ON conditions.
+ * This flag is TRUE iff all the indexquals came from non-pushed-down
+ * JOIN/ON conditions, which means the path is safe to use for an outer join.
*
* 'rows' is the estimated result tuple count for the indexscan. This
* is the same as path.parent->rows for a simple indexscan, but it is
@@ -375,10 +396,10 @@ typedef struct HashPath
* Restriction clause info.
*
* We create one of these for each AND sub-clause of a restriction condition
- * (WHERE clause). Since the restriction clauses are logically ANDed, we
- * can use any one of them or any subset of them to filter out tuples,
- * without having to evaluate the rest. The RestrictInfo node itself stores
- * data used by the optimizer while choosing the best query plan.
+ * (WHERE or JOIN/ON clause). Since the restriction clauses are logically
+ * ANDed, we can use any one of them or any subset of them to filter out
+ * tuples, without having to evaluate the rest. The RestrictInfo node itself
+ * stores data used by the optimizer while choosing the best query plan.
*
* If a restriction clause references a single base relation, it will appear
* in the baserestrictinfo list of the RelOptInfo for that base rel.
@@ -405,6 +426,31 @@ typedef struct HashPath
* sequence we use. So, these clauses cannot be associated directly with
* the join RelOptInfo, but must be kept track of on a per-join-path basis.
*
+ * When dealing with outer joins we have to be very careful about pushing qual
+ * clauses up and down the tree. An outer join's own JOIN/ON conditions must
+ * be evaluated exactly at that join node, and any quals appearing in WHERE or
+ * in a JOIN above the outer join cannot be pushed down below the outer join.
+ * Otherwise the outer join will produce wrong results because it will see the
+ * wrong sets of input rows. All quals are stored as RestrictInfo nodes
+ * during planning, but there's a flag to indicate whether a qual has been
+ * pushed down to a lower level than its original syntactic placement in the
+ * join tree would suggest. If an outer join prevents us from pushing a qual
+ * down to its "natural" semantic level (the level associated with just the
+ * base rels used in the qual) then the qual will appear in JoinInfo lists
+ * that reference more than just the base rels it actually uses. By
+ * pretending that the qual references all the rels appearing in the outer
+ * join, we prevent it from being evaluated below the outer join's joinrel.
+ * 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.
+ *
* In general, the referenced clause might be arbitrarily complex. The
* kinds of clauses we can handle as indexscan quals, mergejoin clauses,
* or hashjoin clauses are fairly limited --- the code for each kind of
@@ -415,16 +461,6 @@ 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 dealing with outer joins we must distinguish between qual clauses
- * that came from WHERE and those that came from JOIN/ON or JOIN/USING.
- * (For inner joins there's no semantic difference and we can treat the
- * clauses interchangeably.) Both kinds of quals are stored as RestrictInfo
- * nodes during planning, but there's a flag to indicate where they came from.
- * Note also that when outer joins are present, a qual clause may be treated
- * as referencing more rels than it really does. This trick ensures that the
- * qual will be evaluated at the right level of the join tree --- we don't
- * want quals from WHERE to be evaluated until after the outer join is done.
*/
typedef struct RestrictInfo
@@ -433,7 +469,7 @@ typedef struct RestrictInfo
Expr *clause; /* the represented clause of WHERE or JOIN */
- bool isjoinqual; /* TRUE if clause came from JOIN/ON */
+ bool ispusheddown; /* TRUE if clause was pushed down in level */
/* only used if clause is an OR clause: */
List *subclauseindices; /* indexes matching subclauses */
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 62bb401193d..881940f9a18 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: clauses.h,v 1.39 2000/09/12 21:07:11 tgl Exp $
+ * $Id: clauses.h,v 1.40 2000/09/29 18:21:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -43,6 +43,7 @@ extern Expr *get_notclausearg(Expr *notclause);
extern bool and_clause(Node *clause);
extern Expr *make_andclause(List *andclauses);
+extern Node *make_and_qual(Node *qual1, Node *qual2);
extern Expr *make_ands_explicit(List *andclauses);
extern List *make_ands_implicit(Expr *clause);
@@ -56,10 +57,7 @@ extern void check_subplans_for_ungrouped_vars(Node *clause, Query *query);
extern bool contain_noncachable_functions(Node *clause);
extern bool is_pseudo_constant_clause(Node *clause);
-
-extern List *pull_constant_clauses(List *quals,
- List **noncachableQual,
- List **constantQual);
+extern List *pull_constant_clauses(List *quals, List **constantQual);
extern void clause_get_relids_vars(Node *clause, Relids *relids, List **vars);
extern int NumRelids(Node *clause);
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index 0bf57ef0cc5..e5810a042f2 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* pathnode.h
- * prototypes for pathnode.c, indexnode.c, relnode.c.
+ * prototypes for pathnode.c, relnode.c.
*
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pathnode.h,v 1.28 2000/09/12 21:07:11 tgl Exp $
+ * $Id: pathnode.h,v 1.29 2000/09/29 18:21:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,6 +32,7 @@ extern IndexPath *create_index_path(Query *root, RelOptInfo *rel,
List *restriction_clauses,
ScanDirection indexscandir);
extern TidPath *create_tidscan_path(RelOptInfo *rel, List *tideval);
+extern Path *create_subqueryscan_path(RelOptInfo *rel);
extern NestPath *create_nestloop_path(RelOptInfo *joinrel,
JoinType jointype,
@@ -66,9 +67,4 @@ extern RelOptInfo *get_join_rel(Query *root, RelOptInfo *outer_rel,
RelOptInfo *inner_rel,
List **restrictlist_ptr);
-/*
- * prototypes for indexnode.h
- */
-extern List *find_relation_indices(Query *root, RelOptInfo *rel);
-
#endif /* PATHNODE_H */
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index 35eb3190f1c..327e63dd694 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: paths.h,v 1.47 2000/09/12 21:07:11 tgl Exp $
+ * $Id: paths.h,v 1.48 2000/09/29 18:21:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,6 +28,7 @@ extern bool enable_geqo;
extern int geqo_rels;
extern RelOptInfo *make_one_rel(Query *root);
+extern RelOptInfo *make_fromexpr_rel(Query *root, FromExpr *from);
/*
* indxpath.c
@@ -77,7 +78,7 @@ extern List *make_rels_by_clause_joins(Query *root,
extern List *make_rels_by_clauseless_joins(Query *root,
RelOptInfo *old_rel,
List *other_rels);
-extern RelOptInfo *make_rel_from_jointree(Query *root, Node *jtnode);
+extern RelOptInfo *make_jointree_rel(Query *root, Node *jtnode);
/*
* pathkeys.c
diff --git a/src/include/optimizer/plancat.h b/src/include/optimizer/plancat.h
index a5c09f4935f..c599114f4a9 100644
--- a/src/include/optimizer/plancat.h
+++ b/src/include/optimizer/plancat.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: plancat.h,v 1.19 2000/06/09 03:17:11 tgl Exp $
+ * $Id: plancat.h,v 1.20 2000/09/29 18:21:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,10 +17,10 @@
#include "nodes/relation.h"
-extern void relation_info(Query *root, Index relid,
- bool *hasindex, long *pages, double *tuples);
+extern void relation_info(Oid relationObjectId,
+ bool *hasindex, long *pages, double *tuples);
-extern List *find_secondary_indexes(Query *root, Index relid);
+extern List *find_secondary_indexes(Oid relationObjectId);
extern List *find_inheritance_children(Oid inhparent);
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index 43c93978cdf..e46d0bdbd84 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: planmain.h,v 1.44 2000/09/12 21:07:11 tgl Exp $
+ * $Id: planmain.h,v 1.45 2000/09/29 18:21:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -40,8 +40,7 @@ extern Result *make_result(List *tlist, Node *resconstantqual, Plan *subplan);
* prototypes for plan/initsplan.c
*/
extern void build_base_rel_tlists(Query *root, List *tlist);
-extern Relids add_join_quals_to_rels(Query *root, Node *jtnode);
-extern void add_restrict_and_join_to_rels(Query *root, List *clauses);
+extern Relids distribute_quals_to_rels(Query *root, Node *jtnode);
extern List *add_missing_rels_to_query(Query *root, Node *jtnode);
extern void process_implied_equality(Query *root, Node *item1, Node *item2,
Oid sortop1, Oid sortop2);
diff --git a/src/include/parser/parse_agg.h b/src/include/parser/parse_agg.h
index 2edc2fff705..cf85ec45850 100644
--- a/src/include/parser/parse_agg.h
+++ b/src/include/parser/parse_agg.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: parse_agg.h,v 1.15 2000/04/12 17:16:45 momjian Exp $
+ * $Id: parse_agg.h,v 1.16 2000/09/29 18:21:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include "parser/parse_node.h"
extern void AddAggToParseState(ParseState *pstate, Aggref *aggref);
-extern void parseCheckAggregates(ParseState *pstate, Query *qry);
+extern void parseCheckAggregates(ParseState *pstate, Query *qry, Node *qual);
extern Aggref *ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
List *args, bool agg_star, bool agg_distinct,
int precedence);
diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h
index 002391d6530..22dd797c7fb 100644
--- a/src/include/parser/parse_node.h
+++ b/src/include/parser/parse_node.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: parse_node.h,v 1.21 2000/09/12 21:07:12 tgl Exp $
+ * $Id: parse_node.h,v 1.22 2000/09/29 18:21:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,7 +23,8 @@ typedef struct ParseState
{
struct ParseState *parentParseState; /* stack link */
List *p_rtable; /* range table so far */
- List *p_jointree; /* join tree so far */
+ List *p_joinlist; /* join items so far (will become
+ * FromExpr node's fromlist) */
int p_last_resno; /* last targetlist resno assigned */
bool p_hasAggs;
bool p_hasSubLinks;
diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h
index 7c7a04844e4..981d4286930 100644
--- a/src/include/parser/parse_relation.h
+++ b/src/include/parser/parse_relation.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: parse_relation.h,v 1.19 2000/09/12 21:07:12 tgl Exp $
+ * $Id: parse_relation.h,v 1.20 2000/09/29 18:21:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,7 +27,7 @@ extern int refnameRangeTablePosn(ParseState *pstate,
extern int RTERangeTablePosn(ParseState *pstate,
RangeTblEntry *rte,
int *sublevels_up);
-extern JoinExpr *scanJoinTreeForRefname(Node *jtnode, char *refname);
+extern JoinExpr *scanJoinListForRefname(Node *jtnode, char *refname);
extern Node *colnameToVar(ParseState *pstate, char *colname);
extern Node *qualifiedNameToVar(ParseState *pstate, char *refname,
char *colname, bool implicitRTEOK);
@@ -36,7 +36,11 @@ extern RangeTblEntry *addRangeTableEntry(ParseState *pstate,
Attr *alias,
bool inh,
bool inFromCl);
-extern void addRTEtoJoinTree(ParseState *pstate, RangeTblEntry *rte);
+extern RangeTblEntry *addRangeTableEntryForSubquery(ParseState *pstate,
+ Query *subquery,
+ Attr *alias,
+ bool inFromCl);
+extern void addRTEtoJoinList(ParseState *pstate, RangeTblEntry *rte);
extern RangeTblEntry *addImplicitRTE(ParseState *pstate, char *relname);
extern void expandRTE(ParseState *pstate, RangeTblEntry *rte,
List **colnames, List **colvars);
diff --git a/src/include/rewrite/locks.h b/src/include/rewrite/locks.h
deleted file mode 100644
index bcc8863c44d..00000000000
--- a/src/include/rewrite/locks.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * locks.h
- *
- *
- *
- * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * $Id: locks.h,v 1.13 2000/01/26 05:58:30 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#ifndef LOCKS_H
-#define LOCKS_H
-
-#include "nodes/parsenodes.h"
-#include "rewrite/prs2lock.h"
-
-extern List *matchLocks(CmdType event, RuleLock *rulelocks, int varno,
- Query *parsetree);
-extern void checkLockPerms(List *locks, Query *parsetree, int rt_index);
-
-#endif /* LOCKS_H */
diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h
index c41519acb8c..2cfbf0e061f 100644
--- a/src/include/rewrite/rewriteManip.h
+++ b/src/include/rewrite/rewriteManip.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: rewriteManip.h,v 1.22 2000/09/12 21:07:15 tgl Exp $
+ * $Id: rewriteManip.h,v 1.23 2000/09/29 18:21:24 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,15 +31,12 @@ extern bool attribute_used(Node *node, int rt_index, int attno,
extern void AddQual(Query *parsetree, Node *qual);
extern void AddHavingQual(Query *parsetree, Node *havingQual);
extern void AddNotQual(Query *parsetree, Node *qual);
-extern void AddGroupClause(Query *parsetree, List *group_by, List *tlist);
extern bool checkExprHasAggs(Node *node);
extern bool checkExprHasSubLink(Node *node);
+extern Node *ResolveNew(Node *node, int target_varno, int sublevels_up,
+ List *targetlist, int event, int update_varno);
extern void FixNew(RewriteInfo *info, Query *parsetree);
-extern void HandleRIRAttributeRule(Query *parsetree, List *rtable,
- List *targetlist, int rt_index,
- int attr_num, int *modified, int *badsql);
-
#endif /* REWRITEMANIP_H */
diff --git a/src/include/rewrite/rewriteSupport.h b/src/include/rewrite/rewriteSupport.h
index 589f4245f74..39605df47ad 100644
--- a/src/include/rewrite/rewriteSupport.h
+++ b/src/include/rewrite/rewriteSupport.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: rewriteSupport.h,v 1.12 2000/06/30 07:04:04 tgl Exp $
+ * $Id: rewriteSupport.h,v 1.13 2000/09/29 18:21:24 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,6 +16,7 @@
extern int IsDefinedRewriteRule(char *ruleName);
-extern void setRelhasrulesInRelation(Oid relationId, bool relhasrules);
+extern void SetRelationRuleStatus(Oid relationId, bool relHasRules,
+ bool relIsBecomingView);
#endif /* REWRITESUPPORT_H */