diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-09-29 18:21:41 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-09-29 18:21:41 +0000 |
commit | 3a94e789f5c9537d804210be3cb26f7fb08e3b9e (patch) | |
tree | f1eac12405e3c0ded881d7dd7e59cec35b30c335 /src/include | |
parent | 6f64c2e54a0b14154a335249f4dca91a39c61c50 (diff) | |
download | postgresql-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.h | 4 | ||||
-rw-r--r-- | src/include/executor/nodeSubqueryscan.h | 25 | ||||
-rw-r--r-- | src/include/nodes/execnodes.h | 20 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 7 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 57 | ||||
-rw-r--r-- | src/include/nodes/pg_list.h | 20 | ||||
-rw-r--r-- | src/include/nodes/plannodes.h | 23 | ||||
-rw-r--r-- | src/include/nodes/primnodes.h | 52 | ||||
-rw-r--r-- | src/include/nodes/relation.h | 78 | ||||
-rw-r--r-- | src/include/optimizer/clauses.h | 8 | ||||
-rw-r--r-- | src/include/optimizer/pathnode.h | 10 | ||||
-rw-r--r-- | src/include/optimizer/paths.h | 5 | ||||
-rw-r--r-- | src/include/optimizer/plancat.h | 8 | ||||
-rw-r--r-- | src/include/optimizer/planmain.h | 5 | ||||
-rw-r--r-- | src/include/parser/parse_agg.h | 4 | ||||
-rw-r--r-- | src/include/parser/parse_node.h | 5 | ||||
-rw-r--r-- | src/include/parser/parse_relation.h | 10 | ||||
-rw-r--r-- | src/include/rewrite/locks.h | 24 | ||||
-rw-r--r-- | src/include/rewrite/rewriteManip.h | 9 | ||||
-rw-r--r-- | src/include/rewrite/rewriteSupport.h | 5 |
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 */ |