diff options
author | Igor Babaev <igor@askmonty.org> | 2019-02-12 23:19:43 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2019-02-12 23:19:43 -0800 |
commit | 953ca199fb62bcd190d2af4d6177f986564ec1ad (patch) | |
tree | 0ee967694db2fe959eed2f4091ab18bf722436b7 /sql/sql_derived.cc | |
parent | 27c3abde3071ad2010cbcda5b07435ad15364a70 (diff) | |
parent | be8709eb7bdf2a68a1c04fd8ab368113f5f39b63 (diff) | |
download | mariadb-git-953ca199fb62bcd190d2af4d6177f986564ec1ad.tar.gz |
Merge branch '10.4' into bb-10.4-mdev17096
Diffstat (limited to 'sql/sql_derived.cc')
-rw-r--r-- | sql/sql_derived.cc | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index fbd8365e619..a3a53320ac0 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -33,6 +33,7 @@ #include "sql_acl.h" // SELECT_ACL #include "sql_class.h" #include "sql_cte.h" +#include "my_json_writer.h" typedef bool (*dt_processor)(THD *thd, LEX *lex, TABLE_LIST *derived); @@ -199,6 +200,7 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) if ((res= (*processors[phase])(lex->thd, lex, derived))) break; } + lex->thd->derived_tables_processing= FALSE; DBUG_RETURN(res); } @@ -369,6 +371,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", (derived->alias.str ? derived->alias.str : "<NULL>"), derived->get_unit())); + const char *cause= NULL; if (derived->merged) { @@ -380,6 +383,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) if (dt_select->uncacheable & UNCACHEABLE_RAND) { /* There is random function => fall back to materialization. */ + cause= "Random function in the select"; derived->change_refs_to_fields(); derived->set_materialized_derived(); DBUG_RETURN(FALSE); @@ -409,15 +413,11 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) and small subqueries, and the bigger one can't be merged it wouldn't block the smaller one. */ - if (parent_lex->get_free_table_map(&map, &tablenr)) - { - /* There is no enough table bits, fall back to materialization. */ - goto unconditional_materialization; - } - - if (dt_select->leaf_tables.elements + tablenr > MAX_TABLES) + if (parent_lex->get_free_table_map(&map, &tablenr) || + dt_select->leaf_tables.elements + tablenr > MAX_TABLES) { /* There is no enough table bits, fall back to materialization. */ + cause= "Not enough table bits to merge subquery"; goto unconditional_materialization; } @@ -494,6 +494,24 @@ exit_merge: DBUG_RETURN(res); unconditional_materialization: + + if (unlikely(thd->trace_started())) + { + /* + Add to the optimizer trace the change in choice for merged + derived tables/views to materialised ones. + */ + Json_writer_object trace_wrapper(thd); + Json_writer_object trace_derived(thd, derived->is_derived() ? + "derived" : "view"); + trace_derived.add("table", derived->alias.str ? derived->alias.str : "<NULL>") + .add_select_number(derived->get_unit()-> + first_select()->select_number) + .add("initial_choice", "merged") + .add("final_choice", "materialized") + .add("cause", cause); + } + derived->change_refs_to_fields(); derived->set_materialized_derived(); if (!derived->table || !derived->table->is_created()) @@ -662,7 +680,6 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) DBUG_ENTER("mysql_derived_prepare"); DBUG_PRINT("enter", ("unit: %p table_list: %p alias: '%s'", unit, derived, derived->alias.str)); - if (!unit) DBUG_RETURN(FALSE); @@ -755,6 +772,22 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) } } + if (unlikely(thd->trace_started())) + { + /* + Add to optimizer trace whether a derived table/view + is merged into the parent select or not. + */ + Json_writer_object trace_wrapper(thd); + Json_writer_object trace_derived(thd, derived->is_derived() ? + "derived" : "view"); + trace_derived.add("table", derived->alias.str ? derived->alias.str : "<NULL>") + .add_select_number(derived->get_unit()->first_select()->select_number); + if (derived->is_materialized_derived()) + trace_derived.add("materialized", true); + if (derived->is_merged_derived()) + trace_derived.add("merged", true); + } /* Above cascade call of prepare is important for PS protocol, but after it is called we can check if we really need prepare for this derived |