3343 Martin Hansson 2011-02-18 [merge]
Merge of fix for Bug#11766675.
modified:
mysql-test/r/group_by.result
mysql-test/t/group_by.test
sql/sql_select.cc
3342 Alexander Barkov 2011-02-18
Bug#11765108 (Bug#58036) client utf32, utf16, ucs2 should be disallowed, they crash server
Problem: ucs2 was correctly disallowed in "SET NAMES" only,
while mysql_real_connect() and mysql_change_user() still allowed
to use ucs2, which made server crash.
Fix: disallow ucs2 in mysql_real_connect() and mysql_change_user().
@ sql/set_var.cc
Using new function.
@ sql/sql_acl.cc
- Return error if character set initialization failed
- Getting rid of pointer aliasing:
Initialize user_name to NULL, to avoid double free().
@ sql/sql_connect.cc
- in case of unsupported client character set send error and return true
- in case of success return false
@ sql/sql_connect.h
- changing return type for thd_init_client_charset() to bool,
to return errors to the caller
@ sql/sql_parse.h
- introducing a new function, to reuse in all places where we need
to check client character set.
@ tests/mysql_client_test.c
Adding test
modified:
sql/set_var.cc
sql/sql_acl.cc
sql/sql_connect.cc
sql/sql_connect.h
sql/sql_parse.h
tests/mysql_client_test.c
=== modified file 'mysql-test/r/group_by.result'
--- a/mysql-test/r/group_by.result 2010-12-17 11:11:34 +0000
+++ b/mysql-test/r/group_by.result 2011-02-18 10:55:24 +0000
@@ -1856,6 +1856,42 @@ ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1;
COUNT(*)
2
DROP TABLE t1;
+#
+# Bug#59839: Aggregation followed by subquery yields wrong result
+#
+CREATE TABLE t1 (
+a INT,
+b INT,
+c INT,
+KEY (a, b)
+);
+INSERT INTO t1 VALUES
+( 1, 1, 1 ),
+( 1, 2, 2 ),
+( 1, 3, 3 ),
+( 1, 4, 6 ),
+( 1, 5, 5 ),
+( 1, 9, 13 ),
+( 2, 1, 6 ),
+( 2, 2, 7 ),
+( 2, 3, 8 );
+EXPLAIN
+SELECT a, AVG(t1.b),
+(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
+(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
+FROM t1 GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 10 NULL 9 Using index
+3 DEPENDENT SUBQUERY t12 ref a a 10 func,func 2 Using where
+2 DEPENDENT SUBQUERY t11 ref a a 10 func,func 2 Using where
+SELECT a, AVG(t1.b),
+(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
+(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
+FROM t1 GROUP BY a;
+a AVG(t1.b) t11c t12c
+1 4.0000 6 6
+2 2.0000 7 7
+DROP TABLE t1;
# End of 5.1 tests
#
# Bug#49771: Incorrect MIN (date) when minimum value is 0000-00-00
=== modified file 'mysql-test/t/group_by.test'
--- a/mysql-test/t/group_by.test 2010-12-17 11:11:34 +0000
+++ b/mysql-test/t/group_by.test 2011-02-18 10:55:24 +0000
@@ -1248,6 +1248,43 @@ ON 1 WHERE t2.f1 > 1 GROUP BY t2.f1;
DROP TABLE t1;
+--echo #
+--echo # Bug#59839: Aggregation followed by subquery yields wrong result
+--echo #
+
+CREATE TABLE t1 (
+ a INT,
+ b INT,
+ c INT,
+ KEY (a, b)
+);
+
+INSERT INTO t1 VALUES
+ ( 1, 1, 1 ),
+ ( 1, 2, 2 ),
+ ( 1, 3, 3 ),
+ ( 1, 4, 6 ),
+ ( 1, 5, 5 ),
+ ( 1, 9, 13 ),
+
+ ( 2, 1, 6 ),
+ ( 2, 2, 7 ),
+ ( 2, 3, 8 );
+
+EXPLAIN
+SELECT a, AVG(t1.b),
+(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
+(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
+FROM t1 GROUP BY a;
+
+SELECT a, AVG(t1.b),
+(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
+(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
+FROM t1 GROUP BY a;
+
+DROP TABLE t1;
+
+
--echo # End of 5.1 tests
--echo #
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2011-02-08 15:47:33 +0000
+++ b/sql/sql_select.cc 2011-02-18 10:55:24 +0000
@@ -307,61 +307,65 @@ bool handle_select(THD *thd, LEX *lex, s
}
-/*
+/**
Fix fields referenced from inner selects.
- SYNOPSIS
- fix_inner_refs()
- thd Thread handle
- all_fields List of all fields used in select
- select Current select
- ref_pointer_array Array of references to Items used in current select
- group_list GROUP BY list (is NULL by default)
+ @param thd Thread handle
+ @param all_fields List of all fields used in select
+ @param select Current select
+ @param ref_pointer_array Array of references to Items used in current select
+ @param group_list GROUP BY list (is NULL by default)
- DESCRIPTION
- The function serves 3 purposes - adds fields referenced from inner
- selects to the current select list, resolves which class to use
- to access referenced item (Item_ref of Item_direct_ref) and fixes
- references (Item_ref objects) to these fields.
+ @details
+ The function serves 3 purposes
+
+ - adds fields referenced from inner query blocks to the current select list
+
+ - Decides which class to use to reference the items (Item_ref or
+ Item_direct_ref)
- If a field isn't already in the select list and the ref_pointer_array
+ - fixes references (Item_ref objects) to these fields.
+
+ If a field isn't already on the select list and the ref_pointer_array
is provided then it is added to the all_fields list and the pointer to
it is saved in the ref_pointer_array.
The class to access the outer field is determined by the following rules:
- 1. If the outer field isn't used under an aggregate function
- then the Item_ref class should be used.
- 2. If the outer field is used under an aggregate function and this
- function is aggregated in the select where the outer field was
- resolved or in some more inner select then the Item_direct_ref
- class should be used.
- Also it should be used if we are grouping by a subquery containing
- the outer field.
+
+ -#. If the outer field isn't used under an aggregate function then the
+ Item_ref class should be used.
+
+ -#. If the outer field is used under an aggregate function and this
+ function is, in turn, aggregated in the query block where the outer
+ field was resolved or some query nested therein, then the
+ Item_direct_ref class should be used. Also it should be used if we are
+ grouping by a subquery containing the outer field.
+
The resolution is done here and not at the fix_fields() stage as
- it can be done only after sum functions are fixed and pulled up to
- selects where they are have to be aggregated.
+ it can be done only after aggregate functions are fixed and pulled up to
+ selects where they are to be aggregated.
+
When the class is chosen it substitutes the original field in the
Item_outer_ref object.
After this we proceed with fixing references (Item_outer_ref objects) to
this field from inner subqueries.
- RETURN
- TRUE an error occured
- FALSE ok
-*/
+ @return Status
+ @retval true An error occured.
+ @retval false OK.
+ */
bool
fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
Item **ref_pointer_array, ORDER *group_list)
{
Item_outer_ref *ref;
- bool res= FALSE;
- bool direct_ref= FALSE;
List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
while ((ref= ref_it++))
{
+ bool direct_ref= false;
Item *item= ref->outer_ref;
Item **item_ref= ref->ref;
Item_ref *new_ref;
@@ -433,7 +437,7 @@ fix_inner_refs(THD *thd, List<Item> &all
return TRUE;
thd->used_tables|= item->used_tables();
}
- return res;
+ return false;
}
/**
Attachment: [text/bzr-bundle] bzr/martin.hansson@oracle.com-20110218105524-c0e6v0suk1ol0c9k.bundle
| Thread |
|---|
| • bzr push into mysql-5.5 branch (martin.hansson:3342 to 3343) Bug#11766675 | Martin Hansson | 18 Feb |