56 #define INDENT_FMT "%*c" 58 #define TITLE_FMT "%-" __STR(TITLE_WIDTH) "s" 59 #define INDENTED_TITLE_FMT INDENT_FMT TITLE_FMT 60 #define __STR(n) __VAL(n) 62 #define SORT_SPEC_FMT(spec) \ 63 "%d %s %s", (spec)->pos_descr.pos_no + 1, \ 64 ((spec)->s_order == S_ASC ? "asc" : "desc"), \ 65 ((spec)->s_nulls == S_NULLS_FIRST ? "nulls first" : "nulls last") 67 #define VALID_INNER(plan) (plan->well_rooted || \ 68 (plan->plan_type == QO_PLANTYPE_SORT)) 70 #define FUDGE_FACTOR 0.7 71 #define ISCAN_OVERHEAD_FACTOR 1.2 72 #define TEMP_SETUP_COST 5.0 73 #define NONGROUPED_SCAN_COST 0.1 75 #define qo_scan_walk qo_generic_walk 76 #define qo_worst_walk qo_generic_walk 78 #define qo_generic_free NULL 79 #define qo_sort_free qo_generic_free 80 #define qo_follow_free qo_generic_free 81 #define qo_worst_free qo_generic_free 83 #define QO_INFO_INDEX(_M_offset, _bitset) \ 84 (_M_offset + (unsigned int)(BITPATTERN(_bitset) & planner->node_mask)) 86 #define QO_IS_LIMIT_NODE(env, node) \ 87 (BITSET_MEMBER (QO_ENV_SORT_LIMIT_NODES ((env)), QO_NODE_IDX ((node)))) 150 static double log3 (
double);
311 "Correlated-index join" 370 #define DEFAULT_NULL_SELECTIVITY (double) 0.01 371 #define DEFAULT_EXISTS_SELECTIVITY (double) 0.1 372 #define DEFAULT_SELECTIVITY (double) 0.1 373 #define DEFAULT_EQUAL_SELECTIVITY (double) 0.001 374 #define DEFAULT_EQUIJOIN_SELECTIVITY (double) 0.001 375 #define DEFAULT_COMP_SELECTIVITY (double) 0.1 376 #define DEFAULT_BETWEEN_SELECTIVITY (double) 0.01 377 #define DEFAULT_IN_SELECTIVITY (double) 0.01 378 #define DEFAULT_RANGE_SELECTIVITY (double) 0.1 421 static int initialized = 0;
435 return log (n) / ln3;
449 if (qo_plan_free_list)
483 static char buf[257];
488 const char *separator;
496 saved_next = conj->
next;
503 sprintf (buf,
"table(");
552 conj->
next = saved_next;
570 double temp_cpu_cost, temp_io_cost;
571 double subq_cpu_cost, subq_io_cost;
577 subq_cpu_cost = subq_io_cost = 0.0;
594 subq_cpu_cost += temp_cpu_cost;
595 subq_io_cost += temp_io_cost;
599 (*(plan->
vtbl)->cost_fn) (plan);
622 double arg1_cpu_cost, arg1_io_cost, arg2_cpu_cost, arg2_io_cost;
624 *subq_cpu_cost = *subq_io_cost = 0.0;
626 if (subquery ==
NULL)
631 *subq_cpu_cost = 5.0;
648 *subq_cpu_cost = 5.0;
662 *subq_cpu_cost = arg1_cpu_cost + arg2_cpu_cost;
663 *subq_io_cost = arg1_io_cost + arg2_io_cost;
671 *subq_cpu_cost = 5.0;
701 return f (plan, arg);
738 && plan->
plan_un.
scan.index->head->groupby_skip ==
true)
740 && plan->
plan_un.
scan.index->head->orderby_skip ==
true))
742 plan->
plan_un.
scan.index->head->use_descending =
true;
816 bool yn = *((
bool *) arg);
854 PT_NODE *tree, *group_by, *order_by, *orderby_for;
891 if (group_by || (all_distinct ==
PT_DISTINCT || order_by))
894 bool groupby_skip, orderby_skip, is_index_w_prefix;
900 groupby_skip = orderby_skip =
false;
910 found_instnum = (t == -1) ?
false :
true;
962 plan->
plan_un.
scan.index->head->groupby_skip =
true;
997 if (found_instnum && orderby_for)
1079 void (*parent_fn) (
QO_PLAN *,
void *),
void *parent_data)
1083 (*parent_fn) (plan, parent_data);
1098 bool is_sort_spec_asc =
true;
1108 for (; list; list = list->
next)
1118 is_sort_spec_asc =
true;
1122 is_sort_spec_asc =
false;
1131 fprintf (f,
" collate %s",
1148 bool is_iscan_asc =
true;
1164 env = (plan->
info)->env;
1203 fprintf (f,
"\n" INDENTED_TITLE_FMT "%.0f card %.0f", (
int) howfar,
' ',
"cost:", fixed + variable,
1204 (plan->
info)->cardinality);
1219 const char *prefix =
"";
1222 if (!((plan->
info)->env->dump_enable))
1313 fprintf (f,
"\n\nAnalytic functions:");
1319 sprintf (buf,
"run[%d]: ", k);
1321 fprintf (f,
"sort with key (");
1334 for (func = eval->
head; func !=
NULL; func = func->
next, i++)
1338 fprintf (f,
"func[%d]: ", i);
1342 fputs (
" partition by (", f);
1353 fputs (
") order by (", f);
1501 int col_num = index_entryp->
col_num;
1504 for (j = 0; j < col_num; j++)
1540 bool first_col_present =
false;
1561 if (range_terms !=
NULL)
1568 if (indexable_terms !=
NULL)
1584 first_seg = index_entryp->
seg_idxs[0];
1586 if (range_terms !=
NULL)
1597 first_col_present =
true;
1625 for (t = 0; t < index_entryp->
nsegs; t++)
1627 if ((index_entryp->
seg_idxs[t]) != -1)
1735 if (first_col_present ==
false)
1827 double sel, sel_limit, objects, height, leaves, opages;
1829 double object_IO, index_IO;
1832 int i, t,
n, pkeys_num;
1836 index_entryp = (ni_entryp)->
head;
1839 if (index_entryp->
force < 0)
1845 else if (index_entryp->
force > 0)
1856 for (i = 0; i <
n; i++)
1879 is_null_sel =
false;
1892 if (pkeys_num > 0 && cum_statsp->
pkeys[0] > 1)
1894 sel_limit = 1.0 / (double) cum_statsp->
pkeys[0];
1899 if (cum_statsp->
keys > 1)
1901 sel_limit = 1.0 / (double) cum_statsp->
keys;
1917 assert (sel_limit < 1.0);
1920 if (is_null_sel ==
false)
1922 sel = MAX (sel, sel_limit);
1925 assert ((is_null_sel ==
false && sel == 1.0) || (is_null_sel ==
true && sel == 0.0));
1938 for (
int j = 0; j < index_entryp->
col_num; j++)
1947 sel = MIN (sel, 1.0);
1952 if (i < pkeys_num && cum_statsp->pkeys[i] > 1)
1954 sel_limit = 1.0 / (double) cum_statsp->
pkeys[i];
1958 if (cum_statsp->
keys > 1)
1960 sel_limit = 1.0 / (double) cum_statsp->
keys;
1971 assert (sel_limit < 1.0);
1974 sel = MAX (sel, sel_limit);
1977 assert ((is_null_sel ==
false) || (is_null_sel ==
true && sel == 0.0));
1982 height = (double) cum_statsp->
height - 1;
1988 leaves = ceil (sel * (
double) cum_statsp->
leafs);
1992 index_IO = ((ni_entryp)->n * height) + leaves;
2005 index_IO += cum_statsp->
pkeys[0] * ((ni_entryp)->n * height);
2008 index_IO += cum_statsp->
pkeys[0];
2016 object_IO = opages * sel;
2022 object_IO = opages * (0.8 * sel + 0.36);
2032 if (object_IO < 1.0)
2047 object_IO = MAX (1.0, object_IO);
2070 bool natural_desc_index =
false;
2072 if (plan->
plan_un.
scan.node->entity_spec->info.spec.cte_pointer)
2094 fprintf (f,
"%s ", plan->
plan_un.
scan.index->head->constraints->name);
2107 saved_next->
next = key_limit;
2114 key_limit->next = saved_next;
2128 fprintf (f,
"(covers)");
2133 fprintf (f,
" (index skip scan)");
2138 fprintf (f,
" (loose index scan on prefix %d)", plan->
plan_un.
scan.index->head->ils_prefix_len);
2143 fprintf (f,
" (multi_range_opt)");
2148 fprintf (f,
" (desc_index)");
2149 natural_desc_index =
true;
2154 fprintf (f,
" (desc_index forced)");
2179 fprintf (f,
"\n%*c%s(", (
int) howfar,
' ', (plan->
vtbl)->info_string);
2185 fprintf (f,
"%s ", (name ? name :
"(anon)"));
2191 fprintf (f,
"%s", (name ? name :
"(unknown)"));
2195 fprintf (f,
"as %s", (name ? name :
"(unknown)"));
2203 const char *separator;
2204 bool natural_desc_index =
false;
2206 env = (plan->
info)->env;
2209 fprintf (f,
"%s%s", separator, plan->
plan_un.
scan.index->head->constraints->name);
2221 saved_next->
next = key_limit;
2228 key_limit->next = saved_next;
2236 separator =
" and ";
2244 separator =
" and ";
2252 fprintf (f,
" (covers)");
2257 fprintf (f,
" (index skip scan)");
2262 fprintf (f,
" (loose index scan on prefix %d)", plan->
plan_un.
scan.index->head->ils_prefix_len);
2267 fprintf (f,
" (multi_range_opt)");
2272 fprintf (f,
" (desc_index)");
2273 natural_desc_index =
true;
2278 fprintf (f,
" (desc_index forced)");
2333 if (subplan ==
NULL)
2350 plan->
order = order;
2379 void (*parent_fn) (
QO_PLAN *,
void *),
void *parent_data)
2383 (*child_fn) (plan->
plan_un.
sort.subplan, child_data);
2387 (*parent_fn) (plan, parent_data);
2402 fprintf (f,
"(sort limit)");
2406 fprintf (f,
"(group by)");
2410 fprintf (f,
"(order by)");
2414 fprintf (f,
"(distinct)");
2446 fprintf (f,
"\n%*c%s(", (
int) howfar,
' ', (plan->
vtbl)->info_string);
2453 fprintf (f,
"\n%*c%s(%s)", (
int) howfar,
' ', (plan->
vtbl)->info_string,
"sort limit");
2457 fprintf (f,
"\n%*c%s(%s)", (
int) howfar,
' ', (plan->
vtbl)->info_string,
"group by");
2462 fprintf (f,
"\n%*c%s(%s)", (
int) howfar,
' ', (plan->
vtbl)->info_string,
"order by");
2467 fprintf (f,
"\n%*c%s(%s)", (
int) howfar,
' ', (plan->
vtbl)->info_string,
"distinct");
2528 double objects, pages, result_size;
2530 order = planp->
order;
2531 objects = (subplanp->
info)->cardinality;
2532 result_size = objects * (double) (subplanp->
info)->projected_size;
2549 double sort_io, tcard;
2568 sort_io = pages *
log3 (pages / 4.0);
2641 switch (join_method)
2686 if ((inner->
info)->cardinality < (outer->
info)->cardinality)
2719 if (inner ==
NULL || outer ==
NULL)
2854 void (*parent_fn) (
QO_PLAN *,
void *),
void *parent_data)
2858 (*child_fn) (plan->
plan_un.
join.outer, child_data);
2859 (*child_fn) (plan->
plan_un.
join.inner, child_data);
2863 (*parent_fn) (plan, parent_data);
2882 fputs (
" (inner join)", f);
2888 fputs (
" (inner join)", f);
2892 fputs (
" (cross join)", f);
2897 fputs (
" (left outer join)", f);
2900 fputs (
" (right outer join)", f);
2903 fputs (
" (full outer join)", f);
2906 fputs (
" (cselect join)", f);
2910 fputs (
" (unknown join type)", f);
2936 const char *separator;
2940 env = (plan->
info)->env;
2943 fprintf (f,
"\n%*c%s(", (
int) howfar,
' ', (plan->
vtbl)->info_string);
2947 separator =
" and ";
2953 fprintf (f,
"\n%*cNested loops", (
int) howfar,
' ');
2958 fprintf (f,
": left outer");
2962 fprintf (f,
": right outer");
2979 double inner_io_cost, inner_cpu_cost, outer_io_cost, outer_cpu_cost;
2980 double pages, guessed_result_cardinality;
2981 double pages2, io_cost, diff_cost;
3015 guessed_result_cardinality = (outer->
info)->cardinality;
3017 inner_cpu_cost = guessed_result_cardinality * (double)
QO_CPU_WEIGHT;
3043 if (inner_io_cost > pages * 2)
3046 inner_io_cost = pages * 2;
3050 inner_io_cost = MAX (0.0, inner_io_cost);
3056 if ((outer->
info)->cardinality == (inner->
info)->cardinality)
3066 inner_io_cost += diff_cost + 0.1;
3087 if (inner_io_cost > pages2)
3089 diff_cost = inner_io_cost - pages2;
3092 inner_io_cost = pages2;
3098 diff_cost = MIN (io_cost, diff_cost);
3120 double temp_cpu_cost, temp_io_cost;
3121 double subq_cpu_cost, subq_io_cost;
3136 subq_cpu_cost = subq_io_cost = 0.0;
3143 subq_cpu_cost += temp_cpu_cost;
3144 subq_io_cost += temp_io_cost;
3147 planp->
variable_cpu_cost += MAX (0.0, guessed_result_cardinality - 1.0) * subq_cpu_cost;
3163 double outer_cardinality = 0.0, inner_cardinality = 0.0;
3225 BITSET * pinned_subqueries)
3278 void (*parent_fn) (
QO_PLAN *,
void *),
void *parent_data)
3286 (*parent_fn) (plan, parent_data);
3329 double cardinality, target_pages, fetch_ios;
3341 cardinality = (planp->
info)->cardinality;
3345 if (cardinality < target_pages)
3350 fetch_ios = cardinality;
3357 fetch_ios = target_pages;
3392 sarged_terms, pinned_subqueries, &empty_terms );
3455 fprintf (f,
"\n%*c%s", (
int) howfar,
' ', (plan->
vtbl)->info_string);
3526 sort_subplan_p = sort_plan_p->
plan_un.
sort.subplan;
3576 #define QO_PLAN_CMP_CHECK_COST(a, b) 3578 #define QO_PLAN_CMP_CHECK_COST(a, b) assert ((a) < ((b)*10)); 3582 if (QO_PLAN_FIXED_COST (a) <= QO_PLAN_FIXED_COST (b))
3584 return QO_PLAN_ACCESS_COST (a) <= QO_PLAN_ACCESS_COST (b) ? a : b;
3588 return QO_PLAN_ACCESS_COST (b) <= QO_PLAN_ACCESS_COST (a) ? b : a;
3591 double af, aa, bf, ba;
3915 int a_range, b_range;
3916 int a_filter, b_filter;
3919 int a_pages, b_pages;
3920 int a_leafs, b_leafs;
3926 a_ent = (a_ni)->
head;
3932 if (a_cum->
pkeys[i] <= 0)
3951 b_ent = (b_ni)->
head;
3957 if (b_cum->
pkeys[i] <= 0)
3980 if (a_range == b_range && a_filter == b_filter)
3984 else if (a_range >= b_range && a_filter >= b_filter)
3989 else if (a_range <= b_range && a_filter <= b_filter)
4018 if (a_range == a_ent->
col_num)
4020 a_keys = a_cum->
keys;
4022 else if (a_range > 0 && a_range < a_last)
4024 a_keys = a_cum->
pkeys[a_range - 1];
4041 a_keys = MIN (a_cum->
pkeys[0], a_keys);
4045 if (a_cum->
leafs <= a_keys)
4049 else if (a_keys == 0)
4055 a_leafs = (int) ceil ((
double) a_cum->
leafs / a_keys);
4059 a_pages = a_leafs + a_cum->
height - 1;
4062 if (b_range == b_ent->
col_num)
4064 b_keys = b_cum->
keys;
4066 else if (b_range > 0 && b_range < b_last)
4068 b_keys = b_cum->
pkeys[b_range - 1];
4085 b_keys = MIN (b_cum->
pkeys[0], b_keys);
4089 if (b_cum->
leafs <= b_keys)
4093 else if (b_keys == 0)
4099 b_leafs = (int) ceil ((
double) b_cum->
leafs / b_keys);
4103 b_pages = b_leafs + b_cum->
height - 1;
4105 if (a_pages < b_pages)
4110 else if (a_pages > b_pages)
4133 if (a_keys > b_keys)
4138 else if (a_keys < b_keys)
4144 if (af == bf && aa == ba)
4216 if (a == b || (af == bf && aa == ba))
4220 if (af <= bf && aa <= ba)
4225 if (bf <= af && ba <= aa)
4269 int a_mro_join_idx = -1, b_mro_join_idx = -1;
4277 if (a_mro_join_idx < b_mro_join_idx)
4281 else if (a_mro_join_idx > b_mro_join_idx)
4323 int a_range, b_range;
4357 if (a_range >= b_range)
4366 if (b_range >= a_range)
4405 fputs ((plan->
vtbl)->plan_string, f);
4410 title_len = title ? (int)
strlen (title) : 0;
4414 (*((plan->
vtbl)->fprint_fn)) (plan, f, howfar);
4434 (*((plan->
vtbl)->info_fn)) (plan, f, howfar);
4467 env = (plan->
info)->env;
4492 void (*parent_fn) (
QO_PLAN *,
void *),
void *parent_data)
4494 (*(plan->
vtbl)->walk_fn) (plan, child_fn, child_data, parent_fn, parent_data);
4525 memset ((
void *) plan, 0,
sizeof (*plan));
4527 qo_plan_free_list = plan;
4547 #if defined(CUBRID_DEBUG) 4548 fprintf (stderr,
"*** optimizer problem: plan refcount = %d ***\n", plan->
refcount);
4553 if ((plan->
vtbl)->free_fn)
4555 (*(plan->
vtbl)->free_fn) (plan);
4570 qo_plan_free_list =
NULL;
4587 while (qo_plan_free_list)
4632 fputs (
"\nNo optimized plan!\n", output);
4646 fputs (
"\n", output);
4663 int n = DIM (all_vtbls);
4667 for (i = 0; i <
n; i++)
4703 int n = DIM (all_vtbls);
4706 for (i = 0; i <
n; i++)
4767 const char *plan_string;
4768 const char *cost_string;
4778 plan_string =
"unknown";
4800 if (plan_string !=
NULL)
4840 for (i = 0; i < planvec->
nplans; ++
i)
4860 int positive_indent = indent < 0 ? -indent : indent;
4864 fputs (
"(overflowed) ", f);
4867 for (i = 0; i < planvec->
nplans; ++
i)
4871 indent = positive_indent;
4891 int already_retained;
4902 already_retained = 0;
4905 for (i = 0; i < planvec->
nplans; i++)
4921 if (already_retained)
4936 planvec->
plan[
i] = plan;
4938 already_retained = 1;
4963 if (!already_retained && !num_eq)
4971 planvec->
plan[
i] = plan;
4972 already_retained = 1;
4976 int best_vc_pid, best_tc_pid;
4977 int worst_vc_pid, worst_tc_pid;
4978 double vc, tc, p_vc, p_tc;
4988 best_vc_pid = best_tc_pid = -1;
4993 for (i = 0; i < planvec->
nplans; i++)
4995 p = planvec->
plan[
i];
5013 worst_vc_pid = worst_tc_pid = -1;
5018 for (i = 0; i < planvec->
nplans; i++)
5020 p = planvec->
plan[
i];
5024 if (i != best_vc_pid && i != best_tc_pid)
5040 if (worst_tc_pid != -1)
5044 planvec->
plan[worst_tc_pid] = plan;
5045 already_retained = 1;
5047 else if (worst_vc_pid != -1)
5051 planvec->
plan[worst_vc_pid] = plan;
5052 already_retained = 1;
5066 if (already_retained)
5092 for (i = 0; i < planvec->
nplans; i++)
5117 double fixed, variable, best_cost, cost;
5125 best_plan = planvec->
plan[0];
5128 best_cost = fixed + (n * variable);
5129 for (i = 1; i < planvec->
nplans; i++)
5131 plan = planvec->
plan[
i];
5134 cost = fixed + (n * variable);
5136 if (cost < best_cost)
5196 info->
env = planner->
env;
5233 for (i = 0; i < EQ; ++
i)
5293 for (i = 0; i < EQ; ++
i)
5316 order = plan->
order;
5331 QO_PLAN *new_plan, *sort_plan, *best_plan;
5345 if (sort_plan !=
NULL)
5349 best_plan = sort_plan;
5357 for (i = 0; i < EQ; i++)
5396 bool found_new_best;
5404 found_new_best =
false;
5406 plan_order = plan->
order;
5462 found_new_best =
true;
5471 if (found_new_best !=
true)
5494 QO_PLAN *temp, *best_plan, *inner;
5495 double temp_cost, best_cost;
5523 inner = pv->
plan[
i];
5526 if (idx_join_plan_n > 0)
5537 if (best_plan ==
NULL || temp_cost < best_cost)
5540 best_cost = temp_cost;
5581 pv = &info->
planvec[order_idx];
5675 int idx_join_plan_n,
BITSET * hash_terms)
5678 QO_PLAN *outer_plan, *inner_plan;
5727 if (outer_plan ==
NULL)
5732 if (inner_plan ==
NULL)
5752 if (outer_plan ==
NULL)
5757 if (inner_plan ==
NULL)
5804 duj_terms, afj_terms, sarged_terms, pinned_subqueries, hash_terms));
5829 QO_PLAN *outer_plan, *inner_plan;
5864 #ifdef OUTER_MERGE_JOIN_RESTRICTION 5901 if (outer_plan ==
NULL)
5907 if (inner_plan ==
NULL)
5949 sm_join_terms, duj_terms, afj_terms, sarged_terms, pinned_subqueries,
6002 if (outer_plan ==
NULL)
6021 if (node_indexp ==
NULL)
6059 for (i = 0; i <
QO_NI_N (node_indexp); i++)
6064 index_entryp = (ni_entryp)->
head;
6065 if (index_entryp->
force < 0)
6084 afj_terms, sarged_terms, pinned_subqueries);
6091 if (n == 0 && num_only_args)
6094 for (i = 0; i <
QO_NI_N (node_indexp); i++)
6099 index_entryp = (ni_entryp)->
head;
6100 if (index_entryp->
force < 0)
6117 afj_terms, sarged_terms, pinned_subqueries);
6139 BITSET * pinned_subqueries)
6155 path_term, sarged_terms, pinned_subqueries));
6187 for (i = 0; i < (signed) planner->
T; i++)
6191 term = &planner->
term[
i];
6196 for (i = 0; i < (signed) planner->
N; ++i)
6250 fputs (
" projected segments: ", f);
6254 fputs (
" best: ", f);
6261 fputs (
"(empty)\n\n", f);
6266 for (i = 0; i < (signed) info->
planner->
EQ; ++i)
6272 sprintf (buf,
"[%d]: ", i);
6273 fprintf (f,
"%8s", buf);
6303 if (planner ==
NULL)
6316 if (planner->
N < 32)
6318 planner->
node_mask = (
unsigned long) ((
unsigned int) (1 << planner->
N) - 1);
6339 for (i = 0; i < (signed) planner->
Q; ++i)
6371 for (info = planner->
info_list; info; info = next_info)
6373 next_info = info->
next;
6412 fputs (
"\nNode info maps:\n", f);
6413 for (i = 0; i < (signed) planner->
N; i++)
6420 fprintf (f,
"node_info[%d]:\n", i);
6428 fputs (
"\nJoin info maps:\n", f);
6432 for (i = i + 3; i < M; i++)
6437 fputs (
"join_info[", f);
6472 BITSET * remaining_subqueries,
int num_path_inner)
6476 int idx_join_cnt = 0;
6483 bool check_afj_terms =
false;
6484 bool is_dummy_term =
false;
6492 BITSET pinned_subqueries;
6503 if (head_node ==
NULL)
6512 int found_num, found_idx;
6603 if (head_info ==
NULL)
6655 goto go_ahead_subvisit;
6670 int retry_cnt, edge_cnt, path_cnt;
6677 edge_cnt = path_cnt = 0;
6741 if (found_edge ==
true)
6747 if (join_type ==
NO_JOIN || is_dummy_term)
6788 if (follow_term ==
NULL)
6855 check_afj_terms =
true;
6894 goto retry_join_edge;
6969 if (new_info ==
NULL)
6972 double selectivity, cardinality;
6986 cardinality = MAX (cardinality, tail_info->
cardinality);
6990 cardinality = MAX (cardinality, head_info->
cardinality);
6994 if (cardinality != 0)
6996 cardinality = MAX (1.0, cardinality);
6999 term = &planner->
term[
i];
7004 if (cardinality != 0)
7006 cardinality = MAX (1.0, cardinality);
7012 selectivity = MAX (1.0 / cardinality, selectivity);
7015 cardinality *= selectivity;
7016 cardinality = MAX (1.0, cardinality);
7023 cardinality = MAX (cardinality, tail_info->
cardinality);
7027 cardinality = MAX (cardinality, head_info->
cardinality);
7036 qo_alloc_info (planner, visited_nodes, visited_terms, &eqclasses, cardinality);
7045 int idx_join_plan_n = 0;
7051 kept +=
qo_examine_follow (new_info, follow_term, head_info, &sarged_terms, &pinned_subqueries);
7066 qo_examine_idx_join (new_info, join_type, head_info, tail_info, &afj_terms, &sarged_terms,
7067 &pinned_subqueries);
7068 kept += idx_join_plan_n;
7078 qo_examine_nl_join (new_info, join_type, head_info, tail_info, &nl_join_terms, &duj_terms, &afj_terms,
7079 &sarged_terms, &pinned_subqueries, idx_join_plan_n, &sm_join_terms);
7086 qo_examine_merge_join (new_info, join_type, head_info, tail_info, &sm_join_terms, &duj_terms, &afj_terms,
7087 &sarged_terms, &pinned_subqueries);
7148 visited_nodes, visited_rel_nodes, visited_terms, nested_path_nodes,
7149 remaining_nodes, remaining_terms, remaining_subqueries, num_path_inner);
7170 bitset_union (remaining_subqueries, &pinned_subqueries);
7196 double total_cost, objects, result_size, pages;
7213 objects = (plan->
info)->cardinality;
7214 result_size = objects * (double) (plan->
info)->projected_size;
7216 pages = MAX (1.0, pages);
7219 total_cost += pages;
7236 objects = (subplan->
info)->cardinality;
7237 result_size = objects * (double) (subplan->
info)->projected_size;
7239 pages = MAX (1.0, pages);
7245 total_cost += pages;
7250 total_cost += pages * 2.0;
7280 BITSET * remaining_subqueries,
int num_path_inner,
int *node_idxp)
7284 QO_INFO *head_info, *best_info;
7285 QO_NODE *head_node, *tail_node;
7287 double best_cost, prev_best_cost;
7294 prev_best_cost = -1.0;
7363 (void)
planner_visit_node (planner, partition, hint, head_node, tail_node, visited_nodes,
7364 visited_rel_nodes, visited_terms, nested_path_nodes, remaining_nodes,
7365 remaining_terms, remaining_subqueries, num_path_inner);
7389 visited_nodes, visited_rel_nodes, visited_terms, nested_path_nodes,
7390 remaining_nodes, remaining_terms, remaining_subqueries, num_path_inner);
7396 if (best_info ==
NULL)
7403 if (best_plan ==
NULL)
7418 if (prev_best_cost == -1.0
7419 || best_cost < prev_best_cost)
7422 prev_best_cost = best_cost;
7460 if (planner ==
NULL)
7497 int i, t, last_t, j,
n, seg, rangelist_term_idx;
7498 bool found_rangelist;
7526 index_entryp = (ni_entryp)->
head;
7527 if (index_entryp->
force < 0)
7533 found_rangelist =
false;
7534 rangelist_term_idx = -1;
7535 for (i = 0; i < index_entryp->
nsegs; i++)
7559 if (found_rangelist ==
true &&
QO_TERM_IDX (termp) != rangelist_term_idx)
7567 found_rangelist =
true;
7601 if (found_rangelist ==
true)
7607 found_rangelist =
true;
7633 if (found_rangelist ==
true)
7661 &empty_terms, &empty_terms, afj_terms, &remaining_terms,
7662 pinned_subqueries, &empty_terms));
7700 bool plan_created =
false;
7707 plan_created =
true;
7742 int i, t,
n, normal_index_plan_n = 0;
7746 int start_column = 0;
7752 index_entryp = (ni_entryp)->
head;
7753 if (index_entryp->
force < 0)
7773 for (i = start_column; i < nsegs - 1; i++)
7802 normal_index_plan_n++;
7824 normal_index_plan_n++;
7834 return normal_index_plan_n;
7855 index_entryp = (ni_entryp)->
head;
7856 if (index_entryp->
force < 0)
7931 for (i = 0; i < env->
nterms; i++)
7992 BITSET nodes, subqueries, remaining_subqueries;
7993 int join_info_bytes;
7994 int normal_index_plan_n,
n;
7995 int start_column = 0;
7997 bool special_index_scan =
false;
8028 join_info_bytes = planner->
M *
sizeof (
QO_INFO *);
8029 if (join_info_bytes > 0)
8045 memset (planner->
join_info, 0, join_info_bytes);
8056 size_t size =
sizeof (
QO_INFO *) * planner->
N;
8067 for (i = 0; i < (signed) planner->
N; ++i)
8069 node = &planner->
node[
i];
8101 for (i = 0; i < (signed) planner->
N; i++)
8103 node = &planner->
node[
i];
8112 if (special_index_scan)
8131 normal_index_plan_n = 0;
8133 if (node_index !=
NULL)
8137 for (j = 0; j <
QO_NI_N (node_index); j++)
8140 index_entry = (ni_entry)->
head;
8141 if (index_entry->
force < 0)
8155 for (nsegs = start_column; nsegs < index_entry->
nsegs; nsegs++)
8179 normal_index_plan_n +=
n;
8195 normal_index_plan_n +=
n;
8202 normal_index_plan_n +=
n;
8253 if (normal_index_plan_n > 0)
8283 size_t size =
sizeof (
QO_INFO *) * planner->
P;
8293 for (i = 0; i < (signed) planner->
P; i++)
8300 for (i = 0; i < (signed) planner->
P; ++i)
8308 for (j = 0; j <
i; ++j)
8383 if (plan->
plan_un.
scan.index->head->use_descending)
8454 int i, nodes_cnt, node_idx;
8462 BITSET visited_rel_nodes;
8465 BITSET nested_path_nodes;
8485 for (i = 0; i < (signed) planner->
T; i++)
8487 term = &planner->
term[
i];
8516 planner->
join_unit = (nodes_cnt <= 25) ? MIN (4, nodes_cnt) : (nodes_cnt <= 37) ? 3 : 2;
8519 if (num_path_inner || (hint & PT_HINT_ORDERED))
8530 bool found_f_edge, found_other_edge;
8649 found_f_edge = found_other_edge =
false;
8650 for (t =
bitset_iterate (&remaining_terms, &bt); t != -1 && !found_other_edge;
8674 found_f_edge =
true;
8681 found_other_edge =
true;
8685 if (found_f_edge && !found_other_edge)
8716 &visited_nodes, &visited_rel_nodes, &visited_terms, &first_nodes, &nested_path_nodes,
8717 &remaining_nodes, &remaining_terms, remaining_subqueries, num_path_inner,
8718 (planner->
join_unit < nodes_cnt) ? &node_idx
8766 visited_info = planner->
node_info[node_idx];
8774 if (visited_info ==
NULL)
8860 for (i = 0; i < (signed) planner->
N; i++)
8884 for (i = 1; i < (signed) planner->
P; ++i)
8887 for (j = 0; j <
i; ++j)
8940 for (i = 0; i < (signed) planner->
P; ++i)
8949 cardinality = (plan->
info)->cardinality;
8955 for (++partition, i = 1; i < (signed) planner->
P; ++partition, ++i)
8962 cardinality *= (next_plan->
info)->cardinality;
8966 for (t = planner->
E; t < (
signed) planner->
T; ++t)
8987 plan =
qo_cp_new (planner->
cp_info[i], plan, next_plan, &sarged_terms, &subqueries);
9000 for (i = planner->
E; i < (
signed) planner->
T; ++i)
9021 else if (plan !=
NULL)
9046 double lhs_selectivity, rhs_selectivity, selectivity, total_selectivity;
9053 total_selectivity = 0.0;
9056 for (node = pt_expr; node; node = node->
or_next)
9169 total_selectivity = MAX (total_selectivity, 0.0);
9170 total_selectivity = MIN (total_selectivity, 1.0);
9173 return total_selectivity;
9194 result = lhs_sel + rhs_sel - (lhs_sel * rhs_sel);
9216 result = lhs_sel * rhs_sel;
9247 PT_NODE *lhs, *rhs, *multi_attr;
9248 PRED_CLASS pc_lhs, pc_rhs;
9249 int lhs_icard, rhs_icard, icard;
9274 icard = MAX (lhs_icard, rhs_icard);
9277 selectivity = (1.0 / icard);
9297 selectivity = (1.0 / lhs_icard);
9329 selectivity = (1.0 / rhs_icard);
9352 for ( ; multi_attr; multi_attr = multi_attr->
next)
9373 selectivity = (1.0 / rhs_icard);
9400 for ( ; multi_attr; multi_attr = multi_attr->
next)
9421 selectivity = (1.0 / lhs_icard);
9433 for ( ; multi_attr; multi_attr = multi_attr->
next)
9455 for ( ; multi_attr; multi_attr = multi_attr->
next)
9475 icard = MAX (lhs_icard, rhs_icard);
9478 selectivity = (1.0 / icard);
9539 PRED_CLASS pc1, pc2;
9540 double total_selectivity, selectivity;
9541 int lhs_icard = 0, rhs_icard = 0, icard = 0;
9554 for ( ; lhs; lhs = lhs->
next)
9587 total_selectivity = 0.0;
9617 icard = MAX (lhs_icard, rhs_icard);
9620 selectivity = (1.0 / icard);
9632 selectivity = (1.0 / lhs_icard);
9647 selectivity = MAX (selectivity, 0.0);
9648 selectivity = MIN (selectivity, 1.0);
9651 total_selectivity = MAX (total_selectivity, 0.0);
9652 total_selectivity = MIN (total_selectivity, 1.0);
9655 return total_selectivity;
9669 PRED_CLASS pc_lhs, pc_rhs;
9670 double list_card = 0, icard;
9672 double equal_selectivity, in_selectivity, selectivity;
9684 equal_selectivity = 1;
9685 for ( ; lhs; lhs = lhs->
next)
9691 selectivity = (1.0 / icard);
9697 equal_selectivity *= selectivity;
9707 equal_selectivity = (1.0 / icard);
9740 in_selectivity = list_card * equal_selectivity;
9741 return in_selectivity > 0.5 ? 0.5 : in_selectivity;
9790 for ( ; func_arg; func_arg = func_arg->
next)
9886 && (plan->
plan_un.
scan.index->head->all_unique_index_columns_are_equi_terms))
9916 bool term_notnull =
false;
9929 index_class = index_entryp->
class_;
9935 for (t = 0; t < env->
nterms && !term_notnull; t++)
9971 term_notnull =
true;
9978 return term_notnull;
9988 bool attr_notnull =
false;
9998 int old_bail_out, key_term_status;
10006 index_class = index_entryp->
class_;
10026 for (i = 0; i < index_entryp->
col_num; i++)
10033 if (i >= index_entryp->
col_num)
10040 #if !defined(NDEBUG) 10056 attr_notnull =
true;
10060 attr_notnull =
false;
10074 if (attr_notnull !=
true)
10081 env_seg[0] = (
void *) env;
10082 env_seg[1] = (
void *) segp;
10093 if (key_term_status == 1)
10095 BITSET expr_segments, key_segment;
10106 for (i = 0; i < env->
nterms; i++)
10112 if (pt_expr ==
NULL)
10131 attr_notnull =
true;
10139 return attr_notnull;
10151 bool key_notnull =
false;
10162 index_entryp = ni_entryp->
head;
10163 index_class = index_entryp->
class_;
10176 pos =
QO_ENV_PT_TREE (env)->info.query.order_by->info.sort_spec.pos_descr.pos_no;
10179 while (pos > 1 && node)
10200 assert (key_notnull ==
false);
10238 BITSET expr_segments, key_segment;
10241 void **env_seg = (
void **) arg;
10243 env = (
QO_ENV *) env_seg[0];
10294 int a_range, b_range;
10295 int a_filter, b_filter;
10307 a_ent = (a_ni)->
head;
10313 if (a_range > 0 && !(a->
plan_un.
scan.index_equi))
10323 b_ent = (b_ni)->
head;
10329 if (b_range > 0 && !(b->
plan_un.
scan.index_equi))
10345 if (a_filter > b_filter)
10349 else if (a_filter < b_filter)
10355 if (a_cum && b_cum)
10397 if (a_range > b_range)
10401 else if (a_range < b_range)
10406 assert (a_range == b_range);
10409 if (a_filter > b_filter)
10413 else if (a_filter < b_filter)
10444 if (a_ent ==
NULL || b_ent ==
NULL)
10501 if (a_ent ==
NULL || b_ent ==
NULL)
10548 bool orderby_skip =
false;
10550 PT_NODE *tree, *trav, *order_by;
10553 tree = order_by =
NULL;
10599 return orderby_skip;
10627 bool key_notnull =
false;
10637 index_entryp = ni_entryp->
head;
10638 index_class = index_entryp->
class_;
10652 groupby_expr =
QO_ENV_PT_TREE (env)->info.query.q.select.group_by->info.sort_spec.expr;
10654 assert (key_notnull ==
false);
10687 bool groupby_skip =
false;
10689 PT_NODE *tree, *trav, *group_by;
10692 tree = group_by =
NULL;
10723 for (trav = list; trav; trav = trav->
next)
10733 for (trav = list; trav; trav = trav->
next)
10739 return groupby_skip;
10759 int nterms, equi_nterms, seg_idx,
i, j;
10766 bool is_const_eq_term;
10770 *is_index_w_prefix =
false;
10838 index_entryp = (ni_entryp)->
head;
10843 equi_nterms = plan->
plan_un.
scan.index_equi ? nterms : nterms - 1;
10849 assert (equi_nterms >= 0);
10863 assert (equi_nterms >= 0);
10864 assert (equi_nterms <= index_entryp->nsegs);
10866 if (equi_nterms >= index_entryp->
nsegs)
10877 key_type = index_entryp->
key_type;
10878 if (key_type ==
NULL)
10898 for (j = 0; j < equi_nterms && col_type; j++)
10900 col_type = col_type->next;
10905 col_type = key_type;
10909 assert (equi_nterms <= 1);
10912 if (equi_nterms > 0)
10918 assert (col_type !=
NULL || equi_nterms > 0);
10921 for (i = equi_nterms; i < index_entryp->
nsegs; i++)
10955 col_type = col_type->
next;
10960 is_const_eq_term =
false;
10967 is_const_eq_term =
true;
10970 if (is_const_eq_term)
10980 if (pos_descr.
pos_no > 0)
10983 for (j = 1; j < pos_descr.
pos_no && col; j++)
10999 if (group_by !=
NULL)
11005 if (pos_descr.
pos_no > 0)
11008 for (col = group_by, j = 1; j < pos_descr.
pos_no && col; j++)
11080 PT_NODE *order_by, *statement;
11082 bool is_prefix =
false, is_orderby_skip =
false;
11099 is_orderby_skip =
false;
11104 if (!is_orderby_skip)
11116 return is_orderby_skip;
11181 bool natural_desc_index =
false;
11182 json_t *scan, *range, *filter;
11183 const char *scan_string =
"";
11184 const char *class_name;
11187 scan = json_object ();
11190 if (class_name ==
NULL)
11192 class_name =
"unknown";
11195 json_object_set_new (scan,
"table", json_string (class_name));
11200 scan_string =
"TABLE SCAN";
11207 scan_string =
"INDEX SCAN";
11208 json_object_set_new (scan,
"index", json_string (plan->
plan_un.
scan.index->head->constraints->name));
11210 env = (plan->
info)->env;
11211 range = json_array ();
11218 json_object_set_new (scan,
"key range", range);
11222 filter = json_array ();
11228 json_object_set_new (scan,
"key filter", filter);
11233 json_object_set_new (scan,
"covered", json_true ());
11238 json_object_set_new (scan,
"desc_index", json_true ());
11239 natural_desc_index =
true;
11244 json_object_set_new (scan,
"desc_index forced", json_true ());
11249 json_object_set_new (scan,
"loose", json_true ());
11255 return json_pack (
"{s:o}", scan_string, scan);
11266 json_t *sort, *subplan =
NULL;
11272 type =
"SORT (temp)";
11276 type =
"SORT (group by)";
11280 type =
"SORT (order by)";
11284 type =
"SORT (distinct)";
11288 type =
"SORT (limit)";
11297 sort = json_object ();
11302 json_object_set_new (sort, type, subplan);
11306 json_object_set_new (sort, type, json_string (
""));
11320 json_t *join, *outer, *inner;
11321 const char *type, *method =
"";
11328 method =
"NESTED LOOPS";
11332 method =
"MERGE JOIN";
11341 type =
"inner join";
11347 type =
"inner join";
11351 type =
"cross join";
11356 type =
"left outer join";
11359 type =
"right outer join";
11362 type =
"full outer join";
11376 sprintf (buf,
"%s (%s)", method, type);
11378 join = json_pack (
"{s:[o,o]}", buf, outer, inner);
11391 json_t *
head, *follow;
11395 follow = json_object ();
11397 json_object_set_new (follow,
"head", head);
11399 return json_pack (
"{s:o}",
"FOLLOW", follow);
11410 json_t *json =
NULL;
11449 unsigned int save_custom;
11464 json_object_set_new (json,
"skip order by", json_true ());
11472 json_object_set_new (json,
"group by nosort", json_true ());
11479 json_object_set_new (json,
"rewritten query", json_string (
parser_print_tree (parser, select)));
11502 bool natural_desc_index =
false;
11503 const char *class_name;
11507 fprintf (fp,
"%*c", indent,
' ');
11510 if (class_name ==
NULL)
11512 class_name =
"unknown";
11518 fprintf (fp,
"TABLE SCAN (%s)", class_name);
11525 fprintf (fp,
"INDEX SCAN (%s.%s)", class_name, plan->
plan_un.
scan.index->head->constraints->name);
11527 env = (plan->
info)->env;
11528 fprintf (fp,
" (");
11545 fprintf (fp,
", covered: true");
11550 fprintf (fp,
", desc_index: true");
11551 natural_desc_index =
true;
11556 fprintf (fp,
", desc_index forced: true");
11561 fprintf (fp,
", loose: true");
11568 fprintf (fp,
"\n");
11588 type =
"SORT (temp)";
11592 type =
"SORT (group by)";
11596 type =
"SORT (order by)";
11600 type =
"SORT (distinct)";
11604 type =
"SORT (limit)";
11613 fprintf (fp,
"%*c%s\n", indent,
' ', type);
11631 const char *type, *method =
"";
11639 method =
"NESTED LOOPS";
11643 method =
"MERGE JOIN";
11652 type =
"inner join";
11658 type =
"inner join";
11662 type =
"cross join";
11667 type =
"left outer join";
11670 type =
"right outer join";
11673 type =
"full outer join";
11684 fprintf (fp,
"%*c%s (%s)\n", indent,
' ', method, type);
11754 unsigned int save_custom;
11778 fprintf (fp,
"%*cskip order by: true\n", indent,
' ');
11786 fprintf (fp,
"%*cgroup by nosort: true\n", indent,
' ');
11797 fprintf (fp,
"\n%*crewritten query: %s\n", indent,
' ', sql);
static void qo_plan_print_text(FILE *fp, QO_PLAN *plan, int indent)
bool qo_is_iscan(QO_PLAN *plan)
QO_CLASS_INFO_ENTRY * class_
bool qo_check_iscan_for_multi_range_opt(QO_PLAN *plan)
static void qo_follow_info(QO_PLAN *, FILE *, int)
#define QO_TERM_SUBQUERIES(t)
QO_PARTITION * partitions
QFILE_TUPLE_VALUE_POSITION pos_descr
static QO_INFO * qo_alloc_info(QO_PLANNER *, BITSET *, BITSET *, BITSET *, double)
static QO_PLAN * qo_worst_new(QO_ENV *)
static json_t * qo_plan_scan_print_json(QO_PLAN *plan)
static void qo_sort_walk(QO_PLAN *, void(*)(QO_PLAN *, void *), void *, void(*)(QO_PLAN *, void *), void *)
int(* QO_WALK_FUNCTION)(QO_PLAN *, void *)
#define QO_TERM_MULTI_COLL_PRED
struct qo_plan::@100::@103 sort
#define LANG_SYS_COLLATION
static json_t * qo_plan_print_json(QO_PLAN *plan)
static int qo_plans_allocated
int bitset_is_equivalent(const BITSET *r, const BITSET *s)
static QO_PLAN_VTBL qo_worst_plan_vtbl
#define PT_EXPR_INFO_FULL_RANGE
struct qo_summary * qo_summary
static PRED_CLASS qo_classify(PT_NODE *attr)
#define PT_ERRORm(parser, node, setNo, msgNo)
static QO_PLAN_VTBL qo_follow_plan_vtbl
void qo_get_optimization_param(void *, QO_PARAM,...)
void qo_env_free(QO_ENV *env)
#define qo_plan_add_ref(p)
#define QO_ASSERT(env, cond)
static void qo_worst_cost(QO_PLAN *)
double qo_expr_selectivity(QO_ENV *env, PT_NODE *pt_expr)
#define QO_ENV_LIMIT_VALUE(env)
#define qo_plan_del_ref(p)
SM_PREDICATE_INFO * filter_predicate
static void qo_plan_scan_print_text(FILE *fp, QO_PLAN *plan, int indent)
static QO_PLAN * qo_search_partition(QO_PLANNER *, QO_PARTITION *, QO_EQCLASS *, BITSET *)
#define QO_TERM_INDEX_SEG(t, i)
#define QO_NI_ENTRY(ni, n)
#define QO_TERM_IS_FLAGED(t, f)
void pt_to_pos_descr_groupby(PARSER_CONTEXT *parser, QFILE_TUPLE_VALUE_POSITION *pos_p, PT_NODE *node, PT_NODE *root)
#define DETAILED_DUMP(level)
bool qo_is_iscan_from_orderby(QO_PLAN *plan)
static double qo_and_selectivity(QO_ENV *env, double lhs_sel, double rhs_sel)
int bitset_intersects(const BITSET *r, const BITSET *s)
void qo_expr_segs(QO_ENV *env, PT_NODE *pt_expr, BITSET *result)
static int qo_examine_correlated_index(QO_INFO *, JOIN_TYPE, QO_INFO *, QO_INFO *, BITSET *, BITSET *, BITSET *)
static void qo_uninit_planvec(QO_PLANVEC *)
void qo_eqclass_fprint_wrt(QO_EQCLASS *eqclass, BITSET *nodeset, FILE *f)
analytic_list_node * head
static void qo_scan_info(QO_PLAN *, FILE *, int)
#define DEFAULT_EQUIJOIN_SELECTIVITY
int bitset_iterate(const BITSET *s, BITSET_ITERATOR *si)
void qo_print_stats(FILE *f)
static void qo_detach_info(QO_INFO *)
#define QO_ENV_PARSER(env)
#define IS_OUTER_JOIN_TYPE(t)
#define QO_NODE_IS_CLASS_PARTITIONED(node)
#define MSGCAT_SEMANTIC_OUT_OF_MEMORY
static void qo_plan_print_sarged_terms(QO_PLAN *, FILE *, int)
static int qo_generate_join_index_scan(QO_INFO *, JOIN_TYPE, QO_PLAN *, QO_INFO *, QO_NODE *, QO_NODE_INDEX_ENTRY *, BITSET *, BITSET *, BITSET *, BITSET *)
bool multi_range_opt_candidate
struct tp_domain * setdomain
static void qo_plan_del_ref_func(QO_PLAN *plan, void *ignore)
static bool qo_index_has_bit_attr(QO_INDEX_ENTRY *index_entryp)
static const char * qo_term_string(QO_TERM *)
#define QO_ON_COND_TERM(term)
QUERY_TRACE_FORMAT format
static QO_PLANNER * qo_alloc_planner(QO_ENV *)
static double qo_or_selectivity(QO_ENV *env, double lhs_sel, double rhs_sel)
bool qo_is_interesting_order_scan(QO_PLAN *plan)
#define VALID_INNER(plan)
static void qo_plan_print_outer_join_terms(QO_PLAN *, FILE *, int)
#define DEFAULT_EQUAL_SELECTIVITY
static void qo_plan_free(QO_PLAN *)
#define QO_JOIN_INFO_SIZE(_partition)
static int qo_validate_index_for_groupby(QO_ENV *env, QO_NODE_INDEX_ENTRY *ni_entryp)
static QO_INFO * qo_search_partition_join(QO_PLANNER *, QO_PARTITION *, BITSET *)
SM_ATTRIBUTE * attributes
static bool qo_plan_is_orderby_skip_candidate(QO_PLAN *plan)
analytic_eval_type * next
static QO_PLAN * qo_plan_finalize(QO_PLAN *)
int bitset_is_empty(const BITSET *s)
static QO_PLAN * qo_scan_new(QO_INFO *, QO_NODE *, QO_SCANMETHOD)
static void qo_plan_add_to_free_list(QO_PLAN *, void *ignore)
#define QO_IS_LIMIT_NODE(env, node)
#define assert_release(e)
static void qo_set_use_desc(QO_PLAN *plan)
union pt_plan_trace_info::@133 trace
#define QO_TERM_LOCATION(t)
static void qo_plan_walk(QO_PLAN *, void(*)(QO_PLAN *, void *), void *, void(*)(QO_PLAN *, void *), void *)
void bitset_difference(BITSET *dst, const BITSET *src)
void(* cost_fn)(QO_PLAN *)
#define QO_TERM_PT_EXPR(t)
static void qo_plan_compute_cost(QO_PLAN *)
PT_NODE * pt_get_end_path_node(PT_NODE *node)
static double qo_equal_selectivity(QO_ENV *env, PT_NODE *pt_expr)
#define SM_IS_CONSTRAINT_UNIQUE_FAMILY(c)
union pt_query_info::@124 q
static void qo_worst_info(QO_PLAN *, FILE *, int)
static void qo_follow_fprint(QO_PLAN *, FILE *, int)
void qo_term_fprint(QO_TERM *term, FILE *f)
SM_FUNCTION_INFO * func_index_info
unsigned int custom_print
#define QO_NODE_INFO_N(node)
static void qo_iscan_cost(QO_PLAN *)
#define QO_NODE_HINT(node)
#define QO_IS_EDGE_TERM(t)
SM_CLASS_CONSTRAINT * constraints
bool qo_is_seq_scan(QO_PLAN *plan)
#define QO_ENV_USE_SORT_LIMIT(env)
#define PT_NAME_INFO_IS_FLAGED(e, f)
struct qo_plan::@100::@104 join
static QO_PLAN_COMPARE_RESULT qo_index_covering_plans_cmp(QO_PLAN *, QO_PLAN *)
#define QO_NODE_INFO(node)
static void qo_plans_teardown(QO_ENV *env)
static void qo_plan_print_sort_spec(QO_PLAN *, FILE *, int)
bool qo_check_join_for_multi_range_opt(QO_PLAN *plan)
static void qo_follow_cost(QO_PLAN *)
#define QO_EQCLASS_IDX(e)
static QO_PLAN * qo_top_plan_new(QO_PLAN *)
#define SIMPLE_DUMP(level)
static QO_PLAN_COMPARE_RESULT qo_plan_cmp_prefer_covering_index(QO_PLAN *, QO_PLAN *)
#define DEFAULT_SELECTIVITY
const char * pt_get_name(PT_NODE *nam)
#define QO_NODE_REL_IDX(node)
#define QO_SEG_INDEX_TERMS(seg)
bool all_unique_index_columns_are_equi_terms
void qo_plan_lite_print(QO_PLAN *, FILE *, int)
QO_PLAN_VTBL * all_vtbls[]
static void qo_free_info(QO_INFO *)
#define QO_PARTITION_PLAN(p)
static void qo_plan_join_print_text(FILE *fp, QO_PLAN *plan, int indent)
#define QO_NODE_DEP_SET(node)
static double qo_all_some_in_selectivity(QO_ENV *env, PT_NODE *pt_expr)
void qo_plan_discard(QO_PLAN *plan)
static QO_PLAN * qo_seq_scan_new(QO_INFO *, QO_NODE *)
PT_PRINT_VALUE_FUNC print_db_value
#define QO_NODE_NCARD(node)
static int qo_examine_merge_join(QO_INFO *, JOIN_TYPE, QO_INFO *, QO_INFO *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *)
static QO_PLAN_VTBL qo_set_follow_plan_vtbl
static int qo_plans_deallocated
bool qo_is_iscan_from_groupby(QO_PLAN *plan)
const char * lang_get_collation_name(const int coll_id)
#define QO_PARTITION_M_OFFSET(p)
static void qo_generate_seq_scan(QO_INFO *, QO_NODE *)
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
static PT_NODE * qo_search_isnull_key_expr(PARSER_CONTEXT *parser, PT_NODE *tree, void *arg, int *continue_walk)
static int infos_deallocated
static QO_PLAN_COMPARE_RESULT qo_group_by_skip_plans_cmp(QO_PLAN *, QO_PLAN *)
void port_close_memstream(FILE *fp, char **ptr, size_t *sizeloc)
#define NONGROUPED_SCAN_COST
bool qo_is_index_loose_scan(QO_PLAN *plan)
static int qo_plans_demalloced
PT_MISC_TYPE derived_table_type
static void qo_compute_projected_segs(QO_PLANNER *, BITSET *, BITSET *, BITSET *)
static QO_PLAN_VTBL qo_index_scan_plan_vtbl
static int qo_has_is_not_null_term(QO_NODE *node)
static double log3(double)
static QO_PLAN_COMPARE_RESULT qo_order_by_skip_plans_cmp(QO_PLAN *, QO_PLAN *)
static void qo_join_walk(QO_PLAN *, void(*)(QO_PLAN *, void *), void *, void(*)(QO_PLAN *, void *), void *)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
int bitset_subset(const BITSET *r, const BITSET *s)
PT_FUNCTION_INFO function
static void qo_join_info(QO_PLAN *, FILE *, int)
#define QO_PLAN_CMP_CHECK_COST(a, b)
static void qo_plan_print_costs(QO_PLAN *, FILE *, int)
void qo_termset_fprint(QO_ENV *env, BITSET *terms, FILE *f)
QO_ATTR_CUM_STATS cum_stats
static void qo_scan_free(QO_PLAN *)
static bool qo_validate_index_term_notnull(QO_ENV *env, QO_INDEX_ENTRY *index_entryp)
static void planner_permutate(QO_PLANNER *, QO_PARTITION *, PT_HINT_ENUM, QO_NODE *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *, int, int *)
void bitset_print(const BITSET *s, FILE *fp)
void bitset_delset(BITSET *s)
void qo_top_plan_print_text(PARSER_CONTEXT *parser, xasl_node *xasl, PT_NODE *select, QO_PLAN *plan)
static PT_NODE * qo_plan_compute_iscan_sort_list(QO_PLAN *root, PT_NODE *group_by, bool *is_index_w_prefix)
static void sort_partitions(QO_PLANNER *)
void bitset_assign(BITSET *dst, const BITSET *src)
#define QO_NODE_ENV(node)
bool pt_sort_spec_cover_groupby(PARSER_CONTEXT *parser, PT_NODE *sort_list, PT_NODE *group_list, PT_NODE *tree)
int prm_get_integer_value(PARAM_ID prm_id)
static double qo_range_selectivity(QO_ENV *env, PT_NODE *pt_expr)
static double qo_between_selectivity(QO_ENV *env, PT_NODE *pt_expr)
#define QO_IS_PATH_TERM(t)
void bitset_union(BITSET *dst, const BITSET *src)
static bool qo_validate_index_attr_notnull(QO_ENV *env, QO_INDEX_ENTRY *index_entryp, PT_NODE *col)
static QO_PLAN * qo_plan_malloc(QO_ENV *)
#define ER_OUT_OF_VIRTUAL_MEMORY
static QO_PLAN_VTBL qo_nl_join_plan_vtbl
static int qo_unset_multi_range_optimization(QO_PLAN *plan, void *arg)
QO_SEGMENT * index_seg[2]
static int qo_check_plan_on_info(QO_INFO *, QO_PLAN *)
PT_NODE * flat_entity_list
static int qo_examine_follow(QO_INFO *, QO_TERM *, QO_INFO *, BITSET *, BITSET *)
void qo_plans_stats(FILE *f)
bool qo_is_index_mro_scan(QO_PLAN *plan)
PT_MISC_TYPE all_distinct
bool pt_has_analytic(PARSER_CONTEXT *parser, PT_NODE *node)
static QO_PLAN_COMPARE_RESULT qo_cmp_planvec(QO_PLANVEC *, QO_PLAN *)
int qo_plan_get_cost_fn(const char *plan_name)
static void qo_plan_print_projected_segs(QO_PLAN *, FILE *, int)
int intl_identifier_casecmp(const char *str1, const char *str2)
#define BTREE_STATS_PKEYS_NUM
struct qo_plan::@100::@105 follow
static QO_PLAN * qo_sort_new(QO_PLAN *, QO_EQCLASS *, SORT_TYPE)
#define QO_NODE_IS_CLASS_HIERARCHY(node)
static double qo_comp_selectivity(QO_ENV *env, PT_NODE *pt_expr)
static QO_PLAN_COMPARE_RESULT qo_multi_range_opt_plans_cmp(QO_PLAN *, QO_PLAN *)
#define TP_DOMAIN_COLLATION(dom)
static QO_PLAN * qo_find_best_nljoin_inner_plan_on_info(QO_PLAN *, QO_INFO *, JOIN_TYPE, int)
#define DEFAULT_RANGE_SELECTIVITY
bool qo_is_all_unique_index_columns_are_equi_terms(QO_PLAN *plan)
int qo_seg_width(QO_SEGMENT *seg)
#define QO_NODE_SUBQUERIES(node)
void qo_top_plan_print_json(PARSER_CONTEXT *parser, xasl_node *xasl, PT_NODE *select, QO_PLAN *plan)
#define PT_NAME_INFO_CONSTANT
union qo_plan::@100 plan_un
BITSET multi_col_range_segs
static void qo_plan_fprint(QO_PLAN *, FILE *, int, const char *)
#define TP_DOMAIN_TYPE(dom)
static void cleanup(int signo)
bool qo_is_index_covering_scan(QO_PLAN *plan)
static QO_PLAN_VTBL qo_seq_scan_plan_vtbl
bool use_iscan_descending
static bool qo_is_sort_limit(QO_PLAN *plan)
#define DEFAULT_COMP_SELECTIVITY
static void qo_sort_fprint(QO_PLAN *, FILE *, int)
static json_t * qo_plan_join_print_json(QO_PLAN *plan)
#define QO_NODE_SARGS(node)
#define DEFAULT_IN_SELECTIVITY
char * parser_print_tree_list(PARSER_CONTEXT *parser, const PT_NODE *node)
void bitset_intersect(BITSET *dst, const BITSET *src)
static QO_PLAN * qo_index_scan_new(QO_INFO *, QO_NODE *, QO_NODE_INDEX_ENTRY *, QO_SCANMETHOD, BITSET *, BITSET *)
#define QO_SEG_FUNC_INDEX(seg)
static void qo_dump_info(QO_INFO *, FILE *)
#define QO_SEG_PT_NODE(seg)
static void qo_plan_compute_subquery_cost(PT_NODE *, double *, double *)
static double qo_not_selectivity(QO_ENV *env, double sel)
QO_PLAN_ULTI_RANGE_OPT_USE multi_range_opt_use
static void qo_plan_sort_print_text(FILE *fp, QO_PLAN *plan, int indent)
#define QO_TERM_MERGEABLE_EDGE
bool qo_plan_multi_range_opt(QO_PLAN *plan)
static json_t * qo_plan_follow_print_json(QO_PLAN *plan)
static void qo_scan_fprint(QO_PLAN *, FILE *, int)
bool qo_is_index_iss_scan(QO_PLAN *plan)
static int qo_set_orderby_skip(QO_PLAN *plan, void *arg)
#define QO_TERM_CAN_USE_INDEX(t)
static QO_PLAN_COMPARE_RESULT qo_plan_cmp(QO_PLAN *, QO_PLAN *)
static QO_PLAN * qo_combine_partitions(QO_PLANNER *, BITSET *)
void qo_seg_fprint(QO_SEGMENT *seg, FILE *f)
int pt_is_between_range_op(PT_OP_TYPE op)
DB_BIGINT db_get_bigint(const DB_VALUE *value)
static QO_PLAN * qo_join_new(QO_INFO *, JOIN_TYPE, QO_JOINMETHOD, QO_PLAN *, QO_PLAN *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *)
static QO_PLAN * qo_follow_new(QO_INFO *, QO_PLAN *, QO_TERM *, BITSET *, BITSET *)
static int qo_examine_idx_join(QO_INFO *, JOIN_TYPE, QO_INFO *, QO_INFO *, BITSET *, BITSET *, BITSET *)
static int qo_accumulating_plans
#define QO_NODE_SELECTIVITY(node)
#define DEFAULT_EXISTS_SELECTIVITY
int bitset_next_member(BITSET_ITERATOR *si)
static void qo_zero_cost(QO_PLAN *)
#define DEFAULT_BETWEEN_SELECTIVITY
static QO_PLAN * qo_find_best_plan_on_planvec(QO_PLANVEC *, double)
static void qo_clean_planner(QO_PLANNER *)
static void qo_sort_info(QO_PLAN *, FILE *, int)
static void qo_worst_fprint(QO_PLAN *, FILE *, int)
#define QO_ENV_SORT_LIMIT_NODES(env)
PT_NODE * parser_append_node(PT_NODE *node, PT_NODE *list)
void bitset_remove(BITSET *dst, int x)
#define QO_NODE_EQCLASSES(node)
PT_NODE * parser_new_node(PARSER_CONTEXT *parser, PT_NODE_TYPE node_type)
static int qo_generate_sort_limit_plan(QO_ENV *, QO_INFO *, QO_PLAN *)
#define QO_ENTRY_MULTI_COL(entry)
void parser_free_node(const PARSER_CONTEXT *parser, PT_NODE *node)
static QO_PLAN * qo_plan_free_list
static void qo_dump_planvec(QO_PLANVEC *, FILE *, int)
static void qo_plans_init(QO_ENV *env)
static int qo_validate_indexes_for_orderby(QO_PLAN *plan, void *arg)
static void qo_init_planvec(QO_PLANVEC *)
#define QO_NODE_TCARD(node)
#define TP_TYPE_HAS_COLLATION(typeid)
PT_SORT_SPEC_INFO sort_spec
bool qo_is_prefix_index(QO_INDEX_ENTRY *ent)
struct qo_plan::@100::@102 scan
#define QO_TERM_SELECTIVITY(t)
static int qo_generate_loose_index_scan(QO_INFO *, QO_NODE *, QO_NODE_INDEX_ENTRY *)
void parser_free_tree(PARSER_CONTEXT *parser, PT_NODE *tree)
static QO_PLAN * qo_search_planner(QO_PLANNER *)
PT_NODE * iscan_sort_list
static void qo_generic_walk(QO_PLAN *, void(*)(QO_PLAN *, void *), void *, void(*)(QO_PLAN *, void *), void *)
#define QO_TERM_NON_IDX_SARG_COLL
float prm_get_float_value(PARAM_ID prm_id)
const char * fcode_get_lowercase_name(FUNC_TYPE ftype)
static json_t * qo_plan_sort_print_json(QO_PLAN *plan)
#define MSGCAT_SET_PARSER_SEMANTIC
int db_make_error(DB_VALUE *value, const int errcode)
#define QO_NODE_LOCATION(node)
static QO_PLAN_VTBL qo_merge_join_plan_vtbl
#define QO_TERM_RANGELIST
int qo_find_subplan_using_multi_range_opt(QO_PLAN *plan, QO_PLAN **result, int *join_idx)
static QO_PLAN_COMPARE_RESULT qo_plan_iscan_terms_cmp(QO_PLAN *a, QO_PLAN *b)
#define free_and_init(ptr)
ACCESS_SPEC_TYPE * spec_list
#define PT_IS_EXPR_NODE(n)
static int qo_compute_projected_size(QO_PLANNER *, BITSET *)
#define BITSET_MEMBER(s, x)
QO_PLAN * qo_planner_search(QO_ENV *env)
QO_ATTR_CUM_STATS cum_stats
static QO_PLAN_VTBL qo_sort_plan_vtbl
PT_NODE * pt_point(PARSER_CONTEXT *parser, const PT_NODE *in_tree)
static bool qo_check_groupby_skip_descending(QO_PLAN *plan, PT_NODE *list)
int intl_mbs_ncasecmp(const char *mbs1, const char *mbs2, size_t n)
struct qo_plan::@100::@101 free
bool qo_has_sort_limit_subplan(QO_PLAN *plan)
static bool qo_check_new_best_plan_on_info(QO_INFO *, QO_PLAN *)
#define INDENTED_TITLE_FMT
bool prm_get_bool_value(PARAM_ID prm_id)
#define QO_TERM_EQCLASS(t)
static QO_PLAN * qo_cp_new(QO_INFO *, QO_PLAN *, QO_PLAN *, BITSET *, BITSET *)
const char * qo_plan_set_cost_fn(const char *plan_name, int fn)
SM_ATTRIBUTE ** attributes
#define SORT_SPEC_FMT(spec)
static QO_PLAN * qo_find_best_plan_on_info(QO_INFO *, QO_EQCLASS *, double)
int pt_is_single_tuple(PARSER_CONTEXT *parser, PT_NODE *select_node)
static void qo_dump_planner_info(QO_PLANNER *, QO_PARTITION *, FILE *)
bool pt_sort_spec_cover(PT_NODE *cur_list, PT_NODE *new_list)
#define QO_NODE_NAME(node)
PARSER_VARCHAR * pt_print_node_value(PARSER_CONTEXT *parser, const PT_NODE *val)
static bool qo_check_orderby_skip_descending(QO_PLAN *plan)
static void planner_visit_node(QO_PLANNER *, QO_PARTITION *, PT_HINT_ENUM, QO_NODE *, QO_NODE *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *, int)
static void qo_plan_print_analytic_eval(QO_PLAN *, FILE *, int)
void qo_plan_dump(QO_PLAN *plan, FILE *output)
#define QO_ENV_NODE(env, n)
static void qo_plan_print_sort_spec_helper(PT_NODE *, bool, FILE *, int)
static int qo_validate_index_for_orderby(QO_ENV *env, QO_NODE_INDEX_ENTRY *ni_entryp)
#define QO_ENV_TERM(env, n)
#define SM_IS_CONSTRAINT_REVERSE_INDEX_FAMILY(c)
char * parser_print_tree(PARSER_CONTEXT *parser, const PT_NODE *node)
#define DB_VALUE_TYPE(value)
#define QO_ENV_SEG(env, n)
#define MAX_NUM_PLAN_TRACE
#define ISCAN_OVERHEAD_FACTOR
static void qo_nljoin_cost(QO_PLAN *)
static int qo_generate_index_scan(QO_INFO *, QO_NODE *, QO_NODE_INDEX_ENTRY *, int)
static void qo_follow_walk(QO_PLAN *, void(*)(QO_PLAN *, void *), void *, void(*)(QO_PLAN *, void *), void *)
static QO_PLAN_COMPARE_RESULT qo_check_planvec(QO_PLANVEC *, QO_PLAN *)
#define QO_PARTITION_DEPENDENCIES(p)
PARSER_VARCHAR *(* PT_PRINT_VALUE_FUNC)(PARSER_CONTEXT *parser, const PT_NODE *val)
void bitset_init(BITSET *s, QO_ENV *env)
#define PT_SPEC_SPECIAL_INDEX_SCAN(spec_)
static QO_PLAN * qo_plan_order_by(QO_PLAN *, QO_EQCLASS *)
QO_NODE * lookup_node(PT_NODE *attr, QO_ENV *env, PT_NODE **entity)
#define PT_IS_SET_TYPE(n)
#define QO_NODE_IDX(node)
#define pt_is_function(n)
PT_PLAN_TRACE_INFO plan_trace[MAX_NUM_PLAN_TRACE]
static QO_PLAN_VTBL qo_idx_join_plan_vtbl
analytic_list_node * next
int bitset_cardinality(const BITSET *s)
static void qo_plan_print_subqueries(QO_PLAN *, FILE *, int)
void pt_to_pos_descr(PARSER_CONTEXT *parser, QFILE_TUPLE_VALUE_POSITION *pos_p, PT_NODE *node, PT_NODE *root, PT_NODE **referred_node)
bool qo_is_filter_index(QO_INDEX_ENTRY *ent)
#define QO_ENV_PT_TREE(env)
#define QO_NODE_ENTITY_SPEC(node)
static void qo_sscan_cost(QO_PLAN *)
#define PT_IS_EXPR_NODE_WITH_OPERATOR(n, op_type)
QO_SEGMENT * lookup_seg(QO_NODE *head, PT_NODE *name, QO_ENV *env)
#define QO_PARTITION_NODES(p)
int bitset_first_member(const BITSET *s)
#define qo_plan_release(p)
static double planner_nodeset_join_cost(QO_PLANNER *, BITSET *)
static int qo_index_cardinality(QO_ENV *env, PT_NODE *attr)
#define QO_NODE_INDEXES(node)
#define QO_NODE_OUTER_DEP_SET(node)
void qo_planner_free(QO_PLANNER *planner)
static int infos_allocated
#define QO_NODE_SEGS(node)
void bitset_add(BITSET *dst, int x)
int pt_length_of_list(const PT_NODE *list)
struct parser_node::@132 flag
static void qo_join_fprint(QO_PLAN *, FILE *, int)
#define QO_NODE_SORT_LIMIT_CANDIDATE(node)
struct json_t * json_plan
static int qo_next_tmpfile
cubxasl::analytic_eval_type * analytic_eval_list
void qo_node_fprint(QO_NODE *node, FILE *f)
PT_NODE * parser_walk_tree(PARSER_CONTEXT *parser, PT_NODE *node, PT_NODE_WALK_FUNCTION pre_function, void *pre_argument, PT_NODE_WALK_FUNCTION post_function, void *post_argument)
#define PT_EXPR_INFO_IS_FLAGED(e, f)
void(* default_cost)(QO_PLAN *)
void qo_set_cost(DB_OBJECT *target, DB_VALUE *result, DB_VALUE *plan, DB_VALUE *cost)
#define QO_PARTITION_EDGES(p)
static void qo_plan_follow_print_text(FILE *fp, QO_PLAN *plan, int indent)
static void qo_sort_cost(QO_PLAN *)
#define DEFAULT_NULL_SELECTIVITY
DB_CONST_C_CHAR db_get_string(const DB_VALUE *value)
#define QO_TERM_JOIN_TYPE(t)
static int qo_examine_nl_join(QO_INFO *, JOIN_TYPE, QO_INFO *, QO_INFO *, BITSET *, BITSET *, BITSET *, BITSET *, BITSET *, int, BITSET *)
static int qo_walk_plan_tree(QO_PLAN *plan, QO_WALK_FUNCTION f, void *arg)
static void qo_mjoin_cost(QO_PLAN *)
#define QO_EQCLASS_SEGS(e)
static void qo_info_nodes_init(QO_ENV *)
#define TP_DOMAIN_COLLATION_FLAG(dom)
static int qo_plans_malloced
FILE * port_open_memstream(char **ptr, size_t *sizeloc)
void qo_info_stats(FILE *f)
#define QO_INFO_INDEX(_M_offset, _bitset)
static void qo_join_free(QO_PLAN *)