CUBRID Engine  latest
query_graph.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * query_graph.h - Query graph
22  */
23 
24 #ifndef _QUERY_GRAPH_H_
25 #define _QUERY_GRAPH_H_
26 
27 #ident "$Id$"
28 
29 #if defined (SERVER_MODE)
30 #error Does not belong to server module
31 #endif /* SERVER_MODE */
32 
33 #include <setjmp.h>
34 
35 #include "work_space.h"
36 #include "statistics.h"
37 
38 #include "optimizer.h"
39 #include "parser.h"
40 #include "query_bitset.h"
41 
43 
45 {
46  /*
47  * The name of the class.
48  */
49  const char *name;
50 
51  /*
52  * The actual oid of the class.
53  */
55 
56  /*
57  * The mop pointer to the memory-resident descriptor for the class
58  * object. It is important that we keep this alive while we still
59  * need statistics; it our guarantee that the garbage collector won't
60  * try to remove the class object from memory and thereby render our
61  * pointer to the statistics structure useless.
62  */
64 
65  /*
66  * The class which contains a statistics structure. This structure will be
67  * automatically reclaimed, so there is no need to explicitly free it
68  * when the QO_CLASS_INFO structure is freed.
69  *
70  * UNLESS we allocate it ourselves in qo_estimate_statistics(); use
71  * the self_allocated flag to remember this tidbit.
72  */
74 
75  /* The statistics which is allocated when it can not get from server */
78 
79  /* is this a normal-resident class ? */
81 
83 };
84 
85 
87 {
88  int n;
90 };
91 
92 
94 {
95  /* cumulative stats for all attributes under this umbrella */
97 };
98 
100 {
101  /* next compatible index under the class hierarchy */
103 
104  /* information of the class to which the index belongs */
106 
107  /* index information; name, type, btid and attributes will be referred during query optimization */
109 
110  int force;
111 
112  /* number of columns of the index */
113  int col_num;
114 
115  /* TP_DOMAIN of the first indexed attribute */
117 
118  /* number of entries of seg_idxs[] and seg_terms[] array */
119  int nsegs;
120 
121  /* array of segment idx's constrained by the index */
122  int *seg_idxs;
123 
124  /* Idx of the first range list term; RANGE (r1, r2, ...) */
126 
127  /* array of equal operator term sets */
129 
130  /* array of non-equal operator term sets */
132 
133  /* terms constrained by the index */
135 
136  /* true if all unique columns are specified in equal terms */
138 
139  /* true if the index cover all segments */
141 
142  /* index of first sort column used for multi range optimization */
144 
145  /* true if the index can skip the order by */
147 
148  /* true if the index can skip the group by */
150 
151  /* true if the index will skip the order by or the group by with the usage of descending index */
153 
154  /* true if the index can be used as covering index */
156 
157  /* index loose scan prefix length or -1 if ILS is not used */
159 
160  /*
161  * the name of the first indexed attribute in a multi column index
162  * the first indexed attribute contain valid statistics
163  */
165 
166  /* key limits */
168 
169  /*
170  * if the first indexed attribute is actually a function expression,
171  * statistics will be retrieved from the B-tree , rather that attribute
172  * stats. This flag is true only if the function expression is the first key
173  * in the index.
174  */
176 
177  /* Idx of the first range list term; RANGE (r1, r2, ...) */
179 
180  /* segs constrained by the index */
182 
183  /* index range condition segments in multiple column term */
185 };
186 
187 #define QO_ENTRY_MULTI_COL(entry) ((entry)->col_num > 1 ? true : false)
188 
189 struct qo_index
190 {
191  int n;
192  int max;
194 };
195 
196 #define QO_INDEX_INDEX(ind, n) (&(ind)->index[(n)])
197 
198 /*
199  * Get current class statistics.
200  */
201 #define QO_GET_CLASS_STATS(entryp) \
202  ((entryp)->self_allocated ? (entryp)->stats : (entryp)->smclass->stats)
203 
204 /*
205  * This structure is the head of a list of QO_INDEX_ENTRY index structures.
206  * The purpose for this node is to have a place to store cumulative
207  * statistics of the indexes on the list and to store the list pointer.
208  */
210 {
211  /* Pointer to a linked list of compatible index nodes. */
213 
214  /* cumulative stats for all indexes in this list */
216 
217  /* Number of classes on the list (depth of the list). */
218  int n;
219 };
220 
221 /*
222  * Contains pointers to usable indexes which span class heirarchies.
223  * Each element in the array contains an index header which consists
224  * of statistical information and a pointer to a list of compatible
225  * index structures where each node of the list represents an index
226  * at each level in the class heirarchy.
227  */
229 {
230  /* Number of usable indexes (size of the array). */
231  int n;
232 
233  /* Array of usable indexes */
234  struct qo_node_index_entry index[1];
235 };
236 
237 #define QO_NI_N(ni) ((ni)->n)
238 #define QO_NI_ENTRY(ni, n) (&(ni)->index[(n)])
239 
240 
241 /* index names for the node specfied in USING INDEX clause */
242 
244 {
245  const char *name;
246  int force;
248 };
249 
251 {
252  /* number of indexes (size of the array) */
253  int n;
254 
255  /* array of index names */
256  struct qo_using_index_entry index[1];
257 };
258 
259 #define QO_UI_N(ui) ((ui)->n)
260 #define QO_UI_INDEX(ui, n) ((ui)->index[(n)].name)
261 #define QO_UI_FORCE(ui, n) ((ui)->index[(n)].force)
262 #define QO_UI_KEYLIMIT(ui, n) ((ui)->index[(n)].key_limit)
263 
264 
265 struct qo_node
266 {
267  /*
268  * The environment in which this Node is embedded, and to which it
269  * refers for other important information.
270  */
272 
273  /*
274  * The PT_NODE from env->pt_tree that gave rise to this graph
275  * node. entity_spec holds all of the interesting information about
276  * class oids, etc. which we need to communicate with the statistics
277  * manager.
278  */
280 
281  /*
282  * The segments (and their equivalence classes) that cover (i.e.,
283  * emanate from) this node.
284  */
287 
288  /*
289  * The partition (see below) to which this node belongs.
290  */
292 
293  /*
294  * If non-NULL, oid_seg is a segment corresponding to the (virtual)
295  * oid attribute of a class. It is often necessary to retrieve the
296  * oid of an object along with other of its attributes (in order to,
297  * for example, supply enough information for update queries, or for
298  * certain kinds of joins), and it is convenient to be able to treat
299  * this the same as any other kind of attribute.
300  */
302 
303  /*
304  * The set of all nodes that this node MAY be dependent on if it is
305  * a derived table that is correlated to this level. It will be all
306  * nodes with an idx less than this node. This is coarser than
307  * perhaps necessary, but makes the implementation considerably
308  * cleaner.
309  */
311 
312  /*
313  * The set of sargs that apply to this node. This is an implicit
314  * conjunction; elements produced from a scan of this node will
315  * satisfy all sargs in the set. selectivity is the product of the
316  * selectivities of the sargs in the set.
317  */
319  double selectivity;
320 
321  /*
322  * The set of all subqueries that must be evaluated whenever a new
323  * row is produced from this node.
324  */
326 
327 
329 
330  /*
331  * Summaries of size information from the various constituent
332  * classes. ncard is the total number of objects represented by this
333  * node, while tcard is the total number of disk pages occupied by
334  * those objects. These silly names are historical artifacts that
335  * correspond to the names in the 197? IBM report on query
336  * optimization in System R.
337  */
338  unsigned long int ncard;
339  unsigned long int tcard;
340 
341  /*
342  * The nominal name of this node, used pretty much only for dumping
343  * debugging information. Right now, we just pick the name of the
344  * first class in the list of classes and subclasses underlying this
345  * node (see above).
346  */
347  const char *class_name;
348 
349  /*
350  * The ordinal id of this node; this is the id used to identify this
351  * node in various bitsets.
352  */
353  int idx;
354 
355  /*
356  * The relative id of this node in partition; this is the id used to
357  * identify this node in join_info vector.
358  */
359  int rel_idx;
360 
361  /*
362  * Indexes can be viewed from a variety of perspectives. Each class
363  * associated with this node has a collection of indexes which are
364  * possible candidates for use in an index scan. For scans across
365  * the class hierarchy, it is necessary to find compatible indexes
366  * at each class in the hierarchy. This hierarchical grouping is
367  * maintained in QO_NODE_INDEX.
368  */
370  QO_USING_INDEX *using_index; /* indexes specified in USING INDEX clause */
371  /* NULL if no USING INDEX clause in the query */
372 
373  BITSET outer_dep_set; /* outer join dependency; to preserve join sequence */
374  BITSET right_dep_set; /* outer join dependency for right outer join; to preserve join sequence */
375  PT_HINT_ENUM hint; /* hint comment contained in given */
376  bool sargable; /* whether sargs are applicable to this node */
377  bool sort_limit_candidate; /* whether this node is a candidate for a SORT_LIMIT plan */
378 };
379 
380 #define QO_NODE_ENV(node) (node)->env
381 #define QO_NODE_ENTITY_SPEC(node) (node)->entity_spec
382 #define QO_NODE_PT_JOIN_TYPE(node) (node)->entity_spec->info.spec.join_type
383 #define QO_NODE_LOCATION(node) (node)->entity_spec->info.spec.location
384 #define QO_NODE_OID_SEG(node) (node)->oid_seg
385 #define QO_NODE_EQCLASSES(node) (node)->eqclasses
386 #define QO_NODE_PARTITION(node) (node)->partition
387 #define QO_NODE_DEP_SET(node) (node)->dep_set
388 #define QO_NODE_SARGS(node) (node)->sargs
389 #define QO_NODE_SELECTIVITY(node) (node)->selectivity
390 #define QO_NODE_SUBQUERIES(node) (node)->subqueries
391 #define QO_NODE_SEGS(node) (node)->segs
392 #define QO_NODE_IDX(node) (node)->idx
393 #define QO_NODE_REL_IDX(node) (node)->rel_idx
394 #define QO_NODE_INDEXES(node) (node)->indexes
395 #define QO_NODE_USING_INDEX(node) (node)->using_index
396 
397 #define QO_NODE_OUTER_DEP_SET(node) (node)->outer_dep_set
398 #define QO_NODE_RIGHT_DEP_SET(node) (node)->right_dep_set
399 #define QO_NODE_SARGABLE(node) (node)->sargable
400 
401 #define QO_NODE_NAME(node) (node)->class_name
402 #define QO_NODE_OIDP(node) (&(node)->info->info[0].oid)
403 #define QO_NODE_INFO(node) (node)->info
404 #define QO_NODE_INFO_N(node) (node)->info->n
405 #define QO_NODE_NCARD(node) (node)->ncard
406 #define QO_NODE_TCARD(node) (node)->tcard
407 #define QO_NODE_HINT(node) (node)->hint
408 #define QO_NODE_INFO_SMCLASS(node) (node)->info[0].info->smclass
409 #define QO_NODE_SORT_LIMIT_CANDIDATE(node) (node)->sort_limit_candidate
410 
411 #define QO_NODE_IS_CLASS_HIERARCHY(node) \
412  (QO_NODE_INFO(node) != NULL \
413  && (QO_NODE_INFO_N(node) > 1 \
414  || (QO_NODE_INFO_SMCLASS(node)->partition != NULL \
415  && QO_NODE_INFO_SMCLASS(node)->users != NULL)))
416 
417 #define QO_NODE_IS_CLASS_PARTITIONED(node) \
418  (QO_NODE_INFO(node) != NULL \
419  && QO_NODE_INFO_SMCLASS(node)->partition != NULL \
420  && QO_NODE_INFO_SMCLASS(node)->users != NULL)
421 
422 #define QO_NODE_IS_OUTER_JOIN(node) \
423  (QO_NODE_PT_JOIN_TYPE(node) == PT_JOIN_LEFT_OUTER || \
424  QO_NODE_PT_JOIN_TYPE(node) == PT_JOIN_RIGHT_OUTER || \
425  QO_NODE_PT_JOIN_TYPE(node) == PT_JOIN_FULL_OUTER)
426 
427 #define QO_ADD_OUTER_DEP_SET(tail,head) \
428  bitset_union (&(QO_NODE_OUTER_DEP_SET (tail)), &(QO_NODE_OUTER_DEP_SET (head))); \
429  bitset_add (&(QO_NODE_OUTER_DEP_SET (tail)), QO_NODE_IDX (head));
430 
431 #define QO_ADD_RIGHT_DEP_SET(tail,head) \
432  bitset_union (&(QO_NODE_RIGHT_DEP_SET (tail)), &(QO_NODE_RIGHT_DEP_SET (head))); \
433  bitset_add (&(QO_NODE_RIGHT_DEP_SET (tail)), QO_NODE_IDX (head));
434 
435 #define QO_ADD_RIGHT_TO_OUTER(tail,head) \
436  bitset_union (&(QO_NODE_OUTER_DEP_SET (tail)), &(QO_NODE_RIGHT_DEP_SET (head)));
437 
439 {
440  /*
441  * The environment in which this Segment is embedded.
442  */
444 
445  /*
446  * The parse node that gave rise to this Segment.
447  */
449 
450 
451  /*
452  * The Node at the head (start) of this segment, i.e., the node from
453  * which this segment emanates.
454  */
456 
457  /*
458  * The Node at the tail (end) of this segment, if any. This will be
459  * non-NULL only if the segment is a join segment, i.e., if the
460  * domain of the underlying attribute is object-based.
461  */
463 
464  /*
465  * The link field used to chain together (in trees, actually)
466  * segments that belong to the same equivalence class. This is used
467  * by env_assign_eq_classes() to actually create and initialize the
468  * EqClass objects.
469  */
472 
473  /*
474  * The actual name of the attribute, squirreled away here for
475  * convenience.
476  */
477  const char *name;
478 
479  /*
480  * A flags indicating whether this segment is set valued, a class
481  * attribute, or a shared attribute.
482  */
486 
487  /* is index term equality expression? */
489 
490  /*
491  * Statistics information gleaned from the underlying attributes for
492  * this segment. This vector should have the same number of entries
493  * as the number of classes underlying the node from which this
494  * segment emanates; each entry in this vector corresponds to the
495  * actual attribute emanating from the actual class in the
496  * corresponding node.
497  */
499 
500  /* indexable terms to which this segment belongs */
502 
503  /* The index of this segment in the corresponding Env's seg array. */
504  int idx;
506 };
507 
508 #define QO_SEG_ENV(seg) (seg)->env
509 #define QO_SEG_PT_NODE(seg) (seg)->pt_node
510 #define QO_SEG_HEAD(seg) (seg)->head
511 #define QO_SEG_TAIL(seg) (seg)->tail
512 #define QO_SEG_EQ_ROOT(seg) (seg)->eq_root
513 #define QO_SEG_EQCLASS(seg) (seg)->eqclass
514 #define QO_SEG_NAME(seg) (seg)->name
515 #define QO_SEG_SET_VALUED(seg) (seg)->set_valued
516 #define QO_SEG_CLASS_ATTR(seg) (seg)->class_attr
517 #define QO_SEG_SHARED_ATTR(seg) (seg)->shared_attr
518 #define QO_SEG_INFO(seg) (seg)->info
519 #define QO_SEG_IDX(seg) (seg)->idx
520 #define QO_SEG_IS_SET_VALUED(seg) (seg)->set_valued
521 #define QO_SEG_ATTR_ID(seg) QO_SEG_ATTR_STATS(seg)->id
522 #define QO_SEG_IS_OID_SEG(seg) (QO_NODE_OID_SEG(QO_SEG_HEAD(seg)) == seg)
523 #define QO_SEG_INDEX_TERMS(seg) (seg)->index_terms
524 #define QO_SEG_FUNC_INDEX(seg) (seg)->is_function_index
525 #define OID_SEG_NAME "OID$"
526 
528 {
529  /* The Env in which this EqClass is embedded. */
531 
532  /*
533  * The set of segments that belong to this equivalence class (i.e.,
534  * that are related by some join term).
535  */
537 
538  /*
539  * The QO_TERM associated with this equivalence class if this class
540  * was fabricated specially to deal with complex merge terms. It
541  * should always be the case that this is NULL if segs is non-empty,
542  * and segs should be empty if this is non-NULL.
543  */
545 
546  /*
547  * The index of this EqClass in the corresponding Env's eqclasses
548  * array.
549  */
550  int idx;
551 };
552 
553 #define QO_UNORDERED ((QO_EQCLASS*)NULL)
554 
555 #define QO_EQCLASS_ENV(e) (e)->env
556 #define QO_EQCLASS_SEGS(e) (e)->segs
557 #define QO_EQCLASS_TERM(e) (e)->term
558 #define QO_EQCLASS_IDX(e) (e)->idx
559 
560 
561 
562 typedef enum
563 {
564  /*
565  * p e f n
566  * a d a u
567  * t g k m
568  * h e e
569  */
570  // todo: explain meaning of each flag
571  QO_TC_PATH = 0x30, /* 1 1 0 000 */
572  QO_TC_JOIN = 0x11, /* 0 1 0 001 */
573  QO_TC_SARG = 0x02, /* 0 0 0 010 */
574  QO_TC_OTHER = 0x03, /* 0 0 0 011 */
575  QO_TC_DEP_LINK = 0x1c, /* 0 1 1 100 */
576  QO_TC_DEP_JOIN = 0x1d, /* 0 1 1 101 */
577  QO_TC_DURING_JOIN = 0x04, /* 0 0 0 100 */
578  QO_TC_AFTER_JOIN = 0x05, /* 0 0 0 101 */
579  QO_TC_TOTALLY_AFTER_JOIN = 0x06, /* 0 0 0 110 */
580  QO_TC_DUMMY_JOIN = 0x1f /* 0 1 1 111 */
581 } QO_TERMCLASS;
582 
583 #define QO_IS_PATH_TERM(t) (QO_TERM_CLASS(t) & 0x20)
584 #define QO_IS_EDGE_TERM(t) (QO_TERM_CLASS(t) & 0x10)
585 #define QO_IS_FAKE_TERM(t) (QO_TERM_CLASS(t) & 0x08)
586 #define QO_IS_DEP_TERM(t) (QO_TERM_CLASS(t) == QO_TC_DEP_LINK || QO_TERM_CLASS(t) == QO_TC_DEP_JOIN)
587 
588 struct qo_term
589 {
590  /*
591  * WARNING!!! WARNING!!! WARNING!!!
592  *
593  * If you add any more elements to this struct, be sure to update the
594  * body of qo_exchange. Sadly, it needs to know about all of
595  * the elements of this struct.
596  */
597 
598  /* The env in which this term is embedded. */
600 
601  /*
602  * The nodes referenced by this term (i.e., the heads of all segments
603  * used in this term).
604  *
605  * If this term is a dependent term, this is the set of all nodes on
606  * which the dependent node depends, PLUS the dependent node.
607  */
609 
610  /*
611  * The set of segments involved in the expression that gives rise to
612  * this term.
613  */
615 
616  /*
617  * The selectivity of this term (i.e., the fraction of candidates
618  * that we expect to satisfy the term) when it is not used as an
619  * index. If T is the cartesian product of all nodes referenced by
620  * the term, selectivity is the fraction of the rows in T that
621  * (are expected to) satisfy the term.
622  */
623  double selectivity;
624 
625  /*
626  * The "flavor" of this term. This is determined by analysis of the
627  * segment or where-clause disjunct that gives rise to the term.
628  */
630 
631  /*
632  * The rank of this term. used for the same selectivity
633  */
634  int rank;
635 
636  /*
637  * The expression that gave rise to this term. This is either a
638  * conjunct from the conjunctive normal form of the query's search
639  * condition, or a "manufactured" term spawned by a path term.
640  */
642 
643  /*
644  * The set of all correlated subqueries appearing in this term.
645  */
647 
648  /*
649  * -1 == NO_JOIN iff this term is not suitable as a join predicate
650  * Currently only applicable to path terms.
651  */
653 
654  /*
655  * can_use_index is non-zero if this term can be implemented with an
656  * index under appropriate circumstances, i.e., one or both sides are
657  * local names, and each side is "independent" of the other (no node
658  * contributes segments to both sides).
659  *
660  * if can_use_index is non-zero, the first "can_use_index" entries in
661  * index_seg hold the segments that can use an index.
662  */
664  QO_SEGMENT *index_seg[2];
665 
666  /*
667  * The two segments involved in a path join term. It's relatively
668  * important to know which one is the (virtual) oid segment and which
669  * is the real segment.
670  */
673 
674  /*
675  * The head and tail nodes joined by this term if it is a join term.
676  * This is redundant, but it is convenient to cache this information
677  * here since it tends to get accessed a lot.
678  *
679  * If the term is a dependency link term, tail identifies the
680  * dependent node.
681  */
684 
685 
688 
689  int flag; /* flags */
690 
691  /*
692  * The ordinal id of this term; this is the id used to identify this
693  * node in various bitsets.
694  */
695  int idx;
696 
697  short location;
698 
699  /*
700  * a segment number of multiple columns ordered by written predicate
701  * ex) (b,a,c) in ... multi_col_segs[0] = b, [1] = a, [2] = c
702  */
705 
706  /*
707  * WARNING!!! WARNING!!! WARNING!!!
708  *
709  * If you add any more elements to this struct, be sure to update the
710  * body of qo_exchange. Sadly, it needs to know about all of
711  * the elements of this struct.
712  */
713 };
714 
715 #define QO_TERM_ENV(t) (t)->env
716 #define QO_TERM_CLASS(t) (t)->term_class
717 #define QO_TERM_NODES(t) (t)->nodes
718 #define QO_TERM_SEGS(t) (t)->segments
719 #define QO_TERM_SELECTIVITY(t) (t)->selectivity
720 #define QO_TERM_RANK(t) (t)->rank
721 #define QO_TERM_HEAD(t) (t)->head
722 #define QO_TERM_TAIL(t) (t)->tail
723 #define QO_TERM_IDX(t) (t)->idx
724 #define QO_TERM_PT_EXPR(t) (t)->pt_expr
725 #define QO_TERM_LOCATION(t) (t)->location
726 #define QO_TERM_SUBQUERIES(t) (t)->subqueries
727 #define QO_TERM_SEG(t) (t)->seg
728 #define QO_TERM_OID_SEG(t) (t)->oid_seg
729 #define QO_TERM_EQCLASS(t) (t)->eqclass
730 #define QO_TERM_NOMINAL_SEG(t) (t)->nominal_seg
731 #define QO_TERM_CAN_USE_INDEX(t) (t)->can_use_index
732 #define QO_TERM_INDEX_SEG(t, i) (t)->index_seg[(i)]
733 #define QO_TERM_JOIN_TYPE(t) (t)->join_type
734 #define QO_TERM_FLAG(t) (t)->flag
735 #define QO_TERM_MULTI_COL_SEGS(t) (t)->multi_col_segs
736 #define QO_TERM_MULTI_COL_CNT(t) (t)->multi_col_cnt
737 
738 
739 #define QO_TERM_EQUAL_OP 1 /* is equal op ? */
740 #define QO_TERM_RANGELIST 2 /* is RANGE (r1, r2, ...) ? */
741 #define QO_TERM_SINGLE_PRED 4 /* is single_pred ? */
742 #define QO_TERM_COPY_PT_EXPR 8 /* pt_expr is copyed ? */
743 #define QO_TERM_MERGEABLE_EDGE 16 /* suitable as a m-join edge ? */
744 #define QO_TERM_NON_IDX_SARG_COLL 32 /* not suitable for key range/filter */
745 #define QO_TERM_MULTI_COLL_PRED 64 /* multi column && in OP, (a,b) in .. */
746 #define QO_TERM_MULTI_COLL_CONST 128 /* multi column && have constant value, (a,1) in .. */
747 #define QO_TERM_OR_PRED 256 /* or predicate. e.g.) a=1 or b=2 */
748 
749 #define QO_TERM_IS_FLAGED(t, f) (QO_TERM_FLAG(t) & (int) (f))
750 #define QO_TERM_SET_FLAG(t, f) QO_TERM_FLAG(t) |= (int) (f)
751 #define QO_TERM_CLEAR_FLAG(t, f) QO_TERM_FLAG(t) &= (int) ~(f)
752 
753 
755 {
756  /*
757  * Interesting information about subqueries that are directly
758  * correlated to this query (i.e., the query being optimized is the
759  * innermost query to which the subqueries have correlated
760  * references).
761  */
762 
763  /*
764  * The parse tree for the subquery itself.
765  */
767 
768  /*
769  * The set of segments (and corresponding nodes) to which the
770  * subquery actually refers.
771  */
774 
775  /*
776  * The QO_TERMs in which this subquery appears, if any. This will
777  * have a cardinality of 1 for normal terms, but it could be larger
778  * for dependent derived tables since they can depend upon more than
779  * one antecedent and they'll be marked as a participant in each
780  * dependency term.
781  */
783 
784  /*
785  * This entry's offset in env->subqueries.
786  */
787  int idx;
788 };
789 
790 
792 {
793  /*
794  * Since the overall join graph can actually be disconnected (this
795  * corresponds to a situation where the luser has specified one or
796  * more cartesian products), we partition it first and optimize each
797  * partition separately. The partitions are then combined by
798  * cartesian product operators in some nominally optimal order; since
799  * cartesian products are almost always stupid, and almost never
800  * present, we don't expend much effort in determining that order.
801  */
802 
803  /*
804  * The nodes, edges, and dependencies (sargable terms) in the
805  * partition. This partition might have dependent tables in it that
806  * depend on tables in other partitions, so we will need this
807  * information to make sure that we order the cartesian product of
808  * partitions correctly.
809  */
813 
814  /*
815  * The optimized plan created for this partition.
816  */
818 
819  /* the starting point of this partition's join_info vector that will be allocated. */
820  int M_offset;
821 
822  /*
823  * The id of this partition.
824  */
825  int idx;
826 };
827 
828 #define QO_PARTITION_NODES(p) (p)->nodes
829 #define QO_PARTITION_EDGES(p) (p)->edges
830 #define QO_PARTITION_DEPENDENCIES(p) (p)->dependencies
831 #define QO_PARTITION_M_OFFSET(p) (p)->M_offset
832 #define QO_PARTITION_PLAN(p) (p)->plan
833 #define QO_PARTITION_IDX(p) (p)->idx
834 
835 typedef enum
836 {
837  QO_SL_INVALID, /* SORT-LIMIT plan cannot be created */
838  QO_SL_USE, /* SORT-LIMIT plan should be created */
839  QO_SL_POSSIBLE /* All conditions for the SORT-LIMIT plans are met but user did not supply a valid
840  * limit */
842 
843 struct qo_env
844 {
845  /*
846  * The repository of all optimizer data structures. These things are
847  * all collected into one data structure in case the optimizer ever
848  * needs to live in a multi-threaded world. This adds a little
849  * tedium (most procedures must accept the environment as an added
850  * parameter), but it's not too bad.
851  */
852 
853  /*
854  * The parser environment that is associated with the pt_tree
855  */
857 
858  /*
859  * The path expression tree for which we are to develop a plan.
860  * The environment initializer will crawl all over this tree to glean
861  * relevant information for the optimizer.
862  */
864 
871 
872  /*
873  * A temporary bitset. This is needed for expr_segs() in build_query_graph
874  */
876 
877  /*
878  * The final plan produced by the optimizer.
879  */
881 
882  /*
883  * The segments (attributes) to be produced as the ultimate result of
884  * the plan, i.e., the attributes that the luser expects to receive.
885  */
887 
888  /*
889  * Counts and vectors that hold the various collections of nodes,
890  * segments, etc.
891  */
892  int nsegs, Nsegs;
893  int nnodes, Nnodes;
894  int neqclasses, Neqclasses;
895  int nterms, Nterms;
898  int nedges;
899 
900  /* nodes which cannot be excluded from plans which compute query limit */
902 
903  /* stopping cardinality for the plan (LIMIT, ORDERBY_FOR, etc) */
905 
906  /* true if we should consider generating SORT-LIMIT plans */
908  /*
909  * True iff we found a conjunct which was not an expression. We assume
910  * that this is a false conjunct and we don't need to optimize a query
911  * that will return no values.
912  */
913  int bail_out;
914 
915  /*
916  * The planner structure used during the search of the plan space.
917  * We keep a pointer to it here to simplify cleanup, whether natural
918  * or forced by an error.
919  */
921 
922  /*
923  * A JMPBUF for aborting from fatal problems. A fatal problem for
924  * the optimizer isn't necessarily a fatal problem for anyone else,
925  * since we can always return to the outer context and try the
926  * default plan.
927  */
928  jmp_buf catch_;
929 
930  /*
931  * A bitset holding the idx's of all fake terms. This is convenient
932  * for a quick exclusion test necessary during the search for good
933  * plans, because fake terms can't be used in certain contexts.
934  */
936 
937  /*
938  * Controls the amount of garbage dumped with plans. Can be
939  * overridden with the environment variable CUBRID_QO_DUMP_LEVEL.
940  */
942 
943  /*
944  * Controls whether the plan is dumped. There are situations like
945  * "SHOW COLUMNS" when the plan should not be dumped, even if QO_PARAM_LEVEL
946  * parameter was set to dump a readable version of the plan
947  */
949 
950  /*
951  * If a plan may be using multi range optimization, but the limit is too
952  * large, this is set to true.
953  */
955 };
956 
957 #define QO_ENV_SEG(env, n) (&(env)->segs[(n)])
958 #define QO_ENV_NODE(env, n) (&(env)->nodes[(n)])
959 #define QO_ENV_EQCLASS(env, n) (&(env)->eqclasses[(n)])
960 #define QO_ENV_TERM(env, n) (&(env)->terms[(n)])
961 #define QO_ENV_PARTITION(env, n) (&(env)->partitions[(n)])
962 #define QO_ENV_SUBQUERY(env, n) (&(env)->subqueries[(n)])
963 #define QO_ENV_PREV_SEG(env) (env)->prev_seg
964 #define QO_ENV_PARSER(env) (env)->parser
965 #define QO_ENV_PT_TREE(env) (env)->pt_tree
966 #define QO_ENV_TMP_BITSET(env) (env)->tmp_bitset
967 #define QO_ENV_LIMIT_VALUE(env) (env)->limit_value
968 #define QO_ENV_SORT_LIMIT_NODES(env) (env)->sort_limit_nodes
969 #define QO_ENV_USE_SORT_LIMIT(env) ((env)->use_sort_limit == QO_SL_USE)
970 
971 /*
972  * QO_XASL_INDEX_INFO gathers information about the indexed terms which
973  * will be used in the generation of the XASL tree.
974  */
976 {
977  /* Number of term expressions. */
978  int nterms;
979 
980  /* Array of term expressions which are associated with this index. */
982 
983  /*
984  * Pointer to the node index entry structure which contains
985  * infomation regarding the index itself.
986  */
988 
989  /* which col match index col. if -1 then term only have one column. */
993 };
994 
995 #define QO_ON_COND_TERM(term) \
996  (QO_TERM_LOCATION(term) > 0)
997 
998 #define QO_INNER_JOIN_TERM(term) \
999  (QO_TERM_CLASS(term) == QO_TC_JOIN && \
1000  QO_TERM_JOIN_TYPE(term) == JOIN_INNER)
1001 
1002 #define QO_OUTER_JOIN_TERM(term) \
1003  ((QO_TERM_CLASS(term) == QO_TC_JOIN || \
1004  QO_TERM_CLASS(term) == QO_TC_DUMMY_JOIN) && \
1005  (QO_TERM_JOIN_TYPE(term) == JOIN_LEFT || \
1006  QO_TERM_JOIN_TYPE(term) == JOIN_RIGHT || \
1007  QO_TERM_JOIN_TYPE(term) == JOIN_OUTER))
1008 
1009 #define QO_LEFT_OUTER_JOIN_TERM(term) \
1010  ((QO_TERM_CLASS(term) == QO_TC_JOIN || \
1011  QO_TERM_CLASS(term) == QO_TC_DUMMY_JOIN) && \
1012  QO_TERM_JOIN_TYPE(term) == JOIN_LEFT)
1013 
1014 #define QO_RIGHT_OUTER_JOIN_TERM(term) \
1015  ((QO_TERM_CLASS(term) == QO_TC_JOIN || \
1016  QO_TERM_CLASS(term) == QO_TC_DUMMY_JOIN) && \
1017  QO_TERM_JOIN_TYPE(term) == JOIN_RIGHT)
1018 
1019 #define QO_FULL_OUTER_JOIN_TERM(term) \
1020  ((QO_TERM_CLASS(term) == QO_TC_JOIN || \
1021  QO_TERM_CLASS(term) == QO_TC_DUMMY_JOIN) && \
1022  QO_TERM_JOIN_TYPE(term) == JOIN_OUTER)
1023 
1024 #define QO_JOIN_INFO_SIZE(_partition) \
1025  (int)(1 << bitset_cardinality(&(QO_PARTITION_NODES(_partition))))
1026 
1027 
1028 extern void qo_env_free (QO_ENV *);
1029 extern void qo_seg_fprint (QO_SEGMENT *, FILE *);
1030 extern void qo_node_fprint (QO_NODE *, FILE *);
1031 extern void qo_term_fprint (QO_TERM *, FILE *);
1032 extern void qo_print_stats (FILE *);
1033 extern void qo_eqclass_fprint_wrt (QO_EQCLASS *, BITSET *, FILE *);
1034 extern void qo_termset_fprint (QO_ENV *, BITSET *, FILE *);
1035 extern int qo_seg_width (QO_SEGMENT * seg);
1036 extern bool qo_is_prefix_index (QO_INDEX_ENTRY *);
1037 extern bool qo_is_filter_index (QO_INDEX_ENTRY *);
1038 extern void qo_check_coll_optimization (QO_INDEX_ENTRY * ent, COLL_OPT * collation_opt);
1039 extern bool qo_check_type_index_covering (QO_INDEX_ENTRY * ent);
1040 
1041 extern double QO_INFINITY;
1042 
1043 #endif /* _QUERY_GRAPH_H_ */
int nsubqueries
Definition: query_graph.h:896
BITSET subqueries
Definition: query_graph.h:646
QO_CLASS_INFO_ENTRY * class_
Definition: query_graph.h:105
void qo_eqclass_fprint_wrt(QO_EQCLASS *, BITSET *, FILE *)
Definition: query_graph.c:8740
bool class_attr
Definition: query_graph.h:484
BITSET edges
Definition: query_graph.h:811
QO_PARTITION * partitions
Definition: query_graph.h:870
bool index_term_eq_expr
Definition: query_graph.h:488
QO_TERM * terms
Definition: query_graph.h:868
int bail_out
Definition: query_graph.h:913
bool is_iss_candidate
Definition: query_graph.h:155
DB_VALUE limit_value
Definition: query_graph.h:904
int neqclasses
Definition: query_graph.h:894
const char * name
Definition: query_graph.h:49
BITSET outer_dep_set
Definition: query_graph.h:373
BITSET nodes
Definition: query_graph.h:608
bool cover_segments
Definition: query_graph.h:140
BITSET terms
Definition: query_graph.h:134
BITSET nodes
Definition: query_graph.h:810
int force
Definition: query_graph.h:246
QO_TERM * term
Definition: query_graph.h:544
QO_SORT_LIMIT_USE
Definition: query_graph.h:835
Definition: query_graph.h:209
int rangelist_seg_idx
Definition: query_graph.h:125
int self_allocated
Definition: query_graph.h:77
BITSET index_terms
Definition: query_graph.h:501
BITSET eqclasses
Definition: query_graph.h:286
PT_NODE * pt_expr
Definition: query_graph.h:641
int ils_prefix_len
Definition: query_graph.h:158
Definition: query_graph.h:243
int nsegs
Definition: query_graph.h:119
bool multi_range_opt_candidate
Definition: query_graph.h:954
SM_CLASS * smclass
Definition: query_graph.h:73
QO_PLANNER * planner
Definition: query_graph.h:920
bool groupby_skip
Definition: query_graph.h:149
JOIN_TYPE join_type
Definition: query_graph.h:652
PT_NODE * node
Definition: query_graph.h:766
int can_use_index
Definition: query_graph.h:663
short location
Definition: query_graph.h:697
int flag
Definition: query_graph.h:689
BITSET sargs
Definition: query_graph.h:318
QO_ATTR_INFO * info
Definition: query_graph.h:498
BITSET sort_limit_nodes
Definition: query_graph.h:901
bool qo_is_prefix_index(QO_INDEX_ENTRY *)
Definition: query_graph.c:9203
PT_NODE * pt_tree
Definition: query_graph.h:863
PT_HINT_ENUM hint
Definition: query_graph.h:375
BITSET dep_set
Definition: query_graph.h:310
int first_sort_column
Definition: query_graph.h:143
void qo_check_coll_optimization(QO_INDEX_ENTRY *ent, COLL_OPT *collation_opt)
Definition: query_graph.c:9254
QO_EQCLASS * eqclasses
Definition: query_graph.h:867
SM_CLASS_CONSTRAINT * constraints
Definition: query_graph.h:108
int npartitions
Definition: query_graph.h:897
bool orderby_skip
Definition: query_graph.h:146
unsigned long int ncard
Definition: query_graph.h:338
bool sort_limit_candidate
Definition: query_graph.h:377
Definition: query_graph.h:44
MOP mop
Definition: query_graph.h:63
int Nsegs
Definition: query_graph.h:892
JOIN_TYPE
Definition: query_list.h:32
int nedges
Definition: query_graph.h:898
QO_SUBQUERY * subqueries
Definition: query_graph.h:869
BITSET segs
Definition: query_graph.h:285
double selectivity
Definition: query_graph.h:623
bool all_unique_index_columns_are_equi_terms
Definition: query_graph.h:137
bool is_func_index
Definition: query_graph.h:175
QO_PLAN * plan
Definition: query_graph.h:817
unsigned long int tcard
Definition: query_graph.h:339
bool use_descending
Definition: query_graph.h:152
QO_SEGMENT * seg
Definition: query_graph.h:671
void qo_print_stats(FILE *)
Definition: query_graph.c:9166
TP_DOMAIN * key_type
Definition: query_graph.h:116
QO_USING_INDEX * using_index
Definition: query_graph.h:370
PT_HINT_ENUM
Definition: parse_tree.h:1161
QO_ATTR_CUM_STATS cum_stats
Definition: query_graph.h:215
BITSET final_segs
Definition: query_graph.h:886
QO_NODE_INDEX * indexes
Definition: query_graph.h:369
double QO_INFINITY
Definition: query_graph.c:160
const char * name
Definition: query_graph.h:477
void qo_node_fprint(QO_NODE *, FILE *)
Definition: query_graph.c:8162
QO_INDEX * index
Definition: query_graph.h:82
unsigned int BITSET
Definition: esql_misc.h:94
bool plan_dump_enabled
Definition: query_graph.h:948
PT_NODE * key_limit
Definition: query_graph.h:247
PARSER_CONTEXT * parser
Definition: query_graph.h:856
BITSET nodes
Definition: query_graph.h:773
QO_NODE * nodes
Definition: query_graph.h:866
QO_EQCLASS * eqclass
Definition: query_graph.h:686
BITSET multi_col_range_segs
Definition: query_graph.h:184
QO_EQCLASS * eqclass
Definition: query_graph.h:471
int rank
Definition: query_graph.h:634
bool qo_is_filter_index(QO_INDEX_ENTRY *)
Definition: query_graph.c:9228
void qo_termset_fprint(QO_ENV *, BITSET *, FILE *)
Definition: query_graph.c:8845
jmp_buf catch_
Definition: query_graph.h:928
BITSET * tmp_bitset
Definition: query_graph.h:875
QO_SEGMENT * oid_seg
Definition: query_graph.h:301
BITSET dependencies
Definition: query_graph.h:812
PT_NODE * pt_node
Definition: query_graph.h:448
BITSET terms
Definition: query_graph.h:782
QO_CLASS_INFO * info
Definition: query_graph.h:328
QO_SEGMENT * nominal_seg
Definition: query_graph.h:687
PT_NODE * entity_spec
Definition: query_graph.h:279
QO_ENV * env
Definition: query_graph.h:443
BITSET index_segs
Definition: query_graph.h:181
int rangelist_term_idx
Definition: query_graph.h:178
int normal_class
Definition: query_graph.h:80
QO_PLAN * final_plan
Definition: query_graph.h:880
double selectivity
Definition: query_graph.h:319
void qo_term_fprint(QO_TERM *, FILE *)
Definition: query_graph.c:8792
CLASS_STATS * stats
Definition: query_graph.h:76
QO_ENV * env
Definition: query_graph.h:599
void qo_env_free(QO_ENV *)
Definition: query_graph.c:5808
QO_NODE * head
Definition: query_graph.h:455
QO_NODE * tail
Definition: query_graph.h:462
QO_ENV * env
Definition: query_graph.h:271
const char * name
Definition: query_graph.h:245
int qo_seg_width(QO_SEGMENT *seg)
Definition: query_graph.c:8313
bool qo_check_type_index_covering(QO_INDEX_ENTRY *ent)
Definition: query_graph.c:9302
struct qo_index_entry * next
Definition: query_graph.h:102
QO_ATTR_CUM_STATS cum_stats
Definition: query_graph.h:96
BITSET * seg_equal_terms
Definition: query_graph.h:128
QO_SORT_LIMIT_USE use_sort_limit
Definition: query_graph.h:907
PT_NODE ** term_exprs
Definition: query_graph.h:981
int * seg_idxs
Definition: query_graph.h:122
bool sargable
Definition: query_graph.h:376
QO_PARTITION * partition
Definition: query_graph.h:291
QO_SEGMENT * segs
Definition: query_graph.h:865
struct qo_node_index_entry * ni_entry
Definition: query_graph.h:987
char * statistics_attribute_name
Definition: query_graph.h:164
QO_TERMCLASS term_class
Definition: query_graph.h:629
void qo_seg_fprint(QO_SEGMENT *, FILE *)
Definition: query_graph.c:8361
bool is_function_index
Definition: query_graph.h:505
int need_copy_multi_range_term
Definition: query_graph.h:991
QO_NODE * head
Definition: query_graph.h:682
QO_SEGMENT * oid_seg
Definition: query_graph.h:672
int rel_idx
Definition: query_graph.h:359
bool shared_attr
Definition: query_graph.h:485
QO_TERMCLASS
Definition: query_graph.h:562
Definition: query_graph.h:99
int force
Definition: query_graph.h:110
bool dump_enable
Definition: query_graph.h:941
QO_INDEX_ENTRY * head
Definition: query_graph.h:212
bool set_valued
Definition: query_graph.h:483
QO_SEGMENT * eq_root
Definition: query_graph.h:470
BITSET segs
Definition: query_graph.h:772
PT_NODE * key_limit
Definition: query_graph.h:167
QO_NODE * tail
Definition: query_graph.h:683
OID oid
Definition: query_graph.h:54
BITSET * seg_other_terms
Definition: query_graph.h:131
BITSET segments
Definition: query_graph.h:614
int Nterms
Definition: query_graph.h:895
int col_num
Definition: query_graph.h:113
int n
Definition: query_graph.h:218
QO_ENV * env
Definition: query_graph.h:530
BITSET subqueries
Definition: query_graph.h:325
BITSET segs
Definition: query_graph.h:536
BITSET right_dep_set
Definition: query_graph.h:374
int Nnodes
Definition: query_graph.h:893
const char * class_name
Definition: query_graph.h:347
BITSET fake_terms
Definition: query_graph.h:935
int * multi_col_segs
Definition: query_graph.h:703
int multi_col_cnt
Definition: query_graph.h:704