summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/order_by.result7
-rw-r--r--mysql-test/t/order_by.test6
-rw-r--r--sql/protocol.cc30
-rw-r--r--sql/sql_class.cc3
-rw-r--r--sql/sql_parse.cc14
-rw-r--r--sql/sql_select.cc14
-rw-r--r--strings/decimal.c10
7 files changed, 38 insertions, 46 deletions
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<Item> &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));