OSDN Git Service

26c465fd03740c488994823e578fa753da1d426a
[pg-rex/syncrep.git] / src / include / nodes / relation.h
1 /*-------------------------------------------------------------------------
2  *
3  * relation.h
4  *        Definitions for internal planner nodes.
5  *
6  *
7  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * $Id: relation.h,v 1.66 2002/08/19 15:08:47 tgl Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef RELATION_H
15 #define RELATION_H
16
17 #include "access/sdir.h"
18 #include "nodes/parsenodes.h"
19
20 /*
21  * Relids
22  *              List of relation identifiers (indexes into the rangetable).
23  *
24  *              Note: these are lists of integers, not Nodes.
25  */
26
27 typedef List *Relids;
28
29 /*
30  * When looking for a "cheapest path", this enum specifies whether we want
31  * cheapest startup cost or cheapest total cost.
32  */
33 typedef enum CostSelector
34 {
35         STARTUP_COST, TOTAL_COST
36 } CostSelector;
37
38 /*----------
39  * RelOptInfo
40  *              Per-relation information for planning/optimization
41  *
42  * For planning purposes, a "base rel" is either a plain relation (a table)
43  * or the output of a sub-SELECT that appears in the range table.
44  * In either case it is uniquely identified by an RT index.  A "joinrel"
45  * is the joining of two or more base rels.  A joinrel is identified by
46  * the set of RT indexes for its component baserels.  We create RelOptInfo
47  * nodes for each baserel and joinrel, and store them in the Query's
48  * base_rel_list and join_rel_list respectively.
49  *
50  * Note that there is only one joinrel for any given set of component
51  * baserels, no matter what order we assemble them in; so an unordered
52  * set is the right datatype to identify it with.
53  *
54  * We also have "other rels", which are like base rels in that they refer to
55  * single RT indexes; but they are not part of the join tree, and are stored
56  * in other_rel_list not base_rel_list.  An otherrel is created for each
57  * join RTE as an aid in processing Vars that refer to the join's outputs,
58  * but it serves no other purpose in planning.  It is important not to
59  * confuse this otherrel with the joinrel that represents the matching set
60  * of base relations.
61  *
62  * A second category of otherrels are those made for child relations of an
63  * inheritance scan (SELECT FROM foo*).  The parent table's RTE and
64  * corresponding baserel represent the whole result of the inheritance scan.
65  * The planner creates separate RTEs and associated RelOptInfos for each child
66  * table (including the parent table, in its capacity as a member of the
67  * inheritance set).  These RelOptInfos are physically identical to baserels,
68  * but are otherrels because they are not in the main join tree.  These added
69  * RTEs and otherrels are used to plan the scans of the individual tables in
70  * the inheritance set; then the parent baserel is given an Append plan
71  * comprising the best plans for the individual child tables.
72  *
73  * Parts of this data structure are specific to various scan and join
74  * mechanisms.  It didn't seem worth creating new node types for them.
75  *
76  *              relids - List of base-relation identifiers; it is a base relation
77  *                              if there is just one, a join relation if more than one
78  *              rows - estimated number of tuples in the relation after restriction
79  *                         clauses have been applied (ie, output rows of a plan for it)
80  *              width - avg. number of bytes per tuple in the relation after the
81  *                              appropriate projections have been done (ie, output width)
82  *              targetlist - List of TargetEntry nodes for the attributes we need
83  *                                       to output from this relation
84  *              pathlist - List of Path nodes, one for each potentially useful
85  *                                 method of generating the relation
86  *              cheapest_startup_path - the pathlist member with lowest startup cost
87  *                                                              (regardless of its ordering)
88  *              cheapest_total_path - the pathlist member with lowest total cost
89  *                                                        (regardless of its ordering)
90  *              pruneable - flag to let the planner know whether it can prune the
91  *                                      pathlist of this RelOptInfo or not.
92  *
93  * If the relation is a base relation it will have these fields set:
94  *
95  *              rtekind - distinguishes plain relation, subquery, or function RTE
96  *              indexlist - list of IndexOptInfo nodes for relation's indexes
97  *                                      (always NIL if it's not a table)
98  *              pages - number of disk pages in relation (zero if not a table)
99  *              tuples - number of tuples in relation (not considering restrictions)
100  *              subplan - plan for subquery (NULL if it's not a subquery)
101  *
102  *              Note: for a subquery, tuples and subplan are not set immediately
103  *              upon creation of the RelOptInfo object; they are filled in when
104  *              set_base_rel_pathlist processes the object.
105  *
106  *              For otherrels that are inheritance children, these fields are filled
107  *              in just as for a baserel.  In otherrels for join RTEs, these fields
108  *              are empty --- the only useful field of a join otherrel is its
109  *              outerjoinset.
110  *
111  * If the relation is a join relation it will have these fields set:
112  *
113  *              joinrti - RT index of corresponding JOIN RTE, if any; 0 if none
114  *              joinrteids - List of RT indexes of JOIN RTEs included in this join
115  *                                       (including joinrti)
116  *
117  * The presence of the remaining fields depends on the restrictions
118  * and joins that the relation participates in:
119  *
120  *              baserestrictinfo - List of RestrictInfo nodes, containing info about
121  *                                      each qualification clause in which this relation
122  *                                      participates (only used for base rels)
123  *              baserestrictcost - Estimated cost of evaluating the baserestrictinfo
124  *                                      clauses at a single tuple (only used for base rels)
125  *              outerjoinset - For a base rel: if the rel appears within the nullable
126  *                                      side of an outer join, the list of all relids
127  *                                      participating in the highest such outer join; else NIL.
128  *                                      For a join otherrel: the list of all baserel relids
129  *                                      syntactically within the join.  Otherwise, unused.
130  *              joininfo  - List of JoinInfo nodes, containing info about each join
131  *                                      clause in which this relation participates
132  *              innerjoin - List of Path nodes that represent indices that may be used
133  *                                      as inner paths of nestloop joins. This field is non-null
134  *                                      only for base rels, since join rels have no indices.
135  *
136  * Note: Keeping a restrictinfo list in the RelOptInfo is useful only for
137  * base rels, because for a join rel the set of clauses that are treated as
138  * restrict clauses varies depending on which sub-relations we choose to join.
139  * (For example, in a 3-base-rel join, a clause relating rels 1 and 2 must be
140  * treated as a restrictclause if we join {1} and {2 3} to make {1 2 3}; but
141  * if we join {1 2} and {3} then that clause will be a restrictclause in {1 2}
142  * and should not be processed again at the level of {1 2 3}.)  Therefore,
143  * the restrictinfo list in the join case appears in individual JoinPaths
144  * (field joinrestrictinfo), not in the parent relation.  But it's OK for
145  * the RelOptInfo to store the joininfo lists, because those are the same
146  * for a given rel no matter how we form it.
147  *
148  * We store baserestrictcost in the RelOptInfo (for base relations) because
149  * we know we will need it at least once (to price the sequential scan)
150  * and may need it multiple times to price index scans.
151  *
152  * outerjoinset is used to ensure correct placement of WHERE clauses that
153  * apply to outer-joined relations; we must not apply such WHERE clauses
154  * until after the outer join is performed.
155  *----------
156  */
157 typedef enum RelOptKind
158 {
159         RELOPT_BASEREL,
160         RELOPT_JOINREL,
161         RELOPT_OTHER_JOIN_REL,
162         RELOPT_OTHER_CHILD_REL
163 } RelOptKind;
164
165 typedef struct RelOptInfo
166 {
167         NodeTag         type;
168
169         RelOptKind      reloptkind;
170
171         /* all relations included in this RelOptInfo */
172         Relids          relids;                 /* integer list of base relids (RT
173                                                                  * indexes) */
174
175         /* size estimates generated by planner */
176         double          rows;                   /* estimated number of result tuples */
177         int                     width;                  /* estimated avg width of result tuples */
178
179         /* materialization information */
180         List       *targetlist;
181         List       *pathlist;           /* Path structures */
182         struct Path *cheapest_startup_path;
183         struct Path *cheapest_total_path;
184         bool            pruneable;
185
186         /* information about a base rel (not set for join rels!) */
187         RTEKind         rtekind;                /* RELATION, SUBQUERY, or FUNCTION */
188         List       *indexlist;
189         long            pages;
190         double          tuples;
191         struct Plan *subplan;           /* if subquery */
192
193         /* information about a join rel (not set for base rels!) */
194         Index           joinrti;
195         List       *joinrteids;
196
197         /* used by various scans and joins: */
198         List       *baserestrictinfo;           /* RestrictInfo structures (if
199                                                                                  * base rel) */
200         Cost            baserestrictcost;               /* cost of evaluating the above */
201         Relids          outerjoinset;   /* integer list of base relids */
202         List       *joininfo;           /* JoinInfo structures */
203         List       *innerjoin;          /* potential indexscans for nestloop joins */
204
205         /*
206          * innerjoin indexscans are not in the main pathlist because they are
207          * not usable except in specific join contexts; we have to test before
208          * seeing whether they can be used.
209          */
210 } RelOptInfo;
211
212 /*
213  * IndexOptInfo
214  *              Per-index information for planning/optimization
215  *
216  *              Prior to Postgres 7.0, RelOptInfo was used to describe both relations
217  *              and indexes, but that created confusion without actually doing anything
218  *              useful.  So now we have a separate IndexOptInfo struct for indexes.
219  *
220  *              indexoid  - OID of the index relation itself
221  *              pages     - number of disk pages in index
222  *              tuples    - number of index tuples in index
223  *              ncolumns  - number of columns in index
224  *              nkeys     - number of keys used by index (input columns)
225  *              classlist - List of PG_OPCLASS OIDs for the index
226  *              indexkeys - List of base-relation attribute numbers that are index keys
227  *              ordering  - List of PG_OPERATOR OIDs which order the indexscan result
228  *              relam     - the OID of the pg_am of the index
229  *              amcostestimate - OID of the relam's cost estimator
230  *              indproc   - OID of the function if a functional index, else 0
231  *              indpred   - index predicate if a partial index, else NULL
232  *              unique    - true if index is unique
233  *
234  *              ncolumns and nkeys are the same except for a functional index,
235  *              wherein ncolumns is 1 (the single function output) while nkeys
236  *              is the number of table columns passed to the function. classlist[]
237  *              and ordering[] have ncolumns entries, while indexkeys[] has nkeys
238  *              entries.
239  *
240  *              Note: for historical reasons, the arrays classlist, indexkeys and
241  *              ordering have an extra entry that is always zero.  Some code scans
242  *              until it sees a zero rather than looking at ncolumns or nkeys.
243  */
244
245 typedef struct IndexOptInfo
246 {
247         NodeTag         type;
248
249         Oid                     indexoid;               /* OID of the index relation */
250
251         /* statistics from pg_class */
252         long            pages;
253         double          tuples;
254
255         /* index descriptor information */
256         int                     ncolumns;               /* number of columns in index */
257         int                     nkeys;                  /* number of keys used by index */
258         Oid                *classlist;          /* AM operator classes for columns */
259         int                *indexkeys;          /* column numbers of index's keys */
260         Oid                *ordering;           /* OIDs of sort operators for each column */
261         Oid                     relam;                  /* OID of the access method (in pg_am) */
262
263         RegProcedure amcostestimate;    /* OID of the access method's cost fcn */
264
265         Oid                     indproc;                /* if a functional index */
266         List       *indpred;            /* if a partial index */
267         bool            unique;                 /* if a unique index */
268 } IndexOptInfo;
269
270
271 /*
272  * A Var is considered to belong to a relation if it's either from one
273  * of the actual base rels making up the relation, or it's a join alias
274  * var that is included in the relation.
275  */
276 #define VARISRELMEMBER(varno,rel) (intMember((varno), (rel)->relids) || \
277                                                                    intMember((varno), (rel)->joinrteids))
278
279
280 /*
281  * PathKeys
282  *
283  *      The sort ordering of a path is represented by a list of sublists of
284  *      PathKeyItem nodes.      An empty list implies no known ordering.  Otherwise
285  *      the first sublist represents the primary sort key, the second the
286  *      first secondary sort key, etc.  Each sublist contains one or more
287  *      PathKeyItem nodes, each of which can be taken as the attribute that
288  *      appears at that sort position.  (See the top of optimizer/path/pathkeys.c
289  *      for more information.)
290  */
291
292 typedef struct PathKeyItem
293 {
294         NodeTag         type;
295
296         Node       *key;                        /* the item that is ordered */
297         Oid                     sortop;                 /* the ordering operator ('<' op) */
298
299         /*
300          * key typically points to a Var node, ie a relation attribute, but it
301          * can also point to a Func clause representing the value indexed by a
302          * functional index.  Someday we might allow arbitrary expressions as
303          * path keys, so don't assume more than you must.
304          */
305 } PathKeyItem;
306
307 /*
308  * Type "Path" is used as-is for sequential-scan paths.  For other
309  * path types it is the first component of a larger struct.
310  */
311
312 typedef struct Path
313 {
314         NodeTag         type;
315
316         RelOptInfo *parent;                     /* the relation this path can build */
317
318         /* estimated execution costs for path (see costsize.c for more info) */
319         Cost            startup_cost;   /* cost expended before fetching any
320                                                                  * tuples */
321         Cost            total_cost;             /* total cost (assuming all tuples
322                                                                  * fetched) */
323
324         NodeTag         pathtype;               /* tag identifying scan/join method */
325         /* XXX why is pathtype separate from the NodeTag? */
326
327         List       *pathkeys;           /* sort ordering of path's output */
328         /* pathkeys is a List of Lists of PathKeyItem nodes; see above */
329 } Path;
330
331 /*----------
332  * IndexPath represents an index scan.  Although an indexscan can only read
333  * a single relation, it can scan it more than once, potentially using a
334  * different index during each scan.  The result is the union (OR) of all the
335  * tuples matched during any scan.      (The executor is smart enough not to return
336  * the same tuple more than once, even if it is matched in multiple scans.)
337  *
338  * 'indexinfo' is a list of IndexOptInfo nodes, one per scan to be performed.
339  *
340  * 'indexqual' is a list of index qualifications, also one per scan.
341  * Each entry in 'indexqual' is a sublist of qualification expressions with
342  * implicit AND semantics across the sublist items.  Only expressions that
343  * are usable as indexquals (as determined by indxpath.c) may appear here.
344  * NOTE that the semantics of the top-level list in 'indexqual' is OR
345  * combination, while the sublists are implicitly AND combinations!
346  * Also note that indexquals lists do not contain RestrictInfo nodes,
347  * just bare clause expressions.
348  *
349  * 'indexscandir' is one of:
350  *              ForwardScanDirection: forward scan of an ordered index
351  *              BackwardScanDirection: backward scan of an ordered index
352  *              NoMovementScanDirection: scan of an unordered index, or don't care
353  * (The executor doesn't care whether it gets ForwardScanDirection or
354  * NoMovementScanDirection for an indexscan, but the planner wants to
355  * distinguish ordered from unordered indexes for building pathkeys.)
356  *
357  * 'joinrelids' is only used in IndexPaths that are constructed for use
358  * as the inner path of a nestloop join.  These paths have indexquals
359  * that refer to values of other rels, so those other rels must be
360  * included in the outer joinrel in order to make a usable join.
361  *
362  * 'alljoinquals' is also used only for inner paths of nestloop joins.
363  * This flag is TRUE iff all the indexquals came from non-pushed-down
364  * JOIN/ON conditions, which means the path is safe to use for an outer join.
365  *
366  * 'rows' is the estimated result tuple count for the indexscan.  This
367  * is the same as path.parent->rows for a simple indexscan, but it is
368  * different for a nestloop inner path, because the additional indexquals
369  * coming from join clauses make the scan more selective than the parent
370  * rel's restrict clauses alone would do.
371  *----------
372  */
373 typedef struct IndexPath
374 {
375         Path            path;
376         List       *indexinfo;
377         List       *indexqual;
378         ScanDirection indexscandir;
379         Relids          joinrelids;             /* other rels mentioned in indexqual */
380         bool            alljoinquals;   /* all indexquals derived from JOIN conds? */
381         double          rows;                   /* estimated number of result tuples */
382 } IndexPath;
383
384 /*
385  * TidPath represents a scan by TID
386  */
387 typedef struct TidPath
388 {
389         Path            path;
390         List       *tideval;
391         Relids          unjoined_relids;        /* some rels not yet part of my Path */
392 } TidPath;
393
394 /*
395  * AppendPath represents an Append plan, ie, successive execution of
396  * several member plans.  Currently it is only used to handle expansion
397  * of inheritance trees.
398  */
399 typedef struct AppendPath
400 {
401         Path            path;
402         List       *subpaths;           /* list of component Paths */
403 } AppendPath;
404
405 /*
406  * All join-type paths share these fields.
407  */
408
409 typedef struct JoinPath
410 {
411         Path            path;
412
413         JoinType        jointype;
414
415         Path       *outerjoinpath;      /* path for the outer side of the join */
416         Path       *innerjoinpath;      /* path for the inner side of the join */
417
418         List       *joinrestrictinfo;           /* RestrictInfos to apply to join */
419
420         /*
421          * See the notes for RelOptInfo to understand why joinrestrictinfo is
422          * needed in JoinPath, and can't be merged into the parent RelOptInfo.
423          */
424 } JoinPath;
425
426 /*
427  * A nested-loop path needs no special fields.
428  */
429
430 typedef JoinPath NestPath;
431
432 /*
433  * A mergejoin path has these fields.
434  *
435  * path_mergeclauses lists the clauses (in the form of RestrictInfos)
436  * that will be used in the merge.      (Before 7.0, this was a list of bare
437  * clause expressions, but we can save on list memory and cost_qual_eval
438  * work by leaving it in the form of a RestrictInfo list.)
439  *
440  * Note that the mergeclauses are a subset of the parent relation's
441  * restriction-clause list.  Any join clauses that are not mergejoinable
442  * appear only in the parent's restrict list, and must be checked by a
443  * qpqual at execution time.
444  *
445  * outersortkeys (resp. innersortkeys) is NIL if the outer path
446  * (resp. inner path) is already ordered appropriately for the
447  * mergejoin.  If it is not NIL then it is a PathKeys list describing
448  * the ordering that must be created by an explicit sort step.
449  */
450
451 typedef struct MergePath
452 {
453         JoinPath        jpath;
454         List       *path_mergeclauses;          /* join clauses to be used for
455                                                                                  * merge */
456         List       *outersortkeys;      /* keys for explicit sort, if any */
457         List       *innersortkeys;      /* keys for explicit sort, if any */
458 } MergePath;
459
460 /*
461  * A hashjoin path has these fields.
462  *
463  * The remarks above for mergeclauses apply for hashclauses as well.
464  * (But note that path_hashclauses will always be a one-element list,
465  * since we only hash on one hashable clause.)
466  *
467  * Hashjoin does not care what order its inputs appear in, so we have
468  * no need for sortkeys.
469  */
470
471 typedef struct HashPath
472 {
473         JoinPath        jpath;
474         List       *path_hashclauses;           /* join clauses used for hashing */
475 } HashPath;
476
477 /*
478  * Restriction clause info.
479  *
480  * We create one of these for each AND sub-clause of a restriction condition
481  * (WHERE or JOIN/ON clause).  Since the restriction clauses are logically
482  * ANDed, we can use any one of them or any subset of them to filter out
483  * tuples, without having to evaluate the rest.  The RestrictInfo node itself
484  * stores data used by the optimizer while choosing the best query plan.
485  *
486  * If a restriction clause references a single base relation, it will appear
487  * in the baserestrictinfo list of the RelOptInfo for that base rel.
488  *
489  * If a restriction clause references more than one base rel, it will
490  * appear in the JoinInfo lists of every RelOptInfo that describes a strict
491  * subset of the base rels mentioned in the clause.  The JoinInfo lists are
492  * used to drive join tree building by selecting plausible join candidates.
493  * The clause cannot actually be applied until we have built a join rel
494  * containing all the base rels it references, however.
495  *
496  * When we construct a join rel that includes all the base rels referenced
497  * in a multi-relation restriction clause, we place that clause into the
498  * joinrestrictinfo lists of paths for the join rel, if neither left nor
499  * right sub-path includes all base rels referenced in the clause.      The clause
500  * will be applied at that join level, and will not propagate any further up
501  * the join tree.  (Note: the "predicate migration" code was once intended to
502  * push restriction clauses up and down the plan tree based on evaluation
503  * costs, but it's dead code and is unlikely to be resurrected in the
504  * foreseeable future.)
505  *
506  * Note that in the presence of more than two rels, a multi-rel restriction
507  * might reach different heights in the join tree depending on the join
508  * sequence we use.  So, these clauses cannot be associated directly with
509  * the join RelOptInfo, but must be kept track of on a per-join-path basis.
510  *
511  * When dealing with outer joins we have to be very careful about pushing qual
512  * clauses up and down the tree.  An outer join's own JOIN/ON conditions must
513  * be evaluated exactly at that join node, and any quals appearing in WHERE or
514  * in a JOIN above the outer join cannot be pushed down below the outer join.
515  * Otherwise the outer join will produce wrong results because it will see the
516  * wrong sets of input rows.  All quals are stored as RestrictInfo nodes
517  * during planning, but there's a flag to indicate whether a qual has been
518  * pushed down to a lower level than its original syntactic placement in the
519  * join tree would suggest.  If an outer join prevents us from pushing a qual
520  * down to its "natural" semantic level (the level associated with just the
521  * base rels used in the qual) then the qual will appear in JoinInfo lists
522  * that reference more than just the base rels it actually uses.  By
523  * pretending that the qual references all the rels appearing in the outer
524  * join, we prevent it from being evaluated below the outer join's joinrel.
525  * When we do form the outer join's joinrel, we still need to distinguish
526  * those quals that are actually in that join's JOIN/ON condition from those
527  * that appeared higher in the tree and were pushed down to the join rel
528  * because they used no other rels.  That's what the ispusheddown flag is for;
529  * it tells us that a qual came from a point above the join of the specific
530  * set of base rels that it uses (or that the JoinInfo structures claim it
531  * uses).  A clause that originally came from WHERE will *always* have its
532  * ispusheddown flag set; a clause that came from an INNER JOIN condition,
533  * but doesn't use all the rels being joined, will also have ispusheddown set
534  * because it will get attached to some lower joinrel.
535  *
536  * In general, the referenced clause might be arbitrarily complex.      The
537  * kinds of clauses we can handle as indexscan quals, mergejoin clauses,
538  * or hashjoin clauses are fairly limited --- the code for each kind of
539  * path is responsible for identifying the restrict clauses it can use
540  * and ignoring the rest.  Clauses not implemented by an indexscan,
541  * mergejoin, or hashjoin will be placed in the plan qual or joinqual field
542  * of the finished Plan node, where they will be enforced by general-purpose
543  * qual-expression-evaluation code.  (But we are still entitled to count
544  * their selectivity when estimating the result tuple count, if we
545  * can guess what it is...)
546  */
547
548 typedef struct RestrictInfo
549 {
550         NodeTag         type;
551
552         Expr       *clause;                     /* the represented clause of WHERE or JOIN */
553
554         bool            ispusheddown;   /* TRUE if clause was pushed down in level */
555
556         /* only used if clause is an OR clause: */
557         List       *subclauseindices;           /* indexes matching subclauses */
558         /* subclauseindices is a List of Lists of IndexOptInfos */
559
560         /* cache space for costs (currently only used for join clauses) */
561         Cost            eval_cost;              /* eval cost of clause; -1 if not yet set */
562         Selectivity this_selec;         /* selectivity; -1 if not yet set */
563
564         /* valid if clause is mergejoinable, else InvalidOid: */
565         Oid                     mergejoinoperator;              /* copy of clause operator */
566         Oid                     left_sortop;    /* leftside sortop needed for mergejoin */
567         Oid                     right_sortop;   /* rightside sortop needed for mergejoin */
568
569         /* cache space for mergeclause processing; NIL if not yet set */
570         List       *left_pathkey;       /* canonical pathkey for left side */
571         List       *right_pathkey;      /* canonical pathkey for right side */
572
573         /* cache space for mergeclause processing; -1 if not yet set */
574         Selectivity left_mergescansel;  /* fraction of left side to scan */
575         Selectivity right_mergescansel; /* fraction of right side to scan */
576
577         /* valid if clause is hashjoinable, else InvalidOid: */
578         Oid                     hashjoinoperator;               /* copy of clause operator */
579
580         /* cache space for hashclause processing; -1 if not yet set */
581         Selectivity left_bucketsize;    /* avg bucketsize of left side */
582         Selectivity right_bucketsize;           /* avg bucketsize of right side */
583 } RestrictInfo;
584
585 /*
586  * Join clause info.
587  *
588  * We make a list of these for each RelOptInfo, containing info about
589  * all the join clauses this RelOptInfo participates in.  (For this
590  * purpose, a "join clause" is a WHERE clause that mentions both vars
591  * belonging to this relation and vars belonging to relations not yet
592  * joined to it.)  We group these clauses according to the set of
593  * other base relations (unjoined relations) mentioned in them.
594  * There is one JoinInfo for each distinct set of unjoined_relids,
595  * and its jinfo_restrictinfo lists the clause(s) that use that set
596  * of other relations.
597  */
598
599 typedef struct JoinInfo
600 {
601         NodeTag         type;
602         Relids          unjoined_relids;        /* some rels not yet part of my RelOptInfo */
603         List       *jinfo_restrictinfo;         /* relevant RestrictInfos */
604 } JoinInfo;
605
606 #endif   /* RELATION_H */