CUBRID Engine  latest
query_planner.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_planner.h - Query plan
22  */
23 
24 #ifndef _QUERY_PLANNER_H_
25 #define _QUERY_PLANNER_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 "optimizer.h"
34 #include "query_bitset.h"
35 
36 // forward definitions
37 struct xasl_node;
38 namespace cubxasl
39 {
40  struct analytic_eval_type;
41 }
42 
43 #define QO_CPU_WEIGHT 0.0025
44 
45 typedef enum
46 {
52 } QO_PLANTYPE;
53 
54 typedef enum
55 {
62 
63 typedef enum
64 {
69 
70 typedef struct qo_plan_vtbl QO_PLAN_VTBL;
72 {
73  const char *plan_string;
74  void (*fprint_fn) (QO_PLAN *, FILE *, int);
75  void (*walk_fn) (QO_PLAN *, void (*)(QO_PLAN *, void *), void *, void (*)(QO_PLAN *, void *), void *);
76  void (*free_fn) (QO_PLAN *);
77  void (*cost_fn) (QO_PLAN *);
78  void (*default_cost) (QO_PLAN *);
79  void (*info_fn) (QO_PLAN *, FILE *, int);
80  const char *info_string;
81 };
82 
83 typedef enum
84 {
90 
91 typedef enum
92 {
98 
99 struct qo_plan
100 {
102 
103  int refcount;
104 
105  /*
106  * A plan is "top-rooted" if it is a top level plan
107  */
109 
110  /*
111  * A plan is "well-rooted" if it is a scan plan, or if it is a follow
112  * plan whose subplan is itself well-rooted. These are plans that
113  * won't require the construction of any temporary files during
114  * execution. The current generation of XASL can't cope with
115  * temporary files for some kinds of queries (in particular, those
116  * with subqueries in the select list), so we have to be sure to
117  * avoid generating plans that require that kind of implementation.
118  */
120 
121  /* CPU and IO cost which are fixed against join position(inner or outer) */
122  double fixed_cpu_cost, fixed_io_cost;
123  /* CPU and IO cost which are variable according to join position */
124  double variable_cpu_cost, variable_io_cost;
127  PT_NODE *iscan_sort_list; /* sorting fields */
128 
129  /*
130  * The set of correlated subqueries that are "covered" by this plan.
131  * These are the subqueries that must be reevaluated every time a new
132  * candidate row is produced by this plan.
133  */
135 
138 
139  union
140  {
141  struct
142  {
143  QO_PLAN *link;
144  } free;
145 
146  struct
147  {
148  QO_SCANMETHOD scan_method; /* SEQ_SCAN, INDEX_SCAN */
153  bool index_cover; /* covered index scan flag */
154  bool index_iss; /* index skip scan flag */
155  bool index_loose; /* loose index scan flag */
157  BITSET multi_col_range_segs; /* range condition segs for multi_col_term */
158  BITSET hash_terms; /* hash_terms for hash list scan */
159  } scan;
160 
161  /*
162  * Sort nodes are now really "build a temp file" nodes; the
163  * created temp file may be sorted or unsorted. If sorted, the
164  * `order' field indicates the sorting order; if unsorted, the
165  * `order' field is NULL. The `tmpnum' field is assigned during
166  * plan finalization; it is the logical number of the temporary
167  * file to be created at runtime.
168  */
169  struct
170  {
172 #if 0 /* DO NOT DELETE ME - need future work */
174 #endif
175  QO_PLAN *subplan;
177  } sort;
178 
179  struct
180  {
181  JOIN_TYPE join_type; /* JOIN_INNER, _LEFT, _RIGHT, _OUTER */
182  QO_JOINMETHOD join_method; /* NL_JOIN, MERGE_JOIN */
183  QO_PLAN *outer;
184  QO_PLAN *inner;
185  BITSET join_terms; /* all join edges */
186  BITSET during_join_terms; /* during join terms */
187  BITSET other_outer_join_terms; /* for merge outer join only */
188  BITSET after_join_terms; /* after join terms */
189  BITSET hash_terms; /* hash_terms for hash list scan */
190  } join;
191 
192  struct
193  {
194  QO_PLAN *head;
196  } follow;
197 
198  } plan_un;
199 
200  QO_PLAN_ULTI_RANGE_OPT_USE multi_range_opt_use; /* used to determine if this plan uses multi range opt */
201  // *INDENT-OFF*
202  cubxasl::analytic_eval_type *analytic_eval_list; /* analytic evaluation list */
203  // *INDENT-ON*
204  bool has_sort_limit; /* true if this plan or one if its subplans is a SORT-LIMIT plan */
206 };
207 
208 #define qo_plan_add_ref(p) ((p->refcount)++, (p))
209 #define qo_plan_del_ref(p) do { \
210  QO_PLAN *__p = (p); \
211  if ((__p) && --(__p->refcount) == 0) \
212  qo_plan_free(__p); \
213  } while(0)
214 #define qo_plan_release(p) do { \
215  QO_PLAN *__p = (p); \
216  if ((__p) && (__p->refcount) == 0) \
217  qo_plan_free(__p); \
218  } while(0)
219 
220 #define NPLANS 4 /* Maximum number of plans to keep in a PlanVec */
221 
222 typedef struct qo_planvec QO_PLANVEC;
224 {
225  QO_PLAN *plan[NPLANS];
226  int nplans;
227  bool overflow;
228 };
229 
230 struct qo_info
231 {
232  struct qo_info *next;
233 
234  /*
235  * The environment relative to which all of the following sets, etc.
236  * make sense.
237  */
239 
240  /*
241  * The Planner instance to which this Info node belongs. I wish
242  * we didn't have to do this, but there are just enough occassions
243  * where we need the back pointer that it is easier just to include
244  * it and be done with it. This pointer is NULL if this info node
245  * has been "detached" from the planner; this happens when the
246  * winning plan is "finalized".
247  */
249 
250  /*
251  * The lowest-cost plan without regard to ordering.
252  */
254 
255  /*
256  * The set of nodes joined by the plans at this node.
257  */
259 
260  /*
261  * All of the terms accounted for by the plans in this node and their
262  * descendents, i.e., the complement of the terms remaining to be
263  * dealt with.
264  */
266 
267  /*
268  * The equivalence classes represented by all of the attributes
269  * (segments) joined together in this node.
270  */
272 
273  /*
274  * 'projected_segs' is the set of segments (attributes) that need to
275  * be projected from this plan produced by this node in order to
276  * satisfy the needs of upper level plans. 'projected_size' is the
277  * number of bytes per record required by 'projected_segs'.
278  * 'cardinality' is the estimated cardinality of the results produced
279  * by plans at this node.
280  */
282  double cardinality;
283 
284  /*
285  * One plan for each equivalence class, in each case the best we have
286  * seen so far. This vector is NULL after a node is detached.
287  */
289 
291 
292  /*
293  * The last join level.
294  */
296 
297  /*
298  * `detached' is true iff the node has been detached; we can no
299  * longer just use the value of `plans' as the indicator because
300  * dependent derived tables can give rise to join graphs that couple
301  * nodes together without creating an equivalence class, and thus
302  * without the need to populate the `plans' vector.
303  */
304  int detached;
305 };
306 
308 {
309  /*
310  * The struct that encapsulates the information involved in searching
311  * for an optimal query plan.
312  */
313 
314  /*
315  * The environment that supplies the various nodes, edges, segments, etc.
316  */
318 
319  /*
320  * The relations being considered in this join; there are N of them.
321  */
323 
324  /*
325  * The join terms (e.g., employee.dno = dept.dno); there are T of
326  * them, E of which are actual edges in the join graph. node_mask is
327  * a bit mask used to mask out non-node terms from node bitsets.
328  * M is simply 2^N, and is the size of the join_info vector that will
329  * be allocated.
330  */
332  unsigned int N;
333  unsigned int E, M, T;
334  unsigned long node_mask;
335 
336  /*
337  * The path segments involved in the various join terms, and the
338  * equivalence classes implied by those joins (e.g., if we have join
339  * terms c1 = c2 and c2 = c3, (c1,c2,c3) is an equivalence class for
340  * the purposes of determining sort orderings).
341  */
343 
345 
346  /*
347  * The partitions (strong components) of the join graph.
348  */
350 
351  /*
352  * The last join level.
353  */
355  unsigned int S;
356  unsigned int EQ;
357  unsigned int P;
358 
359  /*
360  * The (level-1 correlated) subqueries used in this query.
361  */
364  unsigned int Q;
365 
366  /*
367  * The final set of segments to be projected out of the top-level
368  * plan produced by this planner.
369  */
371 
372 
377 
378  QO_PLAN *worst_plan;
380 
381  /* alloced info list */
383 
384  /*
385  * true iff qo_planner_cleanup() needs to be called before freeing
386  * this planner. This is needed to help clean up after aborts, when
387  * control flow takes an unexpected longjmp.
388  */
390 };
391 
392 extern QO_PLAN *qo_planner_search (QO_ENV *);
393 extern void qo_planner_free (QO_PLANNER *);
394 extern void qo_plans_stats (FILE *);
395 extern void qo_info_stats (FILE *);
396 
397 extern bool qo_is_seq_scan (QO_PLAN *);
398 extern bool qo_is_iscan (QO_PLAN *);
399 extern bool qo_is_iscan_from_groupby (QO_PLAN *);
400 extern bool qo_is_iscan_from_orderby (QO_PLAN *);
401 extern bool qo_is_interesting_order_scan (QO_PLAN *);
402 extern bool qo_is_all_unique_index_columns_are_equi_terms (QO_PLAN * plan);
403 extern bool qo_has_sort_limit_subplan (QO_PLAN * plan);
404 #endif /* _QUERY_PLANNER_H_ */
bool index_cover
QO_INFO * info
SORT_TYPE sort_type
QO_EQCLASS * order
QO_PLAN * link
bool qo_is_interesting_order_scan(QO_PLAN *)
Definition: query_graph.h:209
bool has_sort_limit
QO_INFO ** node_info
QO_PLAN * worst_plan
BITSET multi_col_range_segs
SORT_TYPE
Definition: query_list.h:389
BITSET during_join_terms
unsigned int P
JOIN_TYPE join_type
QO_PLAN * head
int detached
QO_INFO * info_list
QO_PLANNER * planner
BITSET join_terms
QO_PARTITION * partition
QO_PLAN * qo_planner_search(QO_ENV *)
QO_SCANMETHOD
Definition: query_planner.h:54
JOIN_TYPE
Definition: query_list.h:32
unsigned int S
#define NPLANS
void qo_plans_stats(FILE *)
QO_SUBQUERY * subqueries
int projected_size
bool qo_is_iscan_from_orderby(QO_PLAN *)
QO_SEGMENT * segment
QO_PLAN_ULTI_RANGE_OPT_USE
Definition: query_planner.h:91
void qo_planner_free(QO_PLANNER *)
bool index_iss
xasl_node * xasl
void qo_info_stats(FILE *)
BITSET terms
unsigned long node_mask
BITSET other_outer_join_terms
QO_PLAN * outer
QO_NODE * node
unsigned int BITSET
Definition: esql_misc.h:94
BITSET after_join_terms
QO_JOINMETHOD join_method
unsigned int Q
QO_INFO * best_info
bool top_rooted
QO_INFO ** cp_info
BITSET all_subqueries
bool use_iscan_descending
struct qo_info * next
int refcount
QO_INFO * worst_info
BITSET projected_segs
bool index_equi
BITSET final_segs
bool well_rooted
int cleanup_needed
const char * plan_string
Definition: query_planner.h:73
unsigned int EQ
QO_PLAN_ULTI_RANGE_OPT_USE multi_range_opt_use
QO_PLAN_VTBL * vtbl
unsigned int N
unsigned int T
QO_PLANVEC best_no_order
bool index_loose
bool qo_is_iscan(QO_PLAN *)
BITSET subqueries
PT_NODE * iscan_sort_list
QO_JOINMETHOD
Definition: query_planner.h:63
QO_INFO ** join_info
bool qo_is_all_unique_index_columns_are_equi_terms(QO_PLAN *plan)
QO_PLAN * inner
BITSET terms
QO_NODE_INDEX_ENTRY * index
BITSET sarged_terms
QO_PLAN * subplan
BITSET nodes
const char * info_string
Definition: query_planner.h:80
int join_unit
BITSET hash_terms
bool qo_has_sort_limit_subplan(QO_PLAN *plan)
double cardinality
BITSET kf_terms
QO_PLAN_COMPARE_RESULT
Definition: query_planner.h:83
QO_NODE * node
QO_SCANMETHOD scan_method
QO_EQCLASS * eqclass
BITSET eqclasses
bool qo_is_seq_scan(QO_PLAN *)
bool qo_is_iscan_from_groupby(QO_PLAN *)
QO_TERM * path
double variable_io_cost
QO_PLANTYPE
Definition: query_planner.h:45
QO_ENV * env
QO_PLANTYPE plan_type
cubxasl::analytic_eval_type * analytic_eval_list
QO_PLANVEC * planvec
QO_TERM * term
double fixed_io_cost
QO_ENV * env