summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-01-11 18:00:31 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2018-01-11 18:00:31 +0200
commitcca611d1c083286396e34d8fc242bbeb90f01d2a (patch)
tree6905df14f4617bcaac9b0ea8a30b8017e201462f /sql
parent773c3ceb573ea5ae8506237d3648412251ce02e7 (diff)
parentbf7719111fff5167e160abf869c03a81a3a39592 (diff)
downloadmariadb-git-cca611d1c083286396e34d8fc242bbeb90f01d2a.tar.gz
Merge 10.2 into bb-10.2-ext
Diffstat (limited to 'sql')
-rw-r--r--sql/opt_subselect.cc64
-rw-r--r--sql/sql_cte.cc7
-rw-r--r--sql/sql_parse.cc22
-rw-r--r--sql/sql_prepare.cc11
-rw-r--r--sql/sql_select.cc6
-rw-r--r--sql/sql_select.h4
-rw-r--r--sql/sql_union.cc1
7 files changed, 69 insertions, 46 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 0ab588f7d19..75296e76da9 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -2676,7 +2676,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
LooseScan detector in best_access_path)
*/
remaining_tables &= ~new_join_tab->table->map;
- table_map dups_producing_tables;
+ table_map dups_producing_tables, prev_dups_producing_tables,
+ prev_sjm_lookup_tables;
if (idx == join->const_tables)
dups_producing_tables= 0;
@@ -2687,7 +2688,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
if ((emb_sj_nest= new_join_tab->emb_sj_nest))
dups_producing_tables |= emb_sj_nest->sj_inner_tables;
- Semi_join_strategy_picker **strategy;
+ Semi_join_strategy_picker **strategy, **prev_strategy;
if (idx == join->const_tables)
{
/* First table, initialize pickers */
@@ -2739,23 +2740,54 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
3. We have no clue what to do about fanount of semi-join Y.
*/
if ((dups_producing_tables & handled_fanout) ||
- (read_time < *current_read_time &&
+ (read_time < *current_read_time &&
!(handled_fanout & pos->inner_tables_handled_with_other_sjs)))
{
- /* Mark strategy as used */
- (*strategy)->mark_used();
- pos->sj_strategy= sj_strategy;
- if (sj_strategy == SJ_OPT_MATERIALIZE)
- join->sjm_lookup_tables |= handled_fanout;
+ DBUG_ASSERT(pos->sj_strategy != sj_strategy);
+ /*
+ If the strategy choosen first time or
+ the strategy replace strategy which was used to exectly the same
+ tables
+ */
+ if (pos->sj_strategy == SJ_OPT_NONE ||
+ handled_fanout ==
+ (prev_dups_producing_tables ^ dups_producing_tables))
+ {
+ prev_strategy= strategy;
+ if (pos->sj_strategy == SJ_OPT_NONE)
+ {
+ prev_dups_producing_tables= dups_producing_tables;
+ prev_sjm_lookup_tables= join->sjm_lookup_tables;
+ }
+ /* Mark strategy as used */
+ (*strategy)->mark_used();
+ pos->sj_strategy= sj_strategy;
+ if (sj_strategy == SJ_OPT_MATERIALIZE)
+ join->sjm_lookup_tables |= handled_fanout;
+ else
+ join->sjm_lookup_tables &= ~handled_fanout;
+ *current_read_time= read_time;
+ *current_record_count= rec_count;
+ dups_producing_tables &= ~handled_fanout;
+ //TODO: update bitmap of semi-joins that were handled together with
+ // others.
+ if (is_multiple_semi_joins(join, join->positions, idx,
+ handled_fanout))
+ pos->inner_tables_handled_with_other_sjs |= handled_fanout;
+ }
else
- join->sjm_lookup_tables &= ~handled_fanout;
- *current_read_time= read_time;
- *current_record_count= rec_count;
- dups_producing_tables &= ~handled_fanout;
- //TODO: update bitmap of semi-joins that were handled together with
- // others.
- if (is_multiple_semi_joins(join, join->positions, idx, handled_fanout))
- pos->inner_tables_handled_with_other_sjs |= handled_fanout;
+ {
+ /* Conflict fall to most general variant */
+ (*prev_strategy)->set_empty();
+ dups_producing_tables= prev_dups_producing_tables;
+ join->sjm_lookup_tables= prev_sjm_lookup_tables;
+ // mark it 'none' to avpoid loops
+ pos->sj_strategy= SJ_OPT_NONE;
+ // next skip to last;
+ strategy= pickers +
+ (sizeof(pickers)/sizeof(Semi_join_strategy_picker*) - 3);
+ continue;
+ }
}
else
{
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index 44fab462c08..d2298619f63 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -816,12 +816,19 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
parse_status= parse_sql(thd, &parser_state, 0);
if (parse_status)
goto err;
+
+ if (check_dependencies_in_with_clauses(lex->with_clauses_list))
+ goto err;
+
spec_tables= lex->query_tables;
spec_tables_tail= 0;
for (TABLE_LIST *tbl= spec_tables;
tbl;
tbl= tbl->next_global)
{
+ if (!tbl->derived && !tbl->schema_table &&
+ thd->open_temporary_table(tbl))
+ goto err;
spec_tables_tail= tbl;
}
if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE))
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 3c73b2f797b..a24a6955dc3 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3243,6 +3243,9 @@ mysql_execute_command(THD *thd)
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
}
+ if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
+ DBUG_RETURN(1);
+
#ifdef HAVE_REPLICATION
if (unlikely(thd->slave_thread))
{
@@ -3700,14 +3703,6 @@ mysql_execute_command(THD *thd)
ulong privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL :
SELECT_ACL;
- /*
- The same function must be called for DML commands
- when CTEs are supported in DML statements
- */
- res= check_dependencies_in_with_clauses(thd->lex->with_clauses_list);
- if (res)
- break;
-
if (all_tables)
res= check_table_access(thd,
privileges_requested,
@@ -4134,8 +4129,7 @@ mysql_execute_command(THD *thd)
/* Copy temporarily the statement flags to thd for lock_table_names() */
uint save_thd_create_info_options= thd->lex->create_info.options;
thd->lex->create_info.options|= create_info.options;
- if (!(res= check_dependencies_in_with_clauses(lex->with_clauses_list)))
- res= open_and_lock_tables(thd, create_info, lex->query_tables, TRUE, 0);
+ res= open_and_lock_tables(thd, create_info, lex->query_tables, TRUE, 0);
thd->lex->create_info.options= save_thd_create_info_options;
if (res)
{
@@ -4749,8 +4743,7 @@ end_with_restore_list:
unit->set_limit(select_lex);
- if (!(res= check_dependencies_in_with_clauses(lex->with_clauses_list)) &&
- !(res=open_and_lock_tables(thd, all_tables, TRUE, 0)))
+ if (!(res=open_and_lock_tables(thd, all_tables, TRUE, 0)))
{
MYSQL_INSERT_SELECT_START(thd->query());
/*
@@ -5081,9 +5074,6 @@ end_with_restore_list:
{
List<set_var_base> *lex_var_list= &lex->var_list;
- if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
- goto error;
-
if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
|| open_and_lock_tables(thd, all_tables, TRUE, 0)))
goto error;
@@ -6402,8 +6392,6 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
new (thd->mem_root) Item_int(thd,
(ulonglong) thd->variables.select_limit);
}
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- return 1;
if (!(res= open_and_lock_tables(thd, all_tables, TRUE, 0)))
{
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 8d10a7f4813..fe5a82805b6 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1516,8 +1516,6 @@ static int mysql_test_select(Prepared_statement *stmt,
lex->select_lex.context.resolve_in_select_list= TRUE;
ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL;
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- goto error;
if (tables)
{
if (check_table_access(thd, privilege, tables, FALSE, UINT_MAX, FALSE))
@@ -1784,9 +1782,6 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
if (create_table_precheck(thd, tables, create_table))
DBUG_RETURN(TRUE);
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- DBUG_RETURN(TRUE);
-
if (select_lex->item_list.elements)
{
/* Base table and temporary table are not in the same name space. */
@@ -2177,9 +2172,6 @@ static bool mysql_test_insert_select(Prepared_statement *stmt,
if (insert_precheck(stmt->thd, tables))
return 1;
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- return 1;
-
/* store it, because mysql_insert_select_prepare_tester change it */
first_local_table= lex->select_lex.table_list.first;
DBUG_ASSERT(first_local_table != 0);
@@ -2282,6 +2274,9 @@ static bool check_prepared_statement(Prepared_statement *stmt)
if (tables)
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
+ if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
+ goto error;
+
if (sql_command_flags[sql_command] & CF_HA_CLOSE)
mysql_ha_rm_tables(thd, tables);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 819633b722e..cada01cb566 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -18099,7 +18099,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
table->in_use->inc_status_created_tmp_tables();
table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
share->db_record_offset= 1;
- table->created= TRUE;
+ table->set_created();
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
@@ -18599,8 +18599,8 @@ int rr_sequential_and_unpack(READ_RECORD *info)
*/
bool instantiate_tmp_table(TABLE *table, KEY *keyinfo,
- MARIA_COLUMNDEF *start_recinfo,
- MARIA_COLUMNDEF **recinfo,
+ TMP_ENGINE_COLUMNDEF *start_recinfo,
+ TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options)
{
if (table->s->db_type() == TMP_ENGINE_HTON)
diff --git a/sql/sql_select.h b/sql/sql_select.h
index e5d3ed1a41f..4e2206dd098 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -2287,8 +2287,8 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options);
bool instantiate_tmp_table(TABLE *table, KEY *keyinfo,
- MARIA_COLUMNDEF *start_recinfo,
- MARIA_COLUMNDEF **recinfo,
+ TMP_ENGINE_COLUMNDEF *start_recinfo,
+ TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options);
bool open_tmp_table(TABLE *table);
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps);
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 3903f3e8d9e..47286f1df14 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1715,6 +1715,7 @@ bool st_select_lex_unit::exec_recursive()
sq;
sq= sq->next_with_rec_ref)
{
+ sq->reset();
sq->engine->force_reexecution();
}