diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-11-20 11:12:08 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-11-20 11:12:08 +0400 |
commit | 4a8039b04e60b599b90e1c58021026697272c324 (patch) | |
tree | b8f3d634a95f90b7a496aa3781fb3d9577294964 /sql | |
parent | a0c7d3ff940600aa2d7cff067396ef6985f0bdc4 (diff) | |
parent | a20c1217a5ce4235f72c59935a03b56fead2f6c4 (diff) | |
download | mariadb-git-4a8039b04e60b599b90e1c58021026697272c324.tar.gz |
Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 6 | ||||
-rw-r--r-- | sql/item_geofunc.cc | 3 | ||||
-rw-r--r-- | sql/item_jsonfunc.cc | 10 | ||||
-rw-r--r-- | sql/share/errmsg-utf8.txt | 3 | ||||
-rw-r--r-- | sql/spatial.cc | 35 | ||||
-rw-r--r-- | sql/spatial.h | 1 | ||||
-rw-r--r-- | sql/sql_acl.cc | 5 | ||||
-rw-r--r-- | sql/sql_cte.cc | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 31 |
10 files changed, 98 insertions, 7 deletions
diff --git a/sql/item.cc b/sql/item.cc index 3daf1e8393e..62c5bdb23b6 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3783,6 +3783,7 @@ void Item_param::set_int(longlong i, uint32 max_length_arg) DBUG_ENTER("Item_param::set_int"); value.integer= (longlong) i; state= INT_VALUE; + collation.set_numeric(); max_length= max_length_arg; decimals= 0; maybe_null= 0; @@ -3795,6 +3796,7 @@ void Item_param::set_double(double d) DBUG_ENTER("Item_param::set_double"); value.real= d; state= REAL_VALUE; + collation.set_numeric(); max_length= DBL_DIG + 8; decimals= NOT_FIXED_DEC; maybe_null= 0; @@ -3824,6 +3826,7 @@ void Item_param::set_decimal(const char *str, ulong length) str2my_decimal(E_DEC_FATAL_ERROR, str, &decimal_value, &end); state= DECIMAL_VALUE; decimals= decimal_value.frac; + collation.set_numeric(); max_length= my_decimal_precision_to_length_no_truncation(decimal_value.precision(), decimals, unsigned_flag); @@ -3839,6 +3842,7 @@ void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg) my_decimal2decimal(dv, &decimal_value); decimals= (uint8) decimal_value.frac; + collation.set_numeric(); unsigned_flag= unsigned_arg; max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, decimals, unsigned_flag); @@ -3849,6 +3853,7 @@ void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg) void Item_param::fix_temporal(uint32 max_length_arg, uint decimals_arg) { state= TIME_VALUE; + collation.set_numeric(); max_length= max_length_arg; decimals= decimals_arg; fix_type(Item::DATE_ITEM); @@ -4579,6 +4584,7 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) } null_value= FALSE; + unsigned_flag= arg->unsigned_flag; switch (arg->result_type()) { case STRING_RESULT: diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 83d8d2516f0..9fd246bbe4c 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -165,6 +165,9 @@ String *Item_func_geometry_from_json::val_str(String *str) case Geometry::GEOJ_TOO_FEW_POINTS: code= ER_GEOJSON_TOO_FEW_POINTS; break; + case Geometry::GEOJ_EMPTY_COORDINATES: + code= ER_GEOJSON_EMPTY_COORDINATES; + break; case Geometry::GEOJ_POLYGON_NOT_CLOSED: code= ER_GEOJSON_NOT_CLOSED; break; diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index ddc1da5b6d2..38d6e4feba0 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -69,6 +69,7 @@ static inline bool append_simple(String *s, const uchar *a, size_t a_len) /* Appends JSON string to the String object taking charsets in consideration. +*/ static int st_append_json(String *s, CHARSET_INFO *json_cs, const uchar *js, uint js_len) { @@ -82,9 +83,8 @@ static int st_append_json(String *s, return 0; } - return js_len; + return str_len; } -*/ /* @@ -475,6 +475,9 @@ String *Item_func_json_value::val_str(String *str) json_scan_start(&je, js->charset(),(const uchar *) js->ptr(), (const uchar *) js->ptr() + js->length()); + str->length(0); + str->set_charset(&my_charset_utf8mb4_bin); + path.cur_step= path.p.steps; continue_search: if (json_find_path(&je, &path.p, &path.cur_step, array_counters)) @@ -515,8 +518,7 @@ bool Item_func_json_value::check_and_get_value(json_engine_t *je, String *res, return true; } - res->set((const char *) je->value, je->value_len, je->s.cs); - return false; + return st_append_json(res, je->s.cs, je->value, je->value_len); } diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 8d426074c5a..63441ade8b7 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7747,6 +7747,9 @@ ER_SUM_FUNC_WITH_WINDOW_FUNC_AS_ARG ER_NET_OK_PACKET_TOO_LARGE eng "OK packet too large" +ER_GEOJSON_EMPTY_COORDINATES + eng "Incorrect GeoJSON format - empty 'coordinates' array." + ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION eng "Illegal parameter data types %s and %s for operation '%s'" ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION diff --git a/sql/spatial.cc b/sql/spatial.cc index 357e311543f..2aca528dd15 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -1041,7 +1041,7 @@ bool Gis_line_string::init_from_json(json_engine_t *je, bool er_on_3D, } if (n_points < 1) { - je->s.error= GEOJ_TOO_FEW_POINTS; + je->s.error= Geometry::GEOJ_TOO_FEW_POINTS; return TRUE; } wkb->write_at_position(np_pos, n_points); @@ -1440,6 +1440,15 @@ bool Gis_polygon::init_from_json(json_engine_t *je, bool er_on_3D, String *wkb) } n_linear_rings++; } + + if (je->s.error) + return TRUE; + + if (n_linear_rings == 0) + { + je->s.error= Geometry::GEOJ_EMPTY_COORDINATES; + return TRUE; + } wkb->write_at_position(lr_pos, n_linear_rings); return FALSE; } @@ -1945,6 +1954,14 @@ bool Gis_multi_point::init_from_json(json_engine_t *je, bool er_on_3D, n_points++; } + if (je->s.error) + return TRUE; + if (n_points == 0) + { + je->s.error= Geometry::GEOJ_EMPTY_COORDINATES; + return TRUE; + } + wkb->write_at_position(np_pos, n_points); return FALSE; } @@ -2214,6 +2231,15 @@ bool Gis_multi_line_string::init_from_json(json_engine_t *je, bool er_on_3D, n_line_strings++; } + if (je->s.error) + return TRUE; + + if (n_line_strings == 0) + { + je->s.error= Geometry::GEOJ_EMPTY_COORDINATES; + return TRUE; + } + wkb->write_at_position(ls_pos, n_line_strings); return FALSE; } @@ -2603,6 +2629,13 @@ bool Gis_multi_polygon::init_from_json(json_engine_t *je, bool er_on_3D, n_polygons++; } + if (je->s.error) + return TRUE; + if (n_polygons == 0) + { + je->s.error= Geometry::GEOJ_EMPTY_COORDINATES; + return TRUE; + } wkb->write_at_position(np_pos, n_polygons); return FALSE; } diff --git a/sql/spatial.h b/sql/spatial.h index 78e850dc2d7..901544b6916 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -256,6 +256,7 @@ public: GEOJ_TOO_FEW_POINTS= 2, GEOJ_POLYGON_NOT_CLOSED= 3, GEOJ_DIMENSION_NOT_SUPPORTED= 4, + GEOJ_EMPTY_COORDINATES= 5, }; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7e95abead67..9935b5a8bd6 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7593,6 +7593,11 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, INSERT_ACL : SELECT_ACL); } + if (tl->with || + (tl->select_lex && + (tl->with= tl->select_lex->find_table_def_in_with_clauses(tl)))) + continue; + const ACL_internal_table_access *access= get_cached_table_access(&t_ref->grant.m_internal, t_ref->get_db_name(), diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 0d91d813dfc..a4a2ff16c62 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -822,9 +822,10 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd, tbl; tbl= tbl->next_global) { - tbl->grant.privilege= with_table->grant.privilege; spec_tables_tail= tbl; } + if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE)) + goto err; if (spec_tables) { if (with_table->next_global) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0132921ad1c..a613ad6c969 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3698,6 +3698,14 @@ 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, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 46b8d7dc9a8..c576aae32ad 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12848,8 +12848,37 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, can be used without tmp. table. */ bool can_subst_to_first_table= false; + bool first_is_in_sjm_nest= false; + if (first_is_base_table) + { + TABLE_LIST *tbl_for_first= + join->join_tab[join->const_tables].table->pos_in_table_list; + first_is_in_sjm_nest= tbl_for_first->sj_mat_info && + tbl_for_first->sj_mat_info->is_used; + } + /* + Currently we do not employ the optimization that uses multiple + equalities for ORDER BY to remove tmp table in the case when + the first table happens to be the result of materialization of + a semi-join nest ( <=> first_is_in_sjm_nest == true). + + When a semi-join nest is materialized and scanned to look for + possible matches in the remaining tables for every its row + the fields from the result of materialization are copied + into the record buffers of tables from the semi-join nest. + So these copies are used to access the remaining tables rather + than the fields from the result of materialization. + + Unfortunately now this so-called 'copy back' technique is + supported only if the rows are scanned with the rr_sequential + function, but not with other rr_* functions that are employed + when the result of materialization is required to be sorted. + + TODO: either to support 'copy back' technique for the above case, + or to get rid of this technique altogether. + */ if (optimizer_flag(join->thd, OPTIMIZER_SWITCH_ORDERBY_EQ_PROP) && - first_is_base_table && + first_is_base_table && !first_is_in_sjm_nest && order->item[0]->real_item()->type() == Item::FIELD_ITEM && join->cond_equal) { |