diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 15643f29513..abc48783cf4 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -733,3 +733,10 @@ xxxxxxxxxxxxxxxxxxxaa xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxz drop table t1; +create table t1 (a int not null, b int not null, c int not null); +insert t1 values (1,1,1),(1,1,2),(1,2,1); +select a, b from t1 group by a, b order by sum(c); +a b +1 2 +1 1 +drop table t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 988c106bf21..dd36cd95969 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -500,3 +500,9 @@ insert into t1 set a = concat(repeat('x', 19), 'aa'); set max_sort_length=20; select a from t1 order by a; drop table t1; + +create table t1 (a int not null, b int not null, c int not null); +insert t1 values (1,1,1),(1,1,2),(1,2,1); +select a, b from t1 group by a, b order by sum(c); +drop table t1; + diff --git a/sql/protocol.cc b/sql/protocol.cc index 88be2710422..11a915ec151 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -131,36 +131,6 @@ void net_send_error(THD *thd, uint sql_errno, const char *err) DBUG_VOID_RETURN; } - -/* - Send a warning to the end user - - SYNOPSIS - send_warning() - thd Thread handler - sql_errno Warning number (error message) - err Error string. If not set, use ER(sql_errno) - - DESCRIPTION - Register the warning so that the user can get it with mysql_warnings() - Send an ok (+ warning count) to the end user. -*/ - -void send_warning(THD *thd, uint sql_errno, const char *err) -{ - DBUG_ENTER("send_warning"); - if (thd->spcont && - thd->spcont->find_handler(sql_errno, MYSQL_ERROR::WARN_LEVEL_WARN)) - { - DBUG_VOID_RETURN; - } - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, sql_errno, - err ? err : ER(sql_errno)); - send_ok(thd); - DBUG_VOID_RETURN; -} - - /* Write error package and flush to client It's a little too low level, but I don't want to use another buffer for diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ae2261e19f9..cc178a3121b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1754,7 +1754,8 @@ bool select_dumpvar::send_data(List &items) bool select_dumpvar::send_eof() { if (! row_count) - send_warning(thd, ER_SP_FETCH_NO_DATA); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA)); ::send_ok(thd,row_count); return 0; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index bfe9db2859d..785d5a329ba 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3648,9 +3648,10 @@ create_error: message in the error log, so we don't send it. */ if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread) - send_warning(thd,ER_WARNING_NOT_COMPLETE_ROLLBACK,0); - else - send_ok(thd); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARNING_NOT_COMPLETE_ROLLBACK, + ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)); + send_ok(thd); } else res= TRUE; @@ -3660,9 +3661,10 @@ create_error: if (!ha_rollback_to_savepoint(thd, lex->savepoint_name)) { if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread) - send_warning(thd, ER_WARNING_NOT_COMPLETE_ROLLBACK, 0); - else - send_ok(thd); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARNING_NOT_COMPLETE_ROLLBACK, + ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)); + send_ok(thd); } else goto error; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 93ed04be4b2..d31305c5dd2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -263,11 +263,13 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array, save_allow_sum_func= thd->allow_sum_func; thd->allow_sum_func= 0; - res= (setup_conds(thd, tables, leaves, conds) || - setup_order(thd, ref_pointer_array, tables, fields, all_fields, - order) || - setup_group(thd, ref_pointer_array, tables, fields, all_fields, - group, hidden_group_fields)); + res= setup_conds(thd, tables, leaves, conds); + thd->allow_sum_func= save_allow_sum_func; + res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, + order); + thd->allow_sum_func= 0; + res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields, + group, hidden_group_fields); thd->allow_sum_func= save_allow_sum_func; DBUG_RETURN(res); } @@ -11346,7 +11348,7 @@ int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, setup_group() thd Thread handler ref_pointer_array We store references to all fields that was not in - 'fields' here. + 'fields' here. fields All fields in the select part. Any item in 'order' that is part of these list is replaced by a pointer to this fields. diff --git a/strings/decimal.c b/strings/decimal.c index b8e8fd3725f..9b418dbe550 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -503,7 +503,7 @@ int decimal2ulonglong(decimal *from, ulonglong *to) { dec1 *buf=from->buf; ulonglong x=0; - int intg; + int intg, frac; if (from->sign) { @@ -515,14 +515,17 @@ int decimal2ulonglong(decimal *from, ulonglong *to) { ulonglong y=x; x=x*DIG_BASE + *buf++; - if (unlikely(x < y)) + if (unlikely(y > (ULONGLONG_MAX/DIG_BASE) || x < y)) { *to=y; return E_DEC_OVERFLOW; } } *to=x; - return from->frac ? E_DEC_TRUNCATED : E_DEC_OK; + for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1) + if (*buf++) + return E_DEC_TRUNCATED; + return E_DEC_OK; } int decimal2longlong(decimal *from, longlong *to) @@ -1928,6 +1931,7 @@ main() test_d2ull("18446744073709551616"); test_d2ull("-1"); test_d2ull("1.23"); + test_d2ull("9999999999999999999999999.000"); printf("==== longlong2decimal ====\n"); test_ll2d(LL(-12345));