summaryrefslogtreecommitdiff
path: root/sql/opt_subselect.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-09-03 12:58:41 +0200
committerSergei Golubchik <serg@mariadb.org>2015-09-03 12:58:41 +0200
commit530a6e74819ec14b5fdc42aa588b236ecb9f2fcd (patch)
treea4d45b1fd0e434c23577507364fa443226676eb5 /sql/opt_subselect.cc
parent5088cbf4ed7224698678f3eaf406361c6e7db4b8 (diff)
parent4b41e3c7f33714186c97a6cc2e6d3bb93b050c61 (diff)
downloadmariadb-git-530a6e74819ec14b5fdc42aa588b236ecb9f2fcd.tar.gz
Merge branch '10.0' into 10.1
referenced_by_foreign_key2(), needed for InnoDB to compile, was taken from 10.0-galera
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r--sql/opt_subselect.cc91
1 files changed, 69 insertions, 22 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index dac607195f0..9c6784437a7 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -4371,6 +4371,74 @@ int init_dups_weedout(JOIN *join, uint first_table, int first_fanout_table, uint
/*
+ @brief
+ Set up semi-join Loose Scan strategy for execution
+
+ @detail
+ Other strategies are done in setup_semijoin_dups_elimination(),
+ however, we need to set up Loose Scan earlier, before make_join_select is
+ called. This is to prevent make_join_select() from switching full index
+ scans into quick selects (which will break Loose Scan access).
+
+ @return
+ 0 OK
+ 1 Error
+*/
+
+int setup_semijoin_loosescan(JOIN *join)
+{
+ uint i;
+ DBUG_ENTER("setup_semijoin_loosescan");
+
+ POSITION *pos= join->best_positions + join->const_tables;
+ for (i= join->const_tables ; i < join->top_join_tab_count; )
+ {
+ JOIN_TAB *tab=join->join_tab + i;
+ switch (pos->sj_strategy) {
+ case SJ_OPT_MATERIALIZE:
+ case SJ_OPT_MATERIALIZE_SCAN:
+ i+= 1; /* join tabs are embedded in the nest */
+ pos += pos->n_sj_tables;
+ break;
+ case SJ_OPT_LOOSE_SCAN:
+ {
+ /* We jump from the last table to the first one */
+ tab->loosescan_match_tab= tab + pos->n_sj_tables - 1;
+
+ /* LooseScan requires records to be produced in order */
+ if (tab->select && tab->select->quick)
+ tab->select->quick->need_sorted_output();
+
+ for (uint j= i; j < i + pos->n_sj_tables; j++)
+ join->join_tab[j].inside_loosescan_range= TRUE;
+
+ /* Calculate key length */
+ uint keylen= 0;
+ uint keyno= pos->loosescan_picker.loosescan_key;
+ for (uint kp=0; kp < pos->loosescan_picker.loosescan_parts; kp++)
+ keylen += tab->table->key_info[keyno].key_part[kp].store_length;
+
+ tab->loosescan_key= keyno;
+ tab->loosescan_key_len= keylen;
+ if (pos->n_sj_tables > 1)
+ tab[pos->n_sj_tables - 1].do_firstmatch= tab;
+ i+= pos->n_sj_tables;
+ pos+= pos->n_sj_tables;
+ break;
+ }
+ default:
+ {
+ i++;
+ pos++;
+ break;
+ }
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
Setup the strategies to eliminate semi-join duplicates.
SYNOPSIS
@@ -4478,8 +4546,6 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
for (i= join->const_tables ; i < join->top_join_tab_count; )
{
JOIN_TAB *tab=join->join_tab + i;
- //POSITION *pos= join->best_positions + i;
- uint keylen, keyno;
switch (pos->sj_strategy) {
case SJ_OPT_MATERIALIZE:
case SJ_OPT_MATERIALIZE_SCAN:
@@ -4489,26 +4555,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
break;
case SJ_OPT_LOOSE_SCAN:
{
- /* We jump from the last table to the first one */
- tab->loosescan_match_tab= tab + pos->n_sj_tables - 1;
-
- /* LooseScan requires records to be produced in order */
- if (tab->select && tab->select->quick)
- tab->select->quick->need_sorted_output();
-
- for (uint j= i; j < i + pos->n_sj_tables; j++)
- join->join_tab[j].inside_loosescan_range= TRUE;
-
- /* Calculate key length */
- keylen= 0;
- keyno= pos->loosescan_picker.loosescan_key;
- for (uint kp=0; kp < pos->loosescan_picker.loosescan_parts; kp++)
- keylen += tab->table->key_info[keyno].key_part[kp].store_length;
-
- tab->loosescan_key= keyno;
- tab->loosescan_key_len= keylen;
- if (pos->n_sj_tables > 1)
- tab[pos->n_sj_tables - 1].do_firstmatch= tab;
+ /* Setup already handled by setup_semijoin_loosescan */
i+= pos->n_sj_tables;
pos+= pos->n_sj_tables;
break;