From 33c4431d39e19fce24c5d3df43fc474439bff115 Mon Sep 17 00:00:00 2001 From: "mhansson/martin@linux-st28.site" <> Date: Thu, 13 Dec 2007 11:19:05 +0100 Subject: Bug #32858: Erro: "Incorrect usage of UNION and INTO" does not take subselects into account It is forbidden to use the SELECT INTO construction inside UNION statements unless on the last SELECT of the union. The parser records whether it has seen INTO or not when parsing a UNION statement. But if the INTO was legally used in an outer query, an error is thrown if UNION is seen in a subquery. Fixed in 5.0 by remembering the nesting level of INTO tokens and mitigate the error unless it collides with the UNION. --- sql/sql_class.h | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'sql/sql_class.h') diff --git a/sql/sql_class.h b/sql/sql_class.h index e6d65f3133a..80665f8b4dc 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1891,6 +1891,7 @@ class select_result :public Sql_alloc { protected: THD *thd; SELECT_LEX_UNIT *unit; + uint nest_level; public: select_result(); virtual ~select_result() {}; @@ -1927,6 +1928,12 @@ public: */ 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 @@ -2006,7 +2013,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 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 &list, SELECT_LEX_UNIT *u); bool send_data(List &items); @@ -2015,7 +2029,15 @@ public: 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 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 &list, SELECT_LEX_UNIT *u); bool send_data(List &items); }; @@ -2422,7 +2444,16 @@ class select_dumpvar :public select_result_interceptor { ha_rows row_count; public: List var_list; - select_dumpvar() { var_list.empty(); row_count= 0;} + /** + Creates a select_dumpvar to represent INTO 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 &list, SELECT_LEX_UNIT *u); bool send_data(List &items); -- cgit v1.2.1