diff options
author | Sergei Petrunia <psergey@askmonty.org> | 2021-06-30 18:13:08 +0300 |
---|---|---|
committer | Sergei Petrunia <psergey@askmonty.org> | 2021-06-30 18:41:46 +0300 |
commit | eebe2090c848b5cedc5235473d80dbd2c25d2943 (patch) | |
tree | bd12d7d9809997b892437ef3b7341d330ee46147 /sql | |
parent | a1e2ca057dda4dc434f057ce9391aa7afd9b5583 (diff) | |
parent | 4a6e2d343745c11086c05f0041a8267591bb073c (diff) | |
download | mariadb-git-eebe2090c848b5cedc5235473d80dbd2c25d2943.tar.gz |
Merge 10.3 -> 10.4
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/item_create.cc | 5 | ||||
-rw-r--r-- | sql/lex.h | 7 | ||||
-rw-r--r-- | sql/spatial.cc | 6 | ||||
-rw-r--r-- | sql/sql_derived.cc | 63 | ||||
-rw-r--r-- | sql/sql_derived.h | 5 | ||||
-rw-r--r-- | sql/sql_lex.cc | 13 | ||||
-rw-r--r-- | sql/sql_show.cc | 83 |
8 files changed, 174 insertions, 10 deletions
diff --git a/sql/handler.h b/sql/handler.h index a179e084605..99aaac12402 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1008,6 +1008,7 @@ enum enum_schema_tables SCH_FILES, SCH_GLOBAL_STATUS, SCH_GLOBAL_VARIABLES, + SCH_KEYWORDS, SCH_KEY_CACHES, SCH_KEY_COLUMN_USAGE, SCH_OPEN_TABLES, @@ -1024,6 +1025,7 @@ enum enum_schema_tables SCH_SESSION_STATUS, SCH_SESSION_VARIABLES, SCH_STATISTICS, + SCH_SQL_FUNCTIONS, SCH_SYSTEM_VARIABLES, SCH_TABLES, SCH_TABLESPACES, diff --git a/sql/item_create.cc b/sql/item_create.cc index ffc90e16b8f..d92aba03a4a 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -7147,7 +7147,6 @@ Create_func_year_week::create_native(THD *thd, LEX_CSTRING *name, return func; } - #define BUILDER(F) & F::s_singleton #ifdef HAVE_SPATIAL @@ -7167,7 +7166,7 @@ Create_func_year_week::create_native(THD *thd, LEX_CSTRING *name, - keep 1 line per entry, it makes grep | sort easier */ -static Native_func_registry func_array[] = +Native_func_registry func_array[] = { { { STRING_WITH_LEN("ABS") }, BUILDER(Create_func_abs)}, { { STRING_WITH_LEN("ACOS") }, BUILDER(Create_func_acos)}, @@ -7526,6 +7525,8 @@ static Native_func_registry func_array[] = { {0, 0}, NULL} }; +size_t func_array_length= sizeof(func_array) / sizeof(Native_func_registry) - 1; + static HASH native_functions_hash; extern "C" uchar* diff --git a/sql/lex.h b/sql/lex.h index 92ce01a1094..e35e109a3bf 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -45,7 +45,7 @@ SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"}; lists */ -static SYMBOL symbols[] = { +SYMBOL symbols[] = { { "&&", SYM(AND_AND_SYM)}, { "<=", SYM(LE)}, { "<>", SYM(NE)}, @@ -731,7 +731,7 @@ static SYMBOL symbols[] = { }; -static SYMBOL sql_functions[] = { +SYMBOL sql_functions[] = { { "ADDDATE", SYM(ADDDATE_SYM)}, { "BIT_AND", SYM(BIT_AND)}, { "BIT_OR", SYM(BIT_OR)}, @@ -782,4 +782,7 @@ static SYMBOL sql_functions[] = { { "VAR_SAMP", SYM(VAR_SAMP_SYM)}, }; +size_t symbols_length= sizeof(symbols) / sizeof(SYMBOL); +size_t sql_functions_length= sizeof(sql_functions) / sizeof(SYMBOL); + #endif /* LEX_INCLUDED */ diff --git a/sql/spatial.cc b/sql/spatial.cc index bda64c6d420..53e8c4c8bdd 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -539,7 +539,11 @@ Geometry *Geometry::create_from_json(Geometry_buffer *buffer, goto handle_geometry_key; feature_type_found= 1; } + else /* can't understand the type. */ + break; } + else /* The "type" value can only be string. */ + break; } else if (key_len == coord_keyname_len && memcmp(key_buf, coord_keyname, coord_keyname_len) == 0) @@ -556,6 +560,8 @@ Geometry *Geometry::create_from_json(Geometry_buffer *buffer, coord_start= je->value_begin; if (ci && ci != &geometrycollection_class) goto create_geom; + if (json_skip_level(je)) + goto err_return; } } else if (key_len == geometries_keyname_len && diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index fc01dcdc750..a4e0fd6b683 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -25,13 +25,13 @@ #include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */ #include "sql_priv.h" #include "unireg.h" -#include "sql_derived.h" #include "sql_select.h" #include "derived_handler.h" #include "sql_base.h" #include "sql_view.h" // check_duplicate_names #include "sql_acl.h" // SELECT_ACL #include "sql_class.h" +#include "sql_derived.h" #include "sql_cte.h" #include "my_json_writer.h" #include "opt_trace.h" @@ -1359,6 +1359,67 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived) } +/* + @brief + Given condition cond and transformer+argument, try transforming as many + conjuncts as possible. + + @detail + The motivation of this function is to convert the condition that's being + pushed into a WHERE clause with derived_field_transformer_for_where or + with derived_grouping_field_transformer_for_where. + The transformer may fail for some sub-condition, in this case we want to + convert the most restrictive part of the condition that can be pushed. + + This function only does it for top-level AND: conjuncts that could not be + converted are dropped. + + @return + Converted condition, or NULL if nothing could be converted +*/ + +Item *transform_condition_or_part(THD *thd, + Item *cond, + Item_transformer transformer, + uchar *arg) +{ + if (cond->type() != Item::COND_ITEM || + ((Item_cond*) cond)->functype() != Item_func::COND_AND_FUNC) + { + Item *new_item= cond->transform(thd, transformer, arg); + // Indicate that the condition is not pushable + if (!new_item) + cond->clear_extraction_flag(); + return new_item; + } + + List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item=li++)) + { + Item *new_item= item->transform(thd, transformer, arg); + if (!new_item) + { + // Indicate that the condition is not pushable + item->clear_extraction_flag(); + li.remove(); + } + else + li.replace(new_item); + } + + switch (((Item_cond*) cond)->argument_list()->elements) + { + case 0: + return NULL; + case 1: + return ((Item_cond*) cond)->argument_list()->head(); + default: + return cond; + } +} + + /** @brief Extract condition that can be pushed into a derived table/view diff --git a/sql/sql_derived.h b/sql/sql_derived.h index 403277d65c9..6100b4b4d7e 100644 --- a/sql/sql_derived.h +++ b/sql/sql_derived.h @@ -23,6 +23,11 @@ struct LEX; bool mysql_handle_derived(LEX *lex, uint phases); bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases); +Item *transform_condition_or_part(THD *thd, + Item *cond, + Item_transformer transformer, + uchar *arg); + bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived); #endif /* SQL_DERIVED_INCLUDED */ diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 93a4fcbe277..1ec5d0b0550 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -31,6 +31,7 @@ #include "sql_select.h" #include "sql_cte.h" #include "sql_signal.h" +#include "sql_derived.h" #include "sql_truncate.h" // Sql_cmd_truncate_table #include "sql_admin.h" // Sql_cmd_analyze/Check..._table #include "sql_partition.h" @@ -9744,8 +9745,7 @@ void st_select_lex::pushdown_cond_into_where_clause(THD *thd, Item *cond, if (!join->group_list && !with_sum_func) { - cond= - cond->transform(thd, transformer, arg); + cond= transform_condition_or_part(thd, cond, transformer, arg); if (cond) { cond->walk( @@ -9770,9 +9770,12 @@ void st_select_lex::pushdown_cond_into_where_clause(THD *thd, Item *cond, into WHERE so it can be pushed. */ if (cond_over_grouping_fields) - cond_over_grouping_fields= cond_over_grouping_fields->transform(thd, - &Item::grouping_field_transformer_for_where, - (uchar*) this); + { + cond_over_grouping_fields= + transform_condition_or_part(thd, cond_over_grouping_fields, + &Item::grouping_field_transformer_for_where, + (uchar*) this); + } if (cond_over_grouping_fields) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 7b5b2c8bf89..1f8278528cf 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -66,6 +66,19 @@ #include "opt_trace.h" #include "my_cpu.h" + +#include "lex_symbol.h" +#define KEYWORD_SIZE 64 + +extern SYMBOL symbols[]; +extern size_t symbols_length; + +extern SYMBOL sql_functions[]; +extern size_t sql_functions_length; + +extern Native_func_registry func_array[]; +extern size_t func_array_length; + enum enum_i_s_events_fields { ISE_EVENT_CATALOG= 0, @@ -7941,6 +7954,60 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_RETURN(res); } +int add_symbol_to_table(const char* name, TABLE* table){ + DBUG_ENTER("add_symbol_to_table"); + + uint length= strlen(name); + + // If you've added a new SQL keyword longer than KEYWORD_SIZE, + // please increase the defined max length + DBUG_ASSERT(length < KEYWORD_SIZE); + + restore_record(table, s->default_values); + table->field[0]->set_notnull(); + table->field[0]->store(name, length, + system_charset_info); + if (schema_table_store_record(table->in_use, table)) + DBUG_RETURN(1); + + DBUG_RETURN(0); +} + +int fill_i_s_keywords(THD *thd, TABLE_LIST *tables, COND *cond) +{ + DBUG_ENTER("fill_i_s_keywords"); + + TABLE *table= tables->table; + + for (uint i= 0; i < symbols_length; i++){ + const char *name= symbols[i].name; + if (add_symbol_to_table(name, table)) + DBUG_RETURN(1); + } + + DBUG_RETURN(0); +} + +int fill_i_s_sql_functions(THD *thd, TABLE_LIST *tables, COND *cond) { + DBUG_ENTER("fill_i_s_sql_functions"); + + TABLE *table= tables->table; + + for (uint i= 0; i < sql_functions_length; i++){ + const char *name= sql_functions[i].name; + if (add_symbol_to_table(name, table)) + DBUG_RETURN(1); + } + + for (uint i= 0; i < func_array_length; i++){ + const char *name= func_array[i].name.str; + if (add_symbol_to_table(name, table)) + DBUG_RETURN(1); + } + + DBUG_RETURN(0); +} + int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) { @@ -9235,6 +9302,18 @@ ST_FIELD_INFO enabled_roles_fields_info[]= {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; +ST_FIELD_INFO keywords_field_info[]= +{ + {"WORD", KEYWORD_SIZE, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} +}; + +ST_FIELD_INFO sql_functions_field_info[]= +{ + {"FUNCTION", KEYWORD_SIZE, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} +}; + ST_FIELD_INFO engines_fields_info[]= { @@ -9942,6 +10021,8 @@ ST_SCHEMA_TABLE schema_tables[]= fill_status, make_old_format, 0, 0, -1, 0, 0}, {"GLOBAL_VARIABLES", variables_fields_info, 0, fill_variables, make_old_format, 0, 0, -1, 0, 0}, + {"KEYWORDS", keywords_field_info, 0, + fill_i_s_keywords, 0, 0, -1, -1, 0, 0}, {"KEY_CACHES", keycache_fields_info, 0, fill_key_cache_tables, 0, 0, -1,-1, 0, 0}, {"KEY_COLUMN_USAGE", key_column_usage_fields_info, 0, @@ -9979,6 +10060,8 @@ ST_SCHEMA_TABLE schema_tables[]= {"STATISTICS", stat_fields_info, 0, get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0, OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE}, + {"SQL_FUNCTIONS", sql_functions_field_info, 0, + fill_i_s_sql_functions, 0, 0, -1, -1, 0, 0}, {"SYSTEM_VARIABLES", sysvars_fields_info, 0, fill_sysvars, make_old_format, 0, 0, -1, 0, 0}, {"TABLES", tables_fields_info, 0, |