diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-12-27 21:17:16 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-12-27 21:17:16 +0200 |
commit | 8cc15c036dbc5fefb025eb957f4d312d41659163 (patch) | |
tree | 6c4d67d677e6bb9bc90b7e3f08d18c8a798680b6 /sql | |
parent | cc28947315887f55814cb8bc4e68d4e2fe6c65e6 (diff) | |
parent | b86e0f25f896285a34c999515ad50e50d879f3e7 (diff) | |
download | mariadb-git-8cc15c036dbc5fefb025eb957f4d312d41659163.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'sql')
-rw-r--r-- | sql/CMakeLists.txt | 19 | ||||
-rw-r--r-- | sql/item.cc | 11 | ||||
-rw-r--r-- | sql/item_sum.cc | 22 | ||||
-rw-r--r-- | sql/item_sum.h | 77 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 16 | ||||
-rw-r--r-- | sql/item_timefunc.h | 51 | ||||
-rw-r--r-- | sql/item_windowfunc.h | 175 | ||||
-rw-r--r-- | sql/sql_audit.h | 22 | ||||
-rw-r--r-- | sql/sql_insert.cc | 41 | ||||
-rw-r--r-- | sql/sql_lex.h | 22 | ||||
-rw-r--r-- | sql/sql_select.cc | 36 | ||||
-rw-r--r-- | sql/sql_select.h | 1 | ||||
-rw-r--r-- | sql/sql_show.cc | 43 | ||||
-rw-r--r-- | sql/sql_type.h | 9 | ||||
-rw-r--r-- | sql/sql_window.cc | 6 | ||||
-rw-r--r-- | sql/threadpool_generic.cc | 2 | ||||
-rw-r--r-- | sql/tztime.cc | 10 | ||||
-rw-r--r-- | sql/unireg.cc | 3 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 1 |
19 files changed, 307 insertions, 260 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index e3e2fba8c78..8465b5a6206 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -449,15 +449,18 @@ IF(WIN32 AND TARGET mysqld AND NOT CMAKE_CROSSCOMPILING) ENDIF() MAKE_DIRECTORY(${CMAKE_CURRENT_BINARY_DIR}/data) ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep - COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} - -DTOP_SRCDIR="${CMAKE_SOURCE_DIR}" - -DBINDIR="${CMAKE_CURRENT_BINARY_DIR}" - -DMYSQLD_EXECUTABLE="$<TARGET_FILE:mysqld>" - -DCMAKE_CFG_INTDIR="${CMAKE_CFG_INTDIR}" - -P ${CMAKE_SOURCE_DIR}/cmake/create_initial_db.cmake + OUTPUT initdb.dep + COMMAND ${CMAKE_COMMAND} -E remove_directory data + COMMAND ${CMAKE_COMMAND} -E make_directory data + COMMAND ${CMAKE_COMMAND} -E chdir data ${CMAKE_COMMAND} + ${CONFIG_PARAM} + -DTOP_SRCDIR="${CMAKE_SOURCE_DIR}" + -DBINDIR="${CMAKE_CURRENT_BINARY_DIR}" + -DMYSQLD_EXECUTABLE="$<TARGET_FILE:mysqld>" + -DCMAKE_CFG_INTDIR="${CMAKE_CFG_INTDIR}" + -P ${CMAKE_SOURCE_DIR}/cmake/create_initial_db.cmake COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ DEPENDS mysqld ) ADD_CUSTOM_TARGET(initial_database diff --git a/sql/item.cc b/sql/item.cc index 1ed178f1194..92b127cf773 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3229,12 +3229,13 @@ bool Item_field::get_date(THD *thd, MYSQL_TIME *ltime,date_mode_t fuzzydate) bool Item_field::get_date_result(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) { - if (result_field->is_null() || result_field->get_date(ltime,fuzzydate)) + if ((null_value= result_field->is_null()) || + result_field->get_date(ltime, fuzzydate)) { bzero((char*) ltime,sizeof(*ltime)); - return (null_value= 1); + return true; } - return (null_value= 0); + return false; } @@ -8238,7 +8239,7 @@ bool Item_ref::val_native(THD *thd, Native *to) longlong Item_ref::val_datetime_packed(THD *thd) { DBUG_ASSERT(fixed); - longlong tmp= (*ref)->val_datetime_packed(thd); + longlong tmp= (*ref)->val_datetime_packed_result(thd); null_value= (*ref)->null_value; return tmp; } @@ -8247,7 +8248,7 @@ longlong Item_ref::val_datetime_packed(THD *thd) longlong Item_ref::val_time_packed(THD *thd) { DBUG_ASSERT(fixed); - longlong tmp= (*ref)->val_time_packed(thd); + longlong tmp= (*ref)->val_time_packed_result(thd); null_value= (*ref)->null_value; return tmp; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index a36bf4c140b..052ac173747 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1094,19 +1094,6 @@ void Aggregator_distinct::endup() String * -Item_sum_num::val_str(String *str) -{ - return val_string_from_real(str); -} - - -my_decimal *Item_sum_num::val_decimal(my_decimal *decimal_value) -{ - return val_decimal_from_real(decimal_value); -} - - -String * Item_sum_int::val_str(String *str) { return val_string_from_int(str); @@ -2185,7 +2172,7 @@ double Stddev::result(bool is_sample_variance) Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item): - Item_sum_num(thd, item), + Item_sum_double(thd, item), m_stddev(item->m_stddev), sample(item->sample), prec_increment(item->prec_increment) { } @@ -2309,13 +2296,6 @@ double Item_sum_variance::val_real() } -my_decimal *Item_sum_variance::val_decimal(my_decimal *dec_buf) -{ - DBUG_ASSERT(fixed == 1); - return val_decimal_from_real(dec_buf); -} - - void Item_sum_variance::reset_field() { double nr; diff --git a/sql/item_sum.h b/sql/item_sum.h index c18454f1506..7fccc4e24aa 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -588,6 +588,7 @@ public: virtual void setup_caches(THD *thd) {}; bool with_sum_func() const { return true; } + virtual void set_partition_row_count(ulonglong count) { DBUG_ASSERT(0); } }; @@ -734,13 +735,33 @@ public: Item_sum_num(THD *thd, Item_sum_num *item): Item_sum(thd, item) {} bool fix_fields(THD *, Item **); - longlong val_int() { return val_int_from_real(); /* Real as default */ } - String *val_str(String*str); - my_decimal *val_decimal(my_decimal *); +}; + + +class Item_sum_double :public Item_sum_num +{ +public: + Item_sum_double(THD *thd): Item_sum_num(thd) {} + Item_sum_double(THD *thd, Item *item_par): Item_sum_num(thd, item_par) {} + Item_sum_double(THD *thd, List<Item> &list): Item_sum_num(thd, list) {} + Item_sum_double(THD *thd, Item_sum_double *item) :Item_sum_num(thd, item) {} + longlong val_int() + { + return val_int_from_real(); + } + String *val_str(String*str) + { + return val_string_from_real(str); + } + my_decimal *val_decimal(my_decimal *to) + { + return val_decimal_from_real(to); + } bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) { - return type_handler()->Item_get_date_with_warn(thd, this, ltime, fuzzydate); + return get_date_from_real(thd, ltime, fuzzydate); } + const Type_handler *type_handler() const { return &type_handler_double; } }; @@ -754,6 +775,10 @@ public: double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); my_decimal *val_decimal(my_decimal *); + bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) + { + return get_date_from_int(thd, ltime, fuzzydate); + } bool fix_length_and_dec() { decimals=0; max_length=21; maybe_null=null_value=0; return FALSE; } }; @@ -794,6 +819,10 @@ public: longlong val_int(); String *val_str(String*str); my_decimal *val_decimal(my_decimal *); + bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) + { + return type_handler()->Item_get_date_with_warn(thd, this, ltime, fuzzydate); + } const Type_handler *type_handler() const { return Type_handler_hybrid_field_type::type_handler(); } void fix_length_and_dec_double(); @@ -986,7 +1015,7 @@ public: -class Item_sum_variance : public Item_sum_num +class Item_sum_variance : public Item_sum_double { Stddev m_stddev; bool fix_length_and_dec(); @@ -996,7 +1025,7 @@ public: uint prec_increment; Item_sum_variance(THD *thd, Item *item_par, uint sample_arg): - Item_sum_num(thd, item_par), + Item_sum_double(thd, item_par), sample(sample_arg) {} Item_sum_variance(THD *thd, Item_sum_variance *item); @@ -1006,7 +1035,6 @@ public: void clear(); bool add(); double val_real(); - my_decimal *val_decimal(my_decimal *); void reset_field(); void update_field(); Item *result_item(THD *thd, Field *field); @@ -1015,11 +1043,10 @@ public: { return sample ? "var_samp(" : "variance("; } Item *copy_or_same(THD* thd); Field *create_tmp_field(MEM_ROOT *root, bool group, TABLE *table); - const Type_handler *type_handler() const { return &type_handler_double; } void cleanup() { m_stddev= Stddev(); - Item_sum_num::cleanup(); + Item_sum_double::cleanup(); } Item *get_copy(THD *thd) { return get_item_copy<Item_sum_variance>(thd, this); } @@ -1732,15 +1759,15 @@ public: #else /* Dummy functions to get sql_yacc.cc compiled */ -class Item_sum_udf_float :public Item_sum_num +class Item_sum_udf_float :public Item_sum_double { public: Item_sum_udf_float(THD *thd, udf_func *udf_arg): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_float(THD *thd, udf_func *udf_arg, List<Item> &list): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) - :Item_sum_num(thd, item) {} + :Item_sum_double(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } void clear() {} @@ -1750,15 +1777,15 @@ class Item_sum_udf_float :public Item_sum_num }; -class Item_sum_udf_int :public Item_sum_num +class Item_sum_udf_int :public Item_sum_double { public: Item_sum_udf_int(THD *thd, udf_func *udf_arg): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_int(THD *thd, udf_func *udf_arg, List<Item> &list): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) - :Item_sum_num(thd, item) {} + :Item_sum_double(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } double val_real() { DBUG_ASSERT(fixed == 1); return 0; } @@ -1769,15 +1796,15 @@ public: }; -class Item_sum_udf_decimal :public Item_sum_num +class Item_sum_udf_decimal :public Item_sum_double { public: Item_sum_udf_decimal(THD *thd, udf_func *udf_arg): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_decimal(THD *thd, udf_func *udf_arg, List<Item> &list): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_decimal(THD *thd, Item_sum_udf_float *item) - :Item_sum_num(thd, item) {} + :Item_sum_double(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; } @@ -1788,15 +1815,15 @@ class Item_sum_udf_decimal :public Item_sum_num }; -class Item_sum_udf_str :public Item_sum_num +class Item_sum_udf_str :public Item_sum_double { public: Item_sum_udf_str(THD *thd, udf_func *udf_arg): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_str(THD *thd, udf_func *udf_arg, List<Item> &list): - Item_sum_num(thd) {} + Item_sum_double(thd) {} Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) - :Item_sum_num(thd, item) {} + :Item_sum_double(thd, item) {} String *val_str(String *) { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 8639edf2944..c73db2f7ed1 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1101,9 +1101,10 @@ longlong Item_func_weekday::val_int() { DBUG_ASSERT(fixed == 1); THD *thd= current_thd; - Datetime d(thd, args[0], Datetime::Options(TIME_NO_ZEROS, thd)); - return ((null_value= !d.is_valid_datetime())) ? 0 : - calc_weekday(d.daynr(), odbc_type) + MY_TEST(odbc_type); + Datetime dt(thd, args[0], Datetime::Options(TIME_NO_ZEROS, thd)); + if ((null_value= !dt.is_valid_datetime())) + return 0; + return dt.weekday(odbc_type) + MY_TEST(odbc_type); } bool Item_func_dayname::fix_length_and_dec() @@ -1122,14 +1123,15 @@ bool Item_func_dayname::fix_length_and_dec() String* Item_func_dayname::val_str(String* str) { DBUG_ASSERT(fixed == 1); - uint weekday=(uint) val_int(); // Always Item_func_weekday() const char *day_name; uint err; + THD *thd= current_thd; + Datetime dt(thd, args[0], Datetime::Options(TIME_NO_ZEROS, thd)); - if (null_value) + if ((null_value= !dt.is_valid_datetime())) return (String*) 0; - - day_name= locale->day_names->type_names[weekday]; + + day_name= locale->day_names->type_names[dt.weekday(false)]; str->copy(day_name, (uint) strlen(day_name), &my_charset_utf8mb3_bin, collation.collation, &err); return str; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 97e9c2ac59b..4d6210e6179 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -166,32 +166,13 @@ public: }; -class Item_func_month :public Item_func +class Item_func_month :public Item_long_func { public: - Item_func_month(THD *thd, Item *a): Item_func(thd, a) - { collation= DTCollation_numeric(); } + Item_func_month(THD *thd, Item *a): Item_long_func(thd, a) + { } longlong val_int(); - double val_real() - { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); } - String *val_str(String *str) - { - longlong nr= val_int(); - if (null_value) - return 0; - str->set(nr, collation.collation); - return str; - } - my_decimal *val_decimal(my_decimal *decimal_value) - { - return val_decimal_from_int(decimal_value); - } - bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) - { - return get_date_from_int(thd, ltime, fuzzydate); - } const char *func_name() const { return "month"; } - const Type_handler *type_handler() const { return &type_handler_slong; } bool fix_length_and_dec() { decimals= 0; @@ -441,24 +422,13 @@ public: }; -class Item_func_weekday :public Item_func +class Item_func_weekday :public Item_long_func { bool odbc_type; public: Item_func_weekday(THD *thd, Item *a, bool type_arg): - Item_func(thd, a), odbc_type(type_arg) { collation= DTCollation_numeric(); } + Item_long_func(thd, a), odbc_type(type_arg) { } longlong val_int(); - double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } - String *val_str(String *str) - { - DBUG_ASSERT(fixed == 1); - str->set(val_int(), &my_charset_bin); - return null_value ? 0 : str; - } - my_decimal *val_decimal(my_decimal *decimal_value) - { - return val_decimal_from_int(decimal_value); - } const char *func_name() const { return (odbc_type ? "dayofweek" : "weekday"); @@ -467,7 +437,6 @@ public: { return type_handler()->Item_get_date_with_warn(thd, this, ltime, fuzzydate); } - const Type_handler *type_handler() const { return &type_handler_slong; } bool fix_length_and_dec() { decimals= 0; @@ -485,11 +454,11 @@ public: { return get_item_copy<Item_func_weekday>(thd, this); } }; -class Item_func_dayname :public Item_func_weekday +class Item_func_dayname :public Item_str_func { MY_LOCALE *locale; public: - Item_func_dayname(THD *thd, Item *a): Item_func_weekday(thd, a, 0) {} + Item_func_dayname(THD *thd, Item *a): Item_str_func(thd, a) {} const char *func_name() const { return "dayname"; } String *val_str(String *str); const Type_handler *type_handler() const { return &type_handler_varchar; } @@ -499,6 +468,12 @@ class Item_func_dayname :public Item_func_weekday { return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC); } + bool check_valid_arguments_processor(void *int_arg) + { + return !has_date_args(); + } + Item *get_copy(THD *thd) + { return get_item_copy<Item_func_dayname>(thd, this); } }; diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index 8b53b2012e7..f38209e4bb5 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2016,2017 MariaDB + Copyright (c) 2016,2019 MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -445,28 +445,38 @@ class Item_sum_lag : public Item_sum_hybrid_simple { return get_item_copy<Item_sum_lag>(thd, this); } }; -/* - A base window function (aggregate) that also holds a counter for the number - of rows. -*/ -class Item_sum_window_with_row_count : public Item_sum_num -{ - public: - Item_sum_window_with_row_count(THD *thd) : Item_sum_num(thd), - partition_row_count_(0) {} - - Item_sum_window_with_row_count(THD *thd, Item *arg) : - Item_sum_num(thd, arg), partition_row_count_(0) {}; - - void set_row_count(ulonglong count) { partition_row_count_ = count; } - void reset_field() { DBUG_ASSERT(0); } - protected: +class Partition_row_count +{ +public: + Partition_row_count() :partition_row_count_(0) { } + void set_partition_row_count(ulonglong count) + { + partition_row_count_ = count; + } + double calc_val_real(bool *null_value, + ulonglong current_row_count) + { + if ((*null_value= (partition_row_count_ == 0))) + return 0; + return static_cast<double>(current_row_count) / partition_row_count_; + } +protected: longlong get_row_count() { return partition_row_count_; } - private: ulonglong partition_row_count_; }; + +class Current_row_count +{ +public: + Current_row_count() :current_row_count_(0) { } +protected: + ulonglong get_row_number() { return current_row_count_ ; } + ulonglong current_row_count_; +}; + + /* @detail "The relative rank of a row R is defined as (RK-1)/(NR-1), where RK is @@ -478,11 +488,12 @@ class Item_sum_window_with_row_count : public Item_sum_num This is held within the row_count context. - Second pass to compute rank of current row and the value of the function */ -class Item_sum_percent_rank: public Item_sum_window_with_row_count +class Item_sum_percent_rank: public Item_sum_double, + public Partition_row_count { public: Item_sum_percent_rank(THD *thd) - : Item_sum_window_with_row_count(thd), cur_rank(1), peer_tracker(NULL) {} + : Item_sum_double(thd), cur_rank(1), peer_tracker(NULL) {} longlong val_int() { @@ -535,6 +546,14 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count } void setup_window_func(THD *thd, Window_spec *window_spec); + + void reset_field() { DBUG_ASSERT(0); } + + void set_partition_row_count(ulonglong count) + { + Partition_row_count::set_partition_row_count(count); + } + Item *get_copy(THD *thd) { return get_item_copy<Item_sum_percent_rank>(thd, this); } @@ -569,25 +588,17 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count two passes. */ -class Item_sum_cume_dist: public Item_sum_window_with_row_count +class Item_sum_cume_dist: public Item_sum_double, + public Partition_row_count, + public Current_row_count { public: - Item_sum_cume_dist(THD *thd) : Item_sum_window_with_row_count(thd), - current_row_count_(0) {} - - Item_sum_cume_dist(THD *thd, Item *arg) : Item_sum_window_with_row_count(thd,arg), - current_row_count_(0) {} + Item_sum_cume_dist(THD *thd) :Item_sum_double(thd) { } + Item_sum_cume_dist(THD *thd, Item *arg) :Item_sum_double(thd, arg) { } double val_real() { - if (get_row_count() == 0) - { - null_value= true; - return 0; - } - ulonglong partition_row_count= get_row_count(); - null_value= false; - return static_cast<double>(current_row_count_) / partition_row_count; + return calc_val_real(&null_value, current_row_count_); } bool add() @@ -604,7 +615,7 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count void clear() { current_row_count_= 0; - set_row_count(0); + partition_row_count_= 0; } const char*func_name() const @@ -622,29 +633,26 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count return FALSE; } - Item *get_copy(THD *thd) - { return get_item_copy<Item_sum_cume_dist>(thd, this); } + void reset_field() { DBUG_ASSERT(0); } - ulonglong get_row_number() + void set_partition_row_count(ulonglong count) { - return current_row_count_ ; + Partition_row_count::set_partition_row_count(count); } - private: - ulonglong current_row_count_; + Item *get_copy(THD *thd) + { return get_item_copy<Item_sum_cume_dist>(thd, this); } + }; -class Item_sum_ntile : public Item_sum_window_with_row_count +class Item_sum_ntile : public Item_sum_int, + public Partition_row_count, + public Current_row_count { public: Item_sum_ntile(THD* thd, Item* num_quantiles_expr) : - Item_sum_window_with_row_count(thd, num_quantiles_expr), - current_row_count_(0) {}; - - double val_real() - { - return (double) val_int(); - } + Item_sum_int(thd, num_quantiles_expr) + { } longlong val_int() { @@ -685,7 +693,7 @@ class Item_sum_ntile : public Item_sum_window_with_row_count void clear() { current_row_count_= 0; - set_row_count(0); + partition_row_count_= 0; } const char*func_name() const @@ -696,20 +704,28 @@ class Item_sum_ntile : public Item_sum_window_with_row_count void update_field() {} const Type_handler *type_handler() const { return &type_handler_slonglong; } - + + void reset_field() { DBUG_ASSERT(0); } + + void set_partition_row_count(ulonglong count) + { + Partition_row_count::set_partition_row_count(count); + } + Item *get_copy(THD *thd) { return get_item_copy<Item_sum_ntile>(thd, this); } private: longlong get_num_quantiles() { return args[0]->val_int(); } - ulong current_row_count_; }; -class Item_sum_percentile_disc : public Item_sum_cume_dist, - public Type_handler_hybrid_field_type +class Item_sum_percentile_disc : public Item_sum_num, + public Type_handler_hybrid_field_type, + public Partition_row_count, + public Current_row_count { public: - Item_sum_percentile_disc(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg), + Item_sum_percentile_disc(THD *thd, Item* arg) : Item_sum_num(thd, arg), Type_handler_hybrid_field_type(&type_handler_slonglong), value(NULL), val_calculated(FALSE), first_call(TRUE), prev_value(0), order_item(NULL){} @@ -758,6 +774,17 @@ public: return value->val_str(str); } + bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) + { + if (get_row_count() == 0 || get_arg(0)->is_null()) + { + null_value= true; + return 0; + } + null_value= false; + return value->get_date(thd, ltime, fuzzydate); + } + bool add() { Item *arg= get_arg(0); @@ -791,8 +818,8 @@ public: if (value->null_value) return false; - Item_sum_cume_dist::add(); - double val= Item_sum_cume_dist::val_real(); + current_row_count_++; + double val= calc_val_real(&null_value, current_row_count_); if (val >= prev_value && !val_calculated) val_calculated= true; @@ -809,7 +836,8 @@ public: val_calculated= false; first_call= true; value->clear(); - Item_sum_cume_dist::clear(); + partition_row_count_= 0; + current_row_count_= 0; } const char*func_name() const @@ -818,7 +846,6 @@ public: } void update_field() {} - void set_type_handler(Window_spec *window_spec); const Type_handler *type_handler() const {return Type_handler_hybrid_field_type::type_handler();} @@ -829,6 +856,13 @@ public: return FALSE; } + void reset_field() { DBUG_ASSERT(0); } + + void set_partition_row_count(ulonglong count) + { + Partition_row_count::set_partition_row_count(count); + } + Item *get_copy(THD *thd) { return get_item_copy<Item_sum_percentile_disc>(thd, this); } void setup_window_func(THD *thd, Window_spec *window_spec); @@ -843,12 +877,12 @@ private: Item *order_item; }; -class Item_sum_percentile_cont : public Item_sum_cume_dist, - public Type_handler_hybrid_field_type +class Item_sum_percentile_cont : public Item_sum_double, + public Partition_row_count, + public Current_row_count { public: - Item_sum_percentile_cont(THD *thd, Item* arg) : Item_sum_cume_dist(thd, arg), - Type_handler_hybrid_field_type(&type_handler_double), + Item_sum_percentile_cont(THD *thd, Item* arg) : Item_sum_double(thd, arg), floor_value(NULL), ceil_value(NULL), first_call(TRUE),prev_value(0), ceil_val_calculated(FALSE), floor_val_calculated(FALSE), order_item(NULL){} @@ -918,7 +952,7 @@ public: return false; } - Item_sum_cume_dist::add(); + current_row_count_++; double val= 1 + prev_value * (get_row_count()-1); if (!floor_val_calculated && get_row_number() == floor(val)) @@ -941,7 +975,8 @@ public: ceil_value->clear(); floor_val_calculated= false; ceil_val_calculated= false; - Item_sum_cume_dist::clear(); + partition_row_count_= 0; + current_row_count_= 0; } const char*func_name() const @@ -949,9 +984,6 @@ public: return "percentile_cont"; } void update_field() {} - void set_type_handler(Window_spec *window_spec); - const Type_handler *type_handler() const - {return Type_handler_hybrid_field_type::type_handler();} bool fix_length_and_dec() { @@ -960,6 +992,13 @@ public: return FALSE; } + void reset_field() { DBUG_ASSERT(0); } + + void set_partition_row_count(ulonglong count) + { + Partition_row_count::set_partition_row_count(count); + } + Item *get_copy(THD *thd) { return get_item_copy<Item_sum_percentile_cont>(thd, this); } void setup_window_func(THD *thd, Window_spec *window_spec); diff --git a/sql/sql_audit.h b/sql/sql_audit.h index 59cced13b0a..97317203e34 100644 --- a/sql/sql_audit.h +++ b/sql/sql_audit.h @@ -284,7 +284,9 @@ void mysql_audit_notify_connection_change_user(THD *thd) } static inline -void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock) +void mysql_audit_external_lock_ex(THD *thd, my_thread_id thread_id, + const char *user, const char *host, const char *ip, query_id_t query_id, + TABLE_SHARE *share, int lock) { if (lock != F_UNLCK && mysql_audit_table_enabled()) { @@ -293,25 +295,33 @@ void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock) event.event_subclass= MYSQL_AUDIT_TABLE_LOCK; event.read_only= lock == F_RDLCK; - event.thread_id= (unsigned long)thd->thread_id; - event.user= sctx->user; + event.thread_id= (unsigned long)thread_id; + event.user= user; event.priv_user= sctx->priv_user; event.priv_host= sctx->priv_host; event.external_user= sctx->external_user; event.proxy_user= sctx->proxy_user; - event.host= sctx->host; - event.ip= sctx->ip; + event.host= host; + event.ip= ip; event.database= share->db; event.table= share->table_name; event.new_database= null_clex_str; event.new_table= null_clex_str; - event.query_id= thd->query_id; + event.query_id= query_id; mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event); } } static inline +void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock) +{ + mysql_audit_external_lock_ex(thd, thd->thread_id, thd->security_ctx->user, + thd->security_ctx->host, thd->security_ctx->ip, thd->query_id, + share, lock); +} + +static inline void mysql_audit_create_table(TABLE *table) { if (mysql_audit_table_enabled()) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0f267fff17b..60b60ec1e54 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2203,36 +2203,16 @@ public: passed from connection thread to the handler thread. */ MDL_request grl_protection; - my_thread_id orig_thread_id; - void set_default_user() - { - thd.security_ctx->user=(char*) delayed_user; - thd.security_ctx->host=(char*) my_localhost; - thd.security_ctx->ip= NULL; - thd.query_id= 0; - thd.thread_id= orig_thread_id; - } - - void set_user_from_row(const delayed_row *r) - { - if (r) - { - thd.security_ctx->user= r->user; - thd.security_ctx->host= r->host; - thd.security_ctx->ip= r->ip; - thd.query_id= r->query_id; - thd.thread_id= r->thread_id; - } - } - Delayed_insert(SELECT_LEX *current_select) :locks_in_memory(0), thd(next_thread_id()), table(0),tables_in_use(0), stacked_inserts(0), status(0), retry(0), handler_thread_initialized(FALSE), group_count(0) { DBUG_ENTER("Delayed_insert constructor"); - orig_thread_id= thd.thread_id; - set_default_user(); + thd.security_ctx->user=(char*) delayed_user; + thd.security_ctx->host=(char*) my_localhost; + thd.security_ctx->ip= NULL; + thd.query_id= 0; strmake_buf(thd.security_ctx->priv_user, thd.security_ctx->user); thd.current_tablenr=0; thd.set_command(COM_DELAYED_INSERT); @@ -3218,7 +3198,6 @@ pthread_handler_t handle_delayed_insert(void *arg) if (di->tables_in_use && ! thd->lock && (!thd->killed || di->stacked_inserts)) { - di->set_user_from_row(di->rows.head()); /* Request for new delayed insert. Lock the table, but avoid to be blocked by a global read lock. @@ -3240,16 +3219,18 @@ pthread_handler_t handle_delayed_insert(void *arg) { delayed_row *row; I_List_iterator<delayed_row> it(di->rows); + my_thread_id cur_thd= di->thd.thread_id; + while ((row= it++)) { - if (di->thd.thread_id != row->thread_id) + if (cur_thd != row->thread_id) { - di->set_user_from_row(row); - mysql_audit_external_lock(&di->thd, di->table->s, F_WRLCK); + mysql_audit_external_lock_ex(&di->thd, row->thread_id, + row->user, row->host, row->ip, row->query_id, + di->table->s, F_WRLCK); + cur_thd= row->thread_id; } } - di->set_default_user(); - if (di->handle_inserts()) { /* Some fatal error */ diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 3afcce6e3bd..308bebd9fa1 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1713,28 +1713,6 @@ public: uint sroutines_list_own_elements; /** - Locking state of tables in this particular statement. - - If we under LOCK TABLES or in prelocked mode we consider tables - for the statement to be "locked" if there was a call to lock_tables() - (which called handler::start_stmt()) for tables of this statement - and there was no matching close_thread_tables() call. - - As result this state may differ significantly from one represented - by Open_tables_state::lock/locked_tables_mode more, which are always - "on" under LOCK TABLES or in prelocked mode. - */ - enum enum_lock_tables_state { - LTS_NOT_LOCKED = 0, - LTS_LOCKED - }; - enum_lock_tables_state lock_tables_state; - bool is_query_tables_locked() - { - return (lock_tables_state == LTS_LOCKED); - } - - /** Number of tables which were open by open_tables() and to be locked by lock_tables(). Note that we set this member only in some cases, when this value diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3619c603697..bece1f9bee2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2128,6 +2128,7 @@ JOIN::optimize_inner() zero_result_cause= "Zero limit"; } table_count= top_join_tab_count= 0; + handle_implicit_grouping_with_window_funcs(); error= 0; subq_exit_fl= true; goto setup_subq_exit; @@ -2175,6 +2176,7 @@ JOIN::optimize_inner() table_count= top_join_tab_count= 0; error=0; subq_exit_fl= true; + handle_implicit_grouping_with_window_funcs(); goto setup_subq_exit; } if (res > 1) @@ -2190,6 +2192,7 @@ JOIN::optimize_inner() tables_list= 0; // All tables resolved select_lex->min_max_opt_list.empty(); const_tables= top_join_tab_count= table_count; + handle_implicit_grouping_with_window_funcs(); /* Extract all table-independent conditions and replace the WHERE clause with them. All other conditions were computed by opt_sum_query @@ -2338,6 +2341,7 @@ int JOIN::optimize_stage2() zero_result_cause= "no matching row in const table"; DBUG_PRINT("error",("Error: %s", zero_result_cause)); error= 0; + handle_implicit_grouping_with_window_funcs(); goto setup_subq_exit; } if (!(thd->variables.option_bits & OPTION_BIG_SELECTS) && @@ -2369,6 +2373,7 @@ int JOIN::optimize_stage2() zero_result_cause= "Impossible WHERE noticed after reading const tables"; select_lex->mark_const_derived(zero_result_cause); + handle_implicit_grouping_with_window_funcs(); goto setup_subq_exit; } @@ -2531,6 +2536,7 @@ int JOIN::optimize_stage2() zero_result_cause= "Impossible WHERE noticed after reading const tables"; select_lex->mark_const_derived(zero_result_cause); + handle_implicit_grouping_with_window_funcs(); goto setup_subq_exit; } @@ -15746,7 +15752,7 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab, } } else if (cond->type() == Item::FUNC_ITEM && - ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC) + ((Item_func*) cond)->functype() == Item_func::MULT_EQUAL_FUNC) { item_equal= (Item_equal *) cond; item_equal->sort(&compare_fields_by_table_order, table_join_idx); @@ -19722,7 +19728,8 @@ void set_postjoin_aggr_write_func(JOIN_TAB *tab) } } else if (join->sort_and_group && !tmp_tbl->precomputed_group_by && - !join->sort_and_group_aggr_tab && join->tables_list) + !join->sort_and_group_aggr_tab && join->tables_list && + join->top_join_tab_count) { DBUG_PRINT("info",("Using end_write_group")); aggr->set_write_func(end_write_group); @@ -25154,7 +25161,8 @@ change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array, for (uint i= 0; (item= it++); i++) { Field *field; - if (item->with_sum_func() && item->type() != Item::SUM_FUNC_ITEM) + if ((item->with_sum_func() && item->type() != Item::SUM_FUNC_ITEM) || + item->with_window_func) item_field= item; else if (item->type() == Item::FIELD_ITEM) { @@ -28696,6 +28704,28 @@ Item *remove_pushed_top_conjuncts(THD *thd, Item *cond) } +/* + There are 5 cases in which we shortcut the join optimization process as we + conclude that the join would be a degenerate one + 1) IMPOSSIBLE WHERE + 2) MIN/MAX optimization (@see opt_sum_query) + 3) EMPTY CONST TABLE + If a window function is present in any of the above cases then to get the + result of the window function, we need to execute it. So we need to + create a temporary table for its execution. Here we need to take in mind + that aggregate functions and non-aggregate function need not be executed. + +*/ + +void JOIN::handle_implicit_grouping_with_window_funcs() +{ + if (select_lex->have_window_funcs() && send_row_on_empty_set()) + { + const_tables= top_join_tab_count= table_count= 0; + } +} + + /** @brief Look for provision of the select_handler interface by a foreign engine diff --git a/sql/sql_select.h b/sql/sql_select.h index d440d79fbf5..e3501fb98c6 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1127,6 +1127,7 @@ protected: Join_plan_state *save_to); /* Choose a subquery plan for a table-less subquery. */ bool choose_tableless_subquery_plan(); + void handle_implicit_grouping_with_window_funcs(); public: void save_query_plan(Join_plan_state *save_to); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 9ba31a0ff83..e3514d286ef 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6795,23 +6795,35 @@ static int get_check_constraints_record(THD *thd, TABLE_LIST *tables, thd->clear_error(); DBUG_RETURN(0); } - else if (!tables->view) + if (!tables->view) { - if (tables->table->s->table_check_constraints) + StringBuffer<MAX_FIELD_WIDTH> str(system_charset_info); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + TABLE_LIST table_acl_check; + bzero((char*) &table_acl_check, sizeof(table_acl_check)); +#endif + for (uint i= 0; i < tables->table->s->table_check_constraints; i++) { - for (uint i= 0; i < tables->table->s->table_check_constraints; i++) +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (!(thd->col_access & TABLE_ACLS)) { - StringBuffer<MAX_FIELD_WIDTH> str(system_charset_info); - Virtual_column_info *check= tables->table->check_constraints[i]; - restore_record(table, s->default_values); - table->field[0]->store(STRING_WITH_LEN("def"), system_charset_info); - table->field[1]->store(db_name->str, db_name->length, system_charset_info); - table->field[2]->store(check->name.str, check->name.length, system_charset_info); - table->field[3]->store(table_name->str, table_name->length, system_charset_info); - check->print(&str); - table->field[4]->store(str.ptr(), str.length(), system_charset_info); - schema_table_store_record(thd, table); + table_acl_check.db= *db_name; + table_acl_check.table_name= *table_name; + table_acl_check.grant.privilege= thd->col_access; + if (check_grant(thd, TABLE_ACLS, &table_acl_check, FALSE, 1, TRUE)) + continue; } +#endif + Virtual_column_info *check= tables->table->check_constraints[i]; + table->field[0]->store(STRING_WITH_LEN("def"), system_charset_info); + table->field[3]->store(check->name.str, check->name.length, + system_charset_info); + /* Make sure the string is empty between each print. */ + str.length(0); + check->print(&str); + table->field[4]->store(str.ptr(), str.length(), system_charset_info); + if (schema_table_store_record(thd, table)) + DBUG_RETURN(1); } } DBUG_RETURN(res); @@ -9370,8 +9382,8 @@ ST_FIELD_INFO check_constraints_fields_info[]= { Column("CONSTRAINT_CATALOG", Catalog(), NOT_NULL, OPEN_FULL_TABLE), Column("CONSTRAINT_SCHEMA", Name(), NOT_NULL, OPEN_FULL_TABLE), - Column("CONSTRAINT_NAME", Name(), NOT_NULL, OPEN_FULL_TABLE), Column("TABLE_NAME", Name(), NOT_NULL, OPEN_FULL_TABLE), + Column("CONSTRAINT_NAME", Name(), NOT_NULL, OPEN_FULL_TABLE), Column("CHECK_CLAUSE", Name(), NOT_NULL, OPEN_FULL_TABLE), CEnd() }; @@ -9402,7 +9414,8 @@ ST_SCHEMA_TABLE schema_tables[]= {"CHARACTER_SETS", Show::charsets_fields_info, 0, fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0}, {"CHECK_CONSTRAINTS", Show::check_constraints_fields_info, 0, - get_all_tables, 0, get_check_constraints_record, 1, 2, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, + get_all_tables, 0, + get_check_constraints_record, 1, 2, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, {"COLLATIONS", Show::collation_fields_info, 0, fill_schema_collation, make_old_format, 0, -1, -1, 0, 0}, {"COLLATION_CHARACTER_SET_APPLICABILITY", Show::coll_charset_app_fields_info, diff --git a/sql/sql_type.h b/sql/sql_type.h index 3943a3f761f..749dc339f98 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -1887,6 +1887,10 @@ protected: { return (ulong) ::calc_daynr((uint) year, (uint) month, (uint) day); } + int weekday(bool sunday_first_day_of_week) const + { + return ::calc_weekday(daynr(), sunday_first_day_of_week); + } ulong dayofyear() const { return (ulong) (daynr() - ::calc_daynr(year, 1, 1) + 1); @@ -2267,6 +2271,11 @@ public: DBUG_ASSERT(is_valid_datetime_slow()); return Temporal_with_date::daynr(); } + int weekday(bool sunday_first_day_of_week) const + { + DBUG_ASSERT(is_valid_datetime_slow()); + return Temporal_with_date::weekday(sunday_first_day_of_week); + } ulong dayofyear() const { DBUG_ASSERT(is_valid_datetime_slow()); diff --git a/sql/sql_window.cc b/sql/sql_window.cc index a6c9dd3fea7..7e319c96000 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -1779,11 +1779,7 @@ protected: List_iterator_fast<Item_sum> it(sum_functions); Item_sum* item; while ((item= it++)) - { - Item_sum_window_with_row_count* item_with_row_count = - static_cast<Item_sum_window_with_row_count *>(item); - item_with_row_count->set_row_count(num_rows_in_partition); - } + item->set_partition_row_count(num_rows_in_partition); } }; diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc index 768dbab4e6b..e11a0613425 100644 --- a/sql/threadpool_generic.cc +++ b/sql/threadpool_generic.cc @@ -1237,7 +1237,7 @@ void wait_begin(thread_group_t *thread_group) DBUG_ASSERT(thread_group->connection_count > 0); if ((thread_group->active_thread_count == 0) && - (is_queue_empty(thread_group) || !thread_group->listener)) + (!is_queue_empty(thread_group) || !thread_group->listener)) { /* Group might stall while this thread waits, thus wake diff --git a/sql/tztime.cc b/sql/tztime.cc index afbe7639dda..fbac2923a84 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2432,7 +2432,7 @@ print_tz_leaps_as_sql(const TIME_ZONE_INFO *sp) if (!opt_skip_write_binlog) printf("\\d |\n" "IF (select count(*) from information_schema.global_variables where\n" - "variable_name='wsrep_on') = 1 THEN\n" + "variable_name='wsrep_on' and variable_value='ON') = 1 THEN\n" "ALTER TABLE time_zone_leap_second ENGINE=InnoDB;\n" "END IF|\n" "\\d ;\n"); @@ -2452,7 +2452,7 @@ print_tz_leaps_as_sql(const TIME_ZONE_INFO *sp) if (!opt_skip_write_binlog) printf("\\d |\n" "IF (select count(*) from information_schema.global_variables where\n" - "variable_name='wsrep_on') = 1 THEN\n" + "variable_name='wsrep_on' and variable_value='ON') = 1 THEN\n" "ALTER TABLE time_zone_leap_second ENGINE=Aria;\n" "END IF|\n" "\\d ;\n"); @@ -2708,7 +2708,7 @@ main(int argc, char **argv) sql_log_bin and wsrep_on to avoid Galera replicating below truncate table clauses. This will allow user to set different time zones to nodes in Galera cluster. */ - printf("set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?');\n" + printf("set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on' and variable_value='ON'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?');\n" "prepare set_wsrep_write_binlog from @prep1;\n" "set @toggle=0; execute set_wsrep_write_binlog using @toggle;\n"); @@ -2724,7 +2724,7 @@ main(int argc, char **argv) // to allow changes to them to replicate with Galera printf("\\d |\n" "IF (select count(*) from information_schema.global_variables where\n" - "variable_name='wsrep_on') = 1 THEN\n" + "variable_name='wsrep_on' and variable_value='ON') = 1 THEN\n" "ALTER TABLE time_zone ENGINE=InnoDB;\n" "ALTER TABLE time_zone_name ENGINE=InnoDB;\n" "ALTER TABLE time_zone_transition ENGINE=InnoDB;\n" @@ -2779,7 +2779,7 @@ main(int argc, char **argv) // Fall back to Aria printf("\\d |\n" "IF (select count(*) from information_schema.global_variables where\n" - "variable_name='wsrep_on') = 1 THEN\n" + "variable_name='wsrep_on' and variable_value='ON') = 1 THEN\n" "ALTER TABLE time_zone ENGINE=Aria;\n" "ALTER TABLE time_zone_name ENGINE=Aria;\n" "ALTER TABLE time_zone_transition ENGINE=Aria;\n" diff --git a/sql/unireg.cc b/sql/unireg.cc index 7130b3e5d8a..e4a43d3ace5 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -538,7 +538,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table, pos+= reclength; int2store(pos, create_info->connect_string.length); pos+= 2; - memcpy(pos, create_info->connect_string.str, create_info->connect_string.length); + if (create_info->connect_string.length) + memcpy(pos, create_info->connect_string.str, create_info->connect_string.length); pos+= create_info->connect_string.length; int2store(pos, str_db_type.length); pos+= 2; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 7345f2f7b9e..708c320c471 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2296,6 +2296,7 @@ int wsrep_wait_committing_connections_close(int wait_time) { int sleep_time= 100; + WSREP_DEBUG("wait for committing transaction to close: %d sleep: %d", wait_time, sleep_time); while (server_threads.iterate(have_committing_connections) && wait_time > 0) { WSREP_DEBUG("wait for committing transaction to close: %d", wait_time); |