Commit a0e95927 authored by unknown's avatar unknown
Browse files

Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt

into  rakia.(none):/home/kgeorge/mysql/autopush/B14654-5.0-opt


mysql-test/r/subselect.result:
  Auto merged
mysql-test/t/subselect.test:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
parents efa8e330 c9bba13a
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -3368,3 +3368,28 @@ ORDER BY t1.t DESC LIMIT 1);
i1	i2	t	i1	i2	t
24	1	2005-05-27 12:40:30	24	1	2006-06-20 12:29:40
DROP TABLE t1, t2;
CREATE TABLE t1 (i INT);
(SELECT i FROM t1) UNION (SELECT i FROM t1);
i
SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS 
(
(SELECT i FROM t1) UNION 
(SELECT i FROM t1)
);
i
SELECT * FROM t1 
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
i
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'union (select t12.i from t1 t12))
from t1' at line 1
explain select * from t1 where not exists 
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	PRIMARY	t1	system	NULL	NULL	NULL	NULL	0	const row not found
2	SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
3	SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	no matching row in const table
4	UNION	t12	system	NULL	NULL	NULL	NULL	0	const row not found
NULL	UNION RESULT	<union2,4>	ALL	NULL	NULL	NULL	NULL	NULL	
DROP TABLE t1;
+26 −0
Original line number Diff line number Diff line
@@ -2280,3 +2280,29 @@ SELECT * FROM t1,t2
                    ORDER BY t1.t DESC LIMIT 1);

DROP TABLE t1, t2;

#
# Bug#14654 : Cannot select from the same table twice within a UNION
# statement 
#
CREATE TABLE t1 (i INT);

(SELECT i FROM t1) UNION (SELECT i FROM t1);
SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS 
  (
   (SELECT i FROM t1) UNION 
   (SELECT i FROM t1)
  );

SELECT * FROM t1 
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));

#TODO:not supported
--error 1064
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
  from t1;
#supported
explain select * from t1 where not exists 
  ((select t11.i from t1 t11) union (select t12.i from t1 t12));

DROP TABLE t1;
+72 −70
Original line number Diff line number Diff line
@@ -725,8 +725,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
	predicate bit_expr bit_term bit_factor value_expr term factor
	table_wild simple_expr udf_expr
	expr_or_default set_expr_or_default interval_expr
	param_marker singlerow_subselect singlerow_subselect_init
	exists_subselect exists_subselect_init geometry_function
	param_marker geometry_function
	signed_literal now_or_signed_literal opt_escape
	sp_opt_default
	simple_ident_nospvar simple_ident_q
@@ -791,7 +790,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);

%type <variable> internal_variable_name

%type <select_lex> in_subselect in_subselect_init
%type <select_lex> subselect subselect_init
	get_select_lex

%type <boolfunc2creator> comp_op
@@ -3915,7 +3914,9 @@ select_paren:
	      YYABORT;
	    }
            if (sel->linkage == UNION_TYPE &&
	      !sel->master_unit()->first_select()->braces)
                !sel->master_unit()->first_select()->braces &&
                sel->master_unit()->first_select()->linkage ==
                UNION_TYPE)
            {
              yyerror(ER(ER_SYNTAX_ERROR));
              YYABORT;
@@ -4177,37 +4178,37 @@ bool_pri:
	| bool_pri EQUAL_SYM predicate	{ $$= new Item_func_equal($1,$3); }
	| bool_pri comp_op predicate %prec EQ
	  { $$= (*$2)(0)->create($1,$3); }
	| bool_pri comp_op all_or_any in_subselect %prec EQ
	  { $$= all_any_subquery_creator($1, $2, $3, $4); }
	| bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
	  { $$= all_any_subquery_creator($1, $2, $3, $5); }
	| predicate ;

predicate:
	 bit_expr IN_SYM '(' expr_list ')'
        bit_expr IN_SYM '(' subselect ')'
	  { $$= new Item_in_subselect($1, $4); }
	| bit_expr not IN_SYM '(' subselect ')'
          { $$= negate_expression(YYTHD, new Item_in_subselect($1, $5)); }
        | bit_expr IN_SYM '(' expr ')'
          {
            if ($4->elements == 1)
              $$= new Item_func_eq($1, $4->head());
            else
            {
              $4->push_front($1);
              $$= new Item_func_in(*$4);
              $$= new Item_func_eq($1, $4);
          }
	| bit_expr IN_SYM '(' expr ',' expr_list ')'
	  { 
              $6->push_front($4);
              $6->push_front($1);
              $$= new Item_func_in(*$6);
          }
	| bit_expr not IN_SYM '(' expr_list ')'
        | bit_expr not IN_SYM '(' expr ')'
          {
            if ($5->elements == 1)
              $$= new Item_func_ne($1, $5->head());
            else
              $$= new Item_func_ne($1, $5);
          }
	| bit_expr not IN_SYM '(' expr ',' expr_list ')'
          {
              $5->push_front($1);
              Item_func_in *item = new Item_func_in(*$5);
              $7->push_front($5);
              $7->push_front($1);
              Item_func_in *item = new Item_func_in(*$7);
              item->negate();
              $$= item;
          }
          }
        | bit_expr IN_SYM in_subselect
	  { $$= new Item_in_subselect($1, $3); }
	| bit_expr not IN_SYM in_subselect
          { $$= negate_expression(YYTHD, new Item_in_subselect($1, $4)); }
	| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
	  { $$= new Item_func_between($1,$3,$5); }
	| bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
@@ -4329,6 +4330,10 @@ simple_expr:
	| '-' simple_expr %prec NEG	{ $$= new Item_func_neg($2); }
	| '~' simple_expr %prec NEG	{ $$= new Item_func_bit_neg($2); }
	| not2 simple_expr %prec NEG	{ $$= negate_expression(YYTHD, $2); }
	| '(' subselect ')'   
          { 
            $$= new Item_singlerow_subselect($2); 
          }
	| '(' expr ')'		{ $$= $2; }
	| '(' expr ',' expr_list ')'
	  {
@@ -4340,8 +4345,10 @@ simple_expr:
	    $5->push_front($3);
	    $$= new Item_row(*$5);
	  }
	| EXISTS exists_subselect { $$= $2; }
	| singlerow_subselect   { $$= $1; }
	| EXISTS '(' subselect ')' 
          {
            $$= new Item_exists_subselect($3); 
          }
	| '{' ident expr '}'	{ $$= $3; }
        | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
          { $2->push_front($5);
@@ -8867,49 +8874,38 @@ union_option:
	| ALL       { $$=0; }
        ;

singlerow_subselect:
	subselect_start singlerow_subselect_init
	subselect_end
	{
	  $$= $2;
	};

singlerow_subselect_init:
	select_init2
	{
	  $$= new Item_singlerow_subselect(Lex->current_select->
					   master_unit()->first_select());
	};

exists_subselect:
	subselect_start exists_subselect_init
	subselect_end
	{
	  $$= $2;
	};

exists_subselect_init:
	select_init2
subselect:
        SELECT_SYM subselect_start subselect_init subselect_end
        {
	  $$= new Item_exists_subselect(Lex->current_select->master_unit()->
					first_select());
	};

in_subselect:
  subselect_start in_subselect_init
  subselect_end
          $$= $3;
        }
        | '(' subselect_start subselect ')'
          {
    $$= $2;
  };
            LEX *lex= Lex;
	    THD *thd= YYTHD;
            /*
              note that a local variable can't be used for
              $3 as it's used in local variable construction
              and some compilers can't guarnatee the order
              in which the local variables are initialized.
            */
            List_iterator<Item> it($3->item_list);
            Item *item;
            /*
              we must fill the items list for the "derived table".
            */
            while ((item= it++))
              add_item_to_list(thd, item);
          }
          union_clause subselect_end { $$= $3; };

in_subselect_init:
subselect_init:
  select_init2
  {
    $$= Lex->current_select->master_unit()->first_select();
  };

subselect_start:
	'(' SELECT_SYM
	{
	  LEX *lex=Lex;
          if (lex->sql_command == (int)SQLCOM_HA_READ ||
@@ -8918,12 +8914,18 @@ subselect_start:
            yyerror(ER(ER_SYNTAX_ERROR));
	    YYABORT;
	  }
          /* 
            we are making a "derived table" for the parenthesis
            as we need to have a lex level to fit the union 
            after the parenthesis, e.g. 
            (SELECT .. ) UNION ...  becomes 
            SELECT * FROM ((SELECT ...) UNION ...)
          */
	  if (mysql_new_select(Lex, 1))
	    YYABORT;
	};

subselect_end:
	')'
	{
	  LEX *lex=Lex;
          lex->pop_context();