29 #include "pars0opt.ic"
43 #define OPT_COMPARISON 2
45 #define OPT_NOT_COND 1
46 #define OPT_END_COND 2
47 #define OPT_TEST_COND 3
48 #define OPT_SCROLL_COND 4
62 }
else if (op ==
'>') {
64 }
else if (op ==
'=') {
66 }
else if (op == PARS_LE_TOKEN) {
67 return(PARS_GE_TOKEN);
68 }
else if (op == PARS_GE_TOKEN) {
69 return(PARS_LE_TOKEN);
85 opt_check_exp_determined_before(
97 ut_ad(exp && sel_node);
102 arg = func_node->
args;
105 if (!opt_check_exp_determined_before(arg, sel_node,
125 for (i = 0; i < nth_table; i++) {
129 if (sym_node->
table == table) {
144 opt_look_for_col_in_comparison_before(
166 || (search_cond->
func ==
'>')
167 || (search_cond->
func ==
'=')
168 || (search_cond->
func == PARS_GE_TOKEN)
169 || (search_cond->
func == PARS_LE_TOKEN)
170 || (search_cond->
func == PARS_LIKE_TOKEN_EXACT)
171 || (search_cond->
func == PARS_LIKE_TOKEN_PREFIX)
172 || (search_cond->
func == PARS_LIKE_TOKEN_SUFFIX)
173 || (search_cond->
func == PARS_LIKE_TOKEN_SUBSTR));
177 if ((cmp_type == OPT_EQUAL)
178 && (search_cond->
func !=
'=')
179 && (search_cond->
func != PARS_LIKE_TOKEN_EXACT)
180 && (search_cond->
func != PARS_LIKE_TOKEN_PREFIX)) {
184 }
else if ((cmp_type == OPT_COMPARISON)
185 && (search_cond->
func !=
'<')
186 && (search_cond->
func !=
'>')
187 && (search_cond->
func != PARS_GE_TOKEN)
188 && (search_cond->
func != PARS_LE_TOKEN)
189 && (search_cond->
func != PARS_LIKE_TOKEN_PREFIX)
190 && (search_cond->
func != PARS_LIKE_TOKEN_SUFFIX)) {
195 arg = search_cond->
args;
202 && (sym_node->
col_no == col_no)) {
211 if (opt_check_exp_determined_before(exp, sel_node,
213 *op = search_cond->
func;
220 exp = search_cond->
args;
228 && (sym_node->
col_no == col_no)) {
230 if (opt_check_exp_determined_before(exp, sel_node,
232 *op = opt_invert_cmp_op(search_cond->
func);
250 opt_look_for_col_in_cond_before(
265 if (search_cond == NULL) {
271 ut_a(search_cond->
func != PARS_OR_TOKEN);
272 ut_a(search_cond->
func != PARS_NOT_TOKEN);
274 if (search_cond->
func == PARS_AND_TOKEN) {
277 exp = opt_look_for_col_in_cond_before(cmp_type, col_no,
288 exp = opt_look_for_col_in_cond_before(cmp_type, col_no,
294 exp = opt_look_for_col_in_comparison_before(cmp_type, col_no,
295 search_cond, sel_node,
306 if (sel_node->
asc && ((*op ==
'<') || (*op == PARS_LE_TOKEN))) {
310 }
else if (!sel_node->
asc
311 && ((*op ==
'>') || (*op == PARS_GE_TOKEN))) {
329 opt_calc_index_goodness(
334 que_node_t** index_plan,
361 for (j = 0; j < n_fields; j++) {
365 exp = opt_look_for_col_in_cond_before(
368 sel_node, nth_table, &op);
379 exp = opt_look_for_col_in_cond_before(
380 OPT_COMPARISON, col_no,
381 static_cast<func_node_t*>(
383 sel_node, nth_table, &op);
421 return(((goodness % 1024) + 2) / 4);
437 || op == PARS_LIKE_TOKEN_EXACT
438 || op == PARS_LIKE_TOKEN_PREFIX
439 || op == PARS_LIKE_TOKEN_SUFFIX
440 || op == PARS_LIKE_TOKEN_SUBSTR) {
447 }
else if (op ==
'<') {
450 }
else if (op ==
'>') {
453 }
else if (op == PARS_GE_TOKEN) {
456 }
else if (op == PARS_LE_TOKEN) {
473 que_node_t* arg_node,
478 arg = func_node->
args;
481 if (arg == arg_node) {
525 for (i = 0; i < sel_node->
n_tables; i++) {
529 if (i < sel_node->n_tables - 1) {
550 opt_search_plan_for_table(
561 ulint last_op = 75946965;
564 ulint best_last_op = 0;
565 que_node_t* index_plan[256];
566 que_node_t* best_index_plan[256];
571 plan->
asc = sel_node->
asc;
577 index = dict_table_get_first_index(table);
583 goodness = opt_calc_index_goodness(index, sel_node, i,
584 index_plan, &last_op);
585 if (goodness > best_goodness) {
588 best_goodness = goodness;
592 n_fields *
sizeof(
void*));
593 best_last_op = last_op;
596 dict_table_next_uncorrupted_index(index);
599 plan->
index = best_index;
613 pars_sym_tab_global->
heap,
614 n_fields *
sizeof(
void*)));
617 n_fields *
sizeof(
void*));
618 if (best_last_op ==
'='
619 || best_last_op == PARS_LIKE_TOKEN_EXACT
620 || best_last_op == PARS_LIKE_TOKEN_PREFIX
621 || best_last_op == PARS_LIKE_TOKEN_SUFFIX
622 || best_last_op == PARS_LIKE_TOKEN_SUBSTR) {
654 opt_classify_comparison(
665 ut_ad(cond && sel_node);
672 if (!opt_check_exp_determined_before(cond, sel_node, i + 1)) {
674 return(OPT_NOT_COND);
677 if ((i > 0) && opt_check_exp_determined_before(cond, sel_node, i)) {
679 return(OPT_NOT_COND);
695 return(OPT_END_COND);
706 && opt_is_arg(plan->
tuple_exps[n_fields - 1], cond)) {
708 return(OPT_SCROLL_COND);
717 && opt_look_for_col_in_comparison_before(
721 cond, sel_node, i, &op)) {
723 if (sel_node->
asc && ((op ==
'<') || (op == PARS_LE_TOKEN))) {
725 return(OPT_END_COND);
728 if (!sel_node->
asc && ((op ==
'>') || (op == PARS_GE_TOKEN))) {
730 return(OPT_END_COND);
736 return(OPT_TEST_COND);
759 if (cond->
func == PARS_AND_TOKEN) {
762 opt_find_test_conds(sel_node, i, new_cond);
767 opt_find_test_conds(sel_node, i, new_cond);
774 fclass = opt_classify_comparison(sel_node, i, cond);
776 if (fclass == OPT_END_COND) {
779 }
else if (fclass == OPT_TEST_COND) {
791 opt_normalize_cmp_conds(
819 cond->
func = opt_invert_cmp_op(cond->
func);
833 opt_determine_and_normalize_test_conds(
872 sym_node_list_t* col_list,
892 for (arg = func_node->
args;
897 copy_val, index, col_list, plan, arg);
925 if (col_node == sym_node) {
934 sym_node->
alias = col_node;
951 dict_table_get_first_index(index->
table), sym_node->
col_no);
958 if (col_pos == ULINT_UNDEFINED) {
983 if (search_cond == NULL) {
990 if (search_cond->
func == PARS_AND_TOKEN) {
993 opt_find_copy_cols(sel_node, i, new_cond);
998 opt_find_copy_cols(sel_node, i, new_cond);
1003 if (!opt_check_exp_determined_before(search_cond, sel_node, i + 1)) {
1052 sel_node, i, static_cast<func_node_t*>(sel_node->
search_cond));
1059 static_cast<func_node_t*>(sel_node->
search_cond));
1083 index = plan->
index;
1097 table = index->
table;
1099 clust_index = dict_table_get_first_index(table);
1103 heap = pars_sym_tab_global->
heap;
1112 for (i = 0; i < n_fields; i++) {
1115 ut_a(pos != ULINT_UNDEFINED);
1120 if (dict_index_get_nth_field(index, pos)->prefix_len != 0
1121 || dict_index_get_nth_field(clust_index, i)
1122 ->prefix_len != 0) {
1124 "InnoDB: Error in pars0opt.cc:"
1125 " table %s has prefix_len != 0\n",
1131 ut_ad(pos != ULINT_UNDEFINED);
1152 pars_sym_tab_global->
heap,
1162 sel_node->
asc = TRUE;
1166 sel_node->
asc = order_by->
asc;
1169 for (i = 0; i < sel_node->
n_tables; i++) {
1171 table = table_node->
table;
1175 opt_search_plan_for_table(sel_node, i, table);
1180 opt_determine_and_normalize_test_conds(sel_node, i);
1188 for (i = 0; i < sel_node->
n_tables; i++) {
1193 opt_classify_cols(sel_node, i);
1198 opt_clust_access(sel_node, i);
1207 opt_check_order_by(sel_node);
1209 #ifdef UNIV_SQL_DEBUG
1226 fputs(
"QUERY PLAN FOR A SELECT NODE\n", stderr);
1228 fputs(sel_node->
asc ?
"Asc. search; " :
"Desc. search; ", stderr);
1231 fputs(
"sets row x-locks; ", stderr);
1235 fputs(
"consistent read; ", stderr);
1238 fputs(
"sets row s-locks; ", stderr);
1243 for (i = 0; i < sel_node->
n_tables; i++) {
1252 fputs(
"Table ", stderr);
1254 fprintf(stderr,
"; exact m. %lu, match %lu, end conds %lu\n",
1256 (
unsigned long) n_fields,