Loading mysql-test/r/order_by.result +32 −0 Original line number Diff line number Diff line Loading @@ -820,3 +820,35 @@ a 2 2 DROP TABLE t1; CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10); (SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a; b a 10 1 10 2 20 1 20 2 30 1 30 2 (SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC; b 10 10 20 20 30 30 (SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b; b a 10 1 20 1 30 1 10 2 20 2 30 2 (SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b; b a 10 1 20 1 10 2 DROP TABLE t1; mysql-test/t/func_gconcat.test +10 −0 Original line number Diff line number Diff line Loading @@ -398,6 +398,16 @@ select f1, group_concat(f1+1) from t1 group by f1 with rollup; select count(distinct (f1+1)) from t1 group by f1 with rollup; drop table t1; # # Bug#14169 type of group_concat() result changed to blob if tmp_table was used # create table t1 (f1 int unsigned, f2 varchar(255)); insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); --enable_metadata select f2,group_concat(f1) from t1 group by f2; --disable_metadata drop table t1; # End of 4.1 tests # Loading mysql-test/t/order_by.test +14 −0 Original line number Diff line number Diff line Loading @@ -563,4 +563,18 @@ SELECT a FROM t1 ORDER BY a; (SELECT a FROM t1) ORDER BY a; DROP TABLE t1; # # Bug #18767: global ORDER BY applied to a SELECT with ORDER BY either was # ignored or 'concatened' to the latter. CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10); (SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a; (SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC; (SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b; (SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b; DROP TABLE t1; # End of 4.1 tests sql/sql_lex.h +1 −0 Original line number Diff line number Diff line Loading @@ -454,6 +454,7 @@ class st_select_lex_unit: public st_select_lex_node { void print(String *str); bool add_fake_select_lex(THD *thd); void init_prepare_fake_select_lex(THD *thd); inline bool is_prepared() { return prepared; } bool change_result(select_subselect *result, select_subselect *old_result); Loading sql/sql_parse.cc +66 −36 Original line number Diff line number Diff line Loading @@ -5544,48 +5544,17 @@ mysql_new_select(LEX *lex, bool move_down) } else { Name_resolution_context *outer_context; if (lex->current_select->order_list.first && !lex->current_select->braces) { my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY"); DBUG_RETURN(1); } select_lex->include_neighbour(lex->current_select); /* we are not sure that we have one level of SELECTs above, so we take outer_context address from first select of unit */ outer_context= select_lex->master_unit()->first_select()->context.outer_context; SELECT_LEX_UNIT *unit= select_lex->master_unit(); SELECT_LEX *fake= unit->fake_select_lex; if (!fake) { /* as far as we included SELECT_LEX for UNION unit should have fake SELECT_LEX for UNION processing */ if (!(fake= unit->fake_select_lex= new (thd->mem_root) SELECT_LEX())) if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd)) DBUG_RETURN(1); fake->include_standalone(unit, (SELECT_LEX_NODE**)&unit->fake_select_lex); fake->select_number= INT_MAX; fake->parent_lex= lex; /* Used in init_query. */ fake->make_empty_select(); fake->linkage= GLOBAL_OPTIONS_TYPE; fake->select_limit= 0; fake->context.outer_context= outer_context; /* allow item list resolving in fake select for ORDER BY */ fake->context.resolve_in_select_list= TRUE; fake->context.select_lex= fake; /* Remove the name resolution context of the fake select from the context stack. */ lex->pop_context(); } select_lex->context.outer_context= outer_context; select_lex->context.outer_context= unit->first_select()->context.outer_context; } select_lex->master_unit()->global_parameters= select_lex; Loading Loading @@ -6357,6 +6326,67 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type) } /* Create a fake SELECT_LEX for a unit SYNOPSIS: add_fake_select_lex() thd thread handle DESCRIPTION The method create a fake SELECT_LEX object for a unit. This object is created for any union construct containing a union operation and also for any single select union construct of the form (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ... or of the form (SELECT ... ORDER BY LIMIT n) ORDER BY ... NOTES The object is used to retrieve rows from the temporary table where the result on the union is obtained. RETURN VALUES 1 on failure to create the object 0 on success */ bool st_select_lex_unit::add_fake_select_lex(THD *thd) { SELECT_LEX *first_sl= first_select(); DBUG_ENTER("add_fake_select_lex"); DBUG_ASSERT(!fake_select_lex); if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); fake_select_lex->include_standalone(this, (SELECT_LEX_NODE**)&fake_select_lex); fake_select_lex->select_number= INT_MAX; fake_select_lex->make_empty_select(); fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE; fake_select_lex->select_limit= 0; fake_select_lex->context.outer_context= first_sl->context.outer_context; /* allow item list resolving in fake select for ORDER BY */ fake_select_lex->context.resolve_in_select_list= TRUE; fake_select_lex->context.select_lex= fake_select_lex; if (!first_sl->next_select()) { /* This works only for (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m], (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m] just before the parser starts processing order_list */ global_parameters= fake_select_lex; fake_select_lex->no_table_names_allowed= 1; thd->lex->current_select= fake_select_lex; } thd->lex->pop_context(); DBUG_RETURN(0); } /* Push a new name resolution context for a JOIN ... ON clause to the context stack of a query block. Loading Loading
mysql-test/r/order_by.result +32 −0 Original line number Diff line number Diff line Loading @@ -820,3 +820,35 @@ a 2 2 DROP TABLE t1; CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10); (SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a; b a 10 1 10 2 20 1 20 2 30 1 30 2 (SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC; b 10 10 20 20 30 30 (SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b; b a 10 1 20 1 30 1 10 2 20 2 30 2 (SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b; b a 10 1 20 1 10 2 DROP TABLE t1;
mysql-test/t/func_gconcat.test +10 −0 Original line number Diff line number Diff line Loading @@ -398,6 +398,16 @@ select f1, group_concat(f1+1) from t1 group by f1 with rollup; select count(distinct (f1+1)) from t1 group by f1 with rollup; drop table t1; # # Bug#14169 type of group_concat() result changed to blob if tmp_table was used # create table t1 (f1 int unsigned, f2 varchar(255)); insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); --enable_metadata select f2,group_concat(f1) from t1 group by f2; --disable_metadata drop table t1; # End of 4.1 tests # Loading
mysql-test/t/order_by.test +14 −0 Original line number Diff line number Diff line Loading @@ -563,4 +563,18 @@ SELECT a FROM t1 ORDER BY a; (SELECT a FROM t1) ORDER BY a; DROP TABLE t1; # # Bug #18767: global ORDER BY applied to a SELECT with ORDER BY either was # ignored or 'concatened' to the latter. CREATE TABLE t1 (a int, b int); INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10); (SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a; (SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC; (SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b; (SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b; DROP TABLE t1; # End of 4.1 tests
sql/sql_lex.h +1 −0 Original line number Diff line number Diff line Loading @@ -454,6 +454,7 @@ class st_select_lex_unit: public st_select_lex_node { void print(String *str); bool add_fake_select_lex(THD *thd); void init_prepare_fake_select_lex(THD *thd); inline bool is_prepared() { return prepared; } bool change_result(select_subselect *result, select_subselect *old_result); Loading
sql/sql_parse.cc +66 −36 Original line number Diff line number Diff line Loading @@ -5544,48 +5544,17 @@ mysql_new_select(LEX *lex, bool move_down) } else { Name_resolution_context *outer_context; if (lex->current_select->order_list.first && !lex->current_select->braces) { my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY"); DBUG_RETURN(1); } select_lex->include_neighbour(lex->current_select); /* we are not sure that we have one level of SELECTs above, so we take outer_context address from first select of unit */ outer_context= select_lex->master_unit()->first_select()->context.outer_context; SELECT_LEX_UNIT *unit= select_lex->master_unit(); SELECT_LEX *fake= unit->fake_select_lex; if (!fake) { /* as far as we included SELECT_LEX for UNION unit should have fake SELECT_LEX for UNION processing */ if (!(fake= unit->fake_select_lex= new (thd->mem_root) SELECT_LEX())) if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd)) DBUG_RETURN(1); fake->include_standalone(unit, (SELECT_LEX_NODE**)&unit->fake_select_lex); fake->select_number= INT_MAX; fake->parent_lex= lex; /* Used in init_query. */ fake->make_empty_select(); fake->linkage= GLOBAL_OPTIONS_TYPE; fake->select_limit= 0; fake->context.outer_context= outer_context; /* allow item list resolving in fake select for ORDER BY */ fake->context.resolve_in_select_list= TRUE; fake->context.select_lex= fake; /* Remove the name resolution context of the fake select from the context stack. */ lex->pop_context(); } select_lex->context.outer_context= outer_context; select_lex->context.outer_context= unit->first_select()->context.outer_context; } select_lex->master_unit()->global_parameters= select_lex; Loading Loading @@ -6357,6 +6326,67 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type) } /* Create a fake SELECT_LEX for a unit SYNOPSIS: add_fake_select_lex() thd thread handle DESCRIPTION The method create a fake SELECT_LEX object for a unit. This object is created for any union construct containing a union operation and also for any single select union construct of the form (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ... or of the form (SELECT ... ORDER BY LIMIT n) ORDER BY ... NOTES The object is used to retrieve rows from the temporary table where the result on the union is obtained. RETURN VALUES 1 on failure to create the object 0 on success */ bool st_select_lex_unit::add_fake_select_lex(THD *thd) { SELECT_LEX *first_sl= first_select(); DBUG_ENTER("add_fake_select_lex"); DBUG_ASSERT(!fake_select_lex); if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); fake_select_lex->include_standalone(this, (SELECT_LEX_NODE**)&fake_select_lex); fake_select_lex->select_number= INT_MAX; fake_select_lex->make_empty_select(); fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE; fake_select_lex->select_limit= 0; fake_select_lex->context.outer_context= first_sl->context.outer_context; /* allow item list resolving in fake select for ORDER BY */ fake_select_lex->context.resolve_in_select_list= TRUE; fake_select_lex->context.select_lex= fake_select_lex; if (!first_sl->next_select()) { /* This works only for (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m], (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m] just before the parser starts processing order_list */ global_parameters= fake_select_lex; fake_select_lex->no_table_names_allowed= 1; thd->lex->current_select= fake_select_lex; } thd->lex->pop_context(); DBUG_RETURN(0); } /* Push a new name resolution context for a JOIN ... ON clause to the context stack of a query block. Loading