Commit ca5f5078 authored by mhansson/martin@linux-st28.site's avatar mhansson/martin@linux-st28.site
Browse files

Merge mhansson@bk-internal:/home/bk/mysql-5.0-opt

into  linux-st28.site:/home/martin/mysql/src/bug32798-united/my50-bug32798-united-push
parents bcfdd274 59314ee3
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -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
+57 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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)
+34 −3
Original line number Diff line number Diff line
@@ -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() {};
@@ -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
@@ -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);
@@ -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);
};
@@ -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);
+16 −9
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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;
	  }
	}
@@ -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;
          }