summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/opt_split.cc48
-rw-r--r--sql/sql_join_cache.cc2
-rw-r--r--sql/sql_select.cc17
-rw-r--r--sql/sql_test.cc8
4 files changed, 66 insertions, 9 deletions
diff --git a/sql/opt_split.cc b/sql/opt_split.cc
index fd7836f55cc..c3a2d03a93b 100644
--- a/sql/opt_split.cc
+++ b/sql/opt_split.cc
@@ -236,6 +236,8 @@ public:
SplM_field_info *spl_fields;
/* The number of elements in the above list */
uint spl_field_cnt;
+ /* The list of equalities injected into WHERE for split optimization */
+ List<Item> inj_cond_list;
/* Contains the structures to generate all KEYUSEs for pushable equalities */
List<KEY_FIELD> added_key_fields;
/* The cache of evaluated execution plans for 'join' with pushed equalities */
@@ -1047,22 +1049,22 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
bool JOIN::inject_best_splitting_cond(table_map remaining_tables)
{
Item *inj_cond= 0;
- List<Item> inj_cond_list;
+ List<Item> *inj_cond_list= &spl_opt_info->inj_cond_list;
List_iterator<KEY_FIELD> li(spl_opt_info->added_key_fields);
KEY_FIELD *added_key_field;
while ((added_key_field= li++))
{
if (remaining_tables & added_key_field->val->used_tables())
continue;
- if (inj_cond_list.push_back(added_key_field->cond, thd->mem_root))
+ if (inj_cond_list->push_back(added_key_field->cond, thd->mem_root))
return true;
}
- DBUG_ASSERT(inj_cond_list.elements);
- switch (inj_cond_list.elements) {
+ DBUG_ASSERT(inj_cond_list->elements);
+ switch (inj_cond_list->elements) {
case 1:
- inj_cond= inj_cond_list.head(); break;
+ inj_cond= inj_cond_list->head(); break;
default:
- inj_cond= new (thd->mem_root) Item_cond_and(thd, inj_cond_list);
+ inj_cond= new (thd->mem_root) Item_cond_and(thd, *inj_cond_list);
if (!inj_cond)
return true;
}
@@ -1082,6 +1084,40 @@ bool JOIN::inject_best_splitting_cond(table_map remaining_tables)
/**
@brief
+ Test if equality is injected for split optimization
+
+ @param
+ eq_item equality to to test
+
+ @retval
+ true eq_item is equality injected for split optimization
+ false otherwise
+*/
+
+bool is_eq_cond_injected_for_split_opt(Item_func_eq *eq_item)
+{
+ Item *left_item= eq_item->arguments()[0]->real_item();
+ if (left_item->type() != Item::FIELD_ITEM)
+ return false;
+ Field *field= ((Item_field *) left_item)->field;
+ if (!field->table->reginfo.join_tab)
+ return false;
+ JOIN *join= field->table->reginfo.join_tab->join;
+ if (!join->spl_opt_info)
+ return false;
+ List_iterator_fast<Item> li(join->spl_opt_info->inj_cond_list);
+ Item *item;
+ while ((item= li++))
+ {
+ if (item == eq_item)
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ @brief
Fix the splitting chosen for a splittable table in the final query plan
@param
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index c62d096ea01..f072a675e31 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -1200,7 +1200,7 @@ bool JOIN_CACHE::check_emb_key_usage()
Item *item= ref->items[i]->real_item();
Field *fld= ((Item_field *) item)->field;
CACHE_FIELD *init_copy= field_descr+flag_fields+i;
- for (j= i, copy= init_copy; i < local_key_arg_fields; i++, copy++)
+ for (j= i, copy= init_copy; j < local_key_arg_fields; j++, copy++)
{
if (fld->eq(copy->field))
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index da5c9bbac54..81bd28a4ac9 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -300,6 +300,8 @@ void set_postjoin_aggr_write_func(JOIN_TAB *tab);
static Item **get_sargable_cond(JOIN *join, TABLE *table);
+bool is_eq_cond_injected_for_split_opt(Item_func_eq *eq_item);
+
#ifndef DBUG_OFF
/*
@@ -22493,6 +22495,21 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
cond->marker=3; // Checked when read
return (COND*) 0;
}
+ /*
+ If cond is an equality injected for split optimization then
+ a. when retain_ref_cond == false : cond is removed unconditionally
+ (cond that supports ref access is removed by the preceding code)
+ b. when retain_ref_cond == true : cond is removed if it does not
+ support ref access
+ */
+ if (left_item->type() == Item::FIELD_ITEM &&
+ is_eq_cond_injected_for_split_opt((Item_func_eq *) cond) &&
+ (!retain_ref_cond ||
+ !test_if_ref(root_cond, (Item_field*) left_item,right_item)))
+ {
+ cond->marker=3;
+ return (COND*) 0;
+ }
}
cond->marker=2;
cond->set_join_tab_idx(join_tab_idx_arg);
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 54eed6e4c90..ca3b9a759b7 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -617,8 +617,12 @@ Next alarm time: %lu\n",
(ulong)alarm_info.next_alarm_time);
#endif
display_table_locks();
-#ifdef HAVE_MALLINFO
- struct mallinfo info= mallinfo();
+#if defined(HAVE_MALLINFO2)
+ struct mallinfo2 info = mallinfo2();
+#elif defined(HAVE_MALLINFO)
+ struct mallinfo info= mallinfo();
+#endif
+#if defined(HAVE_MALLINFO) || defined(HAVE_MALLINFO2)
char llbuff[10][22];
printf("\nMemory status:\n\
Non-mmapped space allocated from system: %s\n\