Loading mysql-test/r/union.result +42 −0 Original line number Diff line number Diff line Loading @@ -1440,4 +1440,46 @@ UNION SELECT 1,1; ERROR HY000: Incorrect usage of UNION and ORDER BY DROP TABLE t1,t2; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1); SELECT a INTO @v FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 ) alias; SELECT a INTO OUTFILE 'union.out.file' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; SELECT a INTO DUMPFILE 'union.out.file2' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO @v FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file3' FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO DUMPFILE 'union.out.file4' FROM t1 ) alias; SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO DROP TABLE t1; End of 5.0 tests mysql-test/t/union.test +57 −0 Original line number Diff line number Diff line Loading @@ -921,4 +921,61 @@ SELECT 1,1; DROP TABLE t1,t2; # Bug#32858: Erro: "Incorrect usage of UNION and INTO" does not take subselects # into account # CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1); SELECT a INTO @v FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 ) alias; SELECT a INTO OUTFILE 'union.out.file' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; SELECT a INTO DUMPFILE 'union.out.file2' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; # # INTO will not be allowed in subqueries in version 5.1 and above. # SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO @v FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file3' FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO DUMPFILE 'union.out.file4' FROM t1 ) alias; SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; --error ER_WRONG_USAGE SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; --error ER_WRONG_USAGE SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; --error ER_WRONG_USAGE SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; DROP TABLE t1; --echo End of 5.0 tests sql/sql_class.cc +1 −0 Original line number Diff line number Diff line Loading @@ -931,6 +931,7 @@ void THD::rollback_item_tree_changes() select_result::select_result() { thd=current_thd; nest_level= -1; } void select_result::send_error(uint errcode,const char *err) Loading sql/sql_class.h +34 −3 Original line number Diff line number Diff line Loading @@ -1912,6 +1912,7 @@ class select_result :public Sql_alloc { protected: THD *thd; SELECT_LEX_UNIT *unit; uint nest_level; public: select_result(); virtual ~select_result() {}; Loading Loading @@ -1948,6 +1949,12 @@ class select_result :public Sql_alloc { */ virtual void cleanup(); void set_thd(THD *thd_arg) { thd= thd_arg; } /** The nest level, if supported. @return -1 if nest level is undefined, otherwise a positive integer. */ int get_nest_level() { return nest_level; } #ifdef EMBEDDED_LIBRARY virtual void begin_dataset() {} #else Loading Loading @@ -2034,7 +2041,14 @@ class select_export :public select_to_file { bool is_unsafe_field_sep; bool fixed_row_size; public: select_export(sql_exchange *ex) :select_to_file(ex) {} /** Creates a select_export to represent INTO OUTFILE <filename> with a defined level of subquery nesting. */ select_export(sql_exchange *ex, uint nest_level_arg) :select_to_file(ex) { nest_level= nest_level_arg; } ~select_export(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); Loading @@ -2043,7 +2057,15 @@ class select_export :public select_to_file { class select_dump :public select_to_file { public: select_dump(sql_exchange *ex) :select_to_file(ex) {} /** Creates a select_export to represent INTO DUMPFILE <filename> with a defined level of subquery nesting. */ select_dump(sql_exchange *ex, uint nest_level_arg) : select_to_file(ex) { nest_level= nest_level_arg; } int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); }; Loading Loading @@ -2461,7 +2483,16 @@ class select_dumpvar :public select_result_interceptor { ha_rows row_count; public: List<my_var> var_list; select_dumpvar() { var_list.empty(); row_count= 0;} /** Creates a select_dumpvar to represent INTO <variable> with a defined level of subquery nesting. */ select_dumpvar(uint nest_level_arg) { var_list.empty(); row_count= 0; nest_level= nest_level_arg; } ~select_dumpvar() {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); Loading sql/sql_yacc.yy +16 −9 Original line number Diff line number Diff line Loading @@ -6350,7 +6350,8 @@ procedure_item: select_var_list_init: { LEX *lex=Lex; if (!lex->describe && (!(lex->result= new select_dumpvar()))) if (!lex->describe && (!(lex->result= new select_dumpvar(lex->nest_level)))) MYSQL_YYABORT; } select_var_list Loading Loading @@ -6424,7 +6425,7 @@ into_destination: LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_SIDEEFFECT); if (!(lex->exchange= new sql_exchange($2.str, 0)) || !(lex->result= new select_export(lex->exchange))) !(lex->result= new select_export(lex->exchange, lex->nest_level))) MYSQL_YYABORT; } opt_field_term opt_line_term Loading @@ -6436,7 +6437,7 @@ into_destination: lex->uncacheable(UNCACHEABLE_SIDEEFFECT); if (!(lex->exchange= new sql_exchange($2.str,1))) MYSQL_YYABORT; if (!(lex->result= new select_dump(lex->exchange))) if (!(lex->result= new select_dump(lex->exchange, lex->nest_level))) MYSQL_YYABORT; } } Loading Loading @@ -9427,9 +9428,15 @@ union_list: UNION_SYM union_option { LEX *lex=Lex; if (lex->result) if (lex->result && (lex->result->get_nest_level() == -1 || lex->result->get_nest_level() == lex->nest_level)) { /* Only the last SELECT can have INTO...... */ /* Only the last SELECT can have INTO unless the INTO and UNION are at different nest levels. In version 5.1 and above, INTO will onle be allowed at top level. */ my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO"); MYSQL_YYABORT; } Loading Loading
mysql-test/r/union.result +42 −0 Original line number Diff line number Diff line Loading @@ -1440,4 +1440,46 @@ UNION SELECT 1,1; ERROR HY000: Incorrect usage of UNION and ORDER BY DROP TABLE t1,t2; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1); SELECT a INTO @v FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 ) alias; SELECT a INTO OUTFILE 'union.out.file' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; SELECT a INTO DUMPFILE 'union.out.file2' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO @v FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file3' FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO DUMPFILE 'union.out.file4' FROM t1 ) alias; SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; ERROR HY000: Incorrect usage of UNION and INTO DROP TABLE t1; End of 5.0 tests
mysql-test/t/union.test +57 −0 Original line number Diff line number Diff line Loading @@ -921,4 +921,61 @@ SELECT 1,1; DROP TABLE t1,t2; # Bug#32858: Erro: "Incorrect usage of UNION and INTO" does not take subselects # into account # CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1); SELECT a INTO @v FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 ) alias; SELECT a INTO OUTFILE 'union.out.file' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; SELECT a INTO DUMPFILE 'union.out.file2' FROM ( SELECT a FROM t1 UNION SELECT a FROM t1 WHERE 0 ) alias; # # INTO will not be allowed in subqueries in version 5.1 and above. # SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO @v FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file3' FROM t1 ) alias; SELECT a FROM ( SELECT a FROM t1 UNION SELECT a INTO DUMPFILE 'union.out.file4' FROM t1 ) alias; SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; --error ER_WRONG_USAGE SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; --error ER_WRONG_USAGE SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; --error ER_WRONG_USAGE SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; DROP TABLE t1; --echo End of 5.0 tests
sql/sql_class.cc +1 −0 Original line number Diff line number Diff line Loading @@ -931,6 +931,7 @@ void THD::rollback_item_tree_changes() select_result::select_result() { thd=current_thd; nest_level= -1; } void select_result::send_error(uint errcode,const char *err) Loading
sql/sql_class.h +34 −3 Original line number Diff line number Diff line Loading @@ -1912,6 +1912,7 @@ class select_result :public Sql_alloc { protected: THD *thd; SELECT_LEX_UNIT *unit; uint nest_level; public: select_result(); virtual ~select_result() {}; Loading Loading @@ -1948,6 +1949,12 @@ class select_result :public Sql_alloc { */ virtual void cleanup(); void set_thd(THD *thd_arg) { thd= thd_arg; } /** The nest level, if supported. @return -1 if nest level is undefined, otherwise a positive integer. */ int get_nest_level() { return nest_level; } #ifdef EMBEDDED_LIBRARY virtual void begin_dataset() {} #else Loading Loading @@ -2034,7 +2041,14 @@ class select_export :public select_to_file { bool is_unsafe_field_sep; bool fixed_row_size; public: select_export(sql_exchange *ex) :select_to_file(ex) {} /** Creates a select_export to represent INTO OUTFILE <filename> with a defined level of subquery nesting. */ select_export(sql_exchange *ex, uint nest_level_arg) :select_to_file(ex) { nest_level= nest_level_arg; } ~select_export(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); Loading @@ -2043,7 +2057,15 @@ class select_export :public select_to_file { class select_dump :public select_to_file { public: select_dump(sql_exchange *ex) :select_to_file(ex) {} /** Creates a select_export to represent INTO DUMPFILE <filename> with a defined level of subquery nesting. */ select_dump(sql_exchange *ex, uint nest_level_arg) : select_to_file(ex) { nest_level= nest_level_arg; } int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); }; Loading Loading @@ -2461,7 +2483,16 @@ class select_dumpvar :public select_result_interceptor { ha_rows row_count; public: List<my_var> var_list; select_dumpvar() { var_list.empty(); row_count= 0;} /** Creates a select_dumpvar to represent INTO <variable> with a defined level of subquery nesting. */ select_dumpvar(uint nest_level_arg) { var_list.empty(); row_count= 0; nest_level= nest_level_arg; } ~select_dumpvar() {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); Loading
sql/sql_yacc.yy +16 −9 Original line number Diff line number Diff line Loading @@ -6350,7 +6350,8 @@ procedure_item: select_var_list_init: { LEX *lex=Lex; if (!lex->describe && (!(lex->result= new select_dumpvar()))) if (!lex->describe && (!(lex->result= new select_dumpvar(lex->nest_level)))) MYSQL_YYABORT; } select_var_list Loading Loading @@ -6424,7 +6425,7 @@ into_destination: LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_SIDEEFFECT); if (!(lex->exchange= new sql_exchange($2.str, 0)) || !(lex->result= new select_export(lex->exchange))) !(lex->result= new select_export(lex->exchange, lex->nest_level))) MYSQL_YYABORT; } opt_field_term opt_line_term Loading @@ -6436,7 +6437,7 @@ into_destination: lex->uncacheable(UNCACHEABLE_SIDEEFFECT); if (!(lex->exchange= new sql_exchange($2.str,1))) MYSQL_YYABORT; if (!(lex->result= new select_dump(lex->exchange))) if (!(lex->result= new select_dump(lex->exchange, lex->nest_level))) MYSQL_YYABORT; } } Loading Loading @@ -9427,9 +9428,15 @@ union_list: UNION_SYM union_option { LEX *lex=Lex; if (lex->result) if (lex->result && (lex->result->get_nest_level() == -1 || lex->result->get_nest_level() == lex->nest_level)) { /* Only the last SELECT can have INTO...... */ /* Only the last SELECT can have INTO unless the INTO and UNION are at different nest levels. In version 5.1 and above, INTO will onle be allowed at top level. */ my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO"); MYSQL_YYABORT; } Loading