Commit ef0c236d authored by unknown's avatar unknown

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 17883212 e28c0331
...@@ -3368,3 +3368,28 @@ ORDER BY t1.t DESC LIMIT 1); ...@@ -3368,3 +3368,28 @@ ORDER BY t1.t DESC LIMIT 1);
i1 i2 t i1 i2 t i1 i2 t i1 i2 t
24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40 24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
DROP TABLE t1, t2; 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;
...@@ -2280,3 +2280,29 @@ SELECT * FROM t1,t2 ...@@ -2280,3 +2280,29 @@ SELECT * FROM t1,t2
ORDER BY t1.t DESC LIMIT 1); ORDER BY t1.t DESC LIMIT 1);
DROP TABLE t1, t2; 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;
...@@ -725,8 +725,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -725,8 +725,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
predicate bit_expr bit_term bit_factor value_expr term factor predicate bit_expr bit_term bit_factor value_expr term factor
table_wild simple_expr udf_expr table_wild simple_expr udf_expr
expr_or_default set_expr_or_default interval_expr expr_or_default set_expr_or_default interval_expr
param_marker singlerow_subselect singlerow_subselect_init param_marker geometry_function
exists_subselect exists_subselect_init geometry_function
signed_literal now_or_signed_literal opt_escape signed_literal now_or_signed_literal opt_escape
sp_opt_default sp_opt_default
simple_ident_nospvar simple_ident_q simple_ident_nospvar simple_ident_q
...@@ -791,7 +790,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -791,7 +790,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <variable> internal_variable_name %type <variable> internal_variable_name
%type <select_lex> in_subselect in_subselect_init %type <select_lex> subselect subselect_init
get_select_lex get_select_lex
%type <boolfunc2creator> comp_op %type <boolfunc2creator> comp_op
...@@ -3915,7 +3914,9 @@ select_paren: ...@@ -3915,7 +3914,9 @@ select_paren:
YYABORT; YYABORT;
} }
if (sel->linkage == UNION_TYPE && 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)); yyerror(ER(ER_SYNTAX_ERROR));
YYABORT; YYABORT;
...@@ -4177,37 +4178,37 @@ bool_pri: ...@@ -4177,37 +4178,37 @@ bool_pri:
| bool_pri EQUAL_SYM predicate { $$= new Item_func_equal($1,$3); } | bool_pri EQUAL_SYM predicate { $$= new Item_func_equal($1,$3); }
| bool_pri comp_op predicate %prec EQ | bool_pri comp_op predicate %prec EQ
{ $$= (*$2)(0)->create($1,$3); } { $$= (*$2)(0)->create($1,$3); }
| bool_pri comp_op all_or_any in_subselect %prec EQ | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
{ $$= all_any_subquery_creator($1, $2, $3, $4); } { $$= all_any_subquery_creator($1, $2, $3, $5); }
| predicate ; | predicate ;
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);
$$= new Item_func_eq($1, $4->head());
else
{
$4->push_front($1);
$$= new Item_func_in(*$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);
$$= new Item_func_ne($1, $5->head()); }
else | bit_expr not IN_SYM '(' expr ',' expr_list ')'
{ {
$5->push_front($1); $7->push_front($5);
Item_func_in *item = new Item_func_in(*$5); $7->push_front($1);
Item_func_in *item = new Item_func_in(*$7);
item->negate(); item->negate();
$$= item; $$= 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 | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
{ $$= new Item_func_between($1,$3,$5); } { $$= new Item_func_between($1,$3,$5); }
| bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
...@@ -4329,6 +4330,10 @@ simple_expr: ...@@ -4329,6 +4330,10 @@ simple_expr:
| '-' simple_expr %prec NEG { $$= new Item_func_neg($2); } | '-' simple_expr %prec NEG { $$= new Item_func_neg($2); }
| '~' simple_expr %prec NEG { $$= new Item_func_bit_neg($2); } | '~' simple_expr %prec NEG { $$= new Item_func_bit_neg($2); }
| not2 simple_expr %prec NEG { $$= negate_expression(YYTHD, $2); } | not2 simple_expr %prec NEG { $$= negate_expression(YYTHD, $2); }
| '(' subselect ')'
{
$$= new Item_singlerow_subselect($2);
}
| '(' expr ')' { $$= $2; } | '(' expr ')' { $$= $2; }
| '(' expr ',' expr_list ')' | '(' expr ',' expr_list ')'
{ {
...@@ -4340,8 +4345,10 @@ simple_expr: ...@@ -4340,8 +4345,10 @@ simple_expr:
$5->push_front($3); $5->push_front($3);
$$= new Item_row(*$5); $$= new Item_row(*$5);
} }
| EXISTS exists_subselect { $$= $2; } | EXISTS '(' subselect ')'
| singlerow_subselect { $$= $1; } {
$$= new Item_exists_subselect($3);
}
| '{' ident expr '}' { $$= $3; } | '{' ident expr '}' { $$= $3; }
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')' | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
{ $2->push_front($5); { $2->push_front($5);
...@@ -8867,49 +8874,38 @@ union_option: ...@@ -8867,49 +8874,38 @@ union_option:
| ALL { $$=0; } | ALL { $$=0; }
; ;
singlerow_subselect: subselect:
subselect_start singlerow_subselect_init SELECT_SYM subselect_start subselect_init subselect_end
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
{ {
$$= new Item_exists_subselect(Lex->current_select->master_unit()-> $$= $3;
first_select()); }
}; | '(' subselect_start subselect ')'
in_subselect:
subselect_start in_subselect_init
subselect_end
{ {
$$= $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 select_init2
{ {
$$= Lex->current_select->master_unit()->first_select(); $$= Lex->current_select->master_unit()->first_select();
}; };
subselect_start: subselect_start:
'(' SELECT_SYM
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->sql_command == (int)SQLCOM_HA_READ || if (lex->sql_command == (int)SQLCOM_HA_READ ||
...@@ -8918,12 +8914,18 @@ subselect_start: ...@@ -8918,12 +8914,18 @@ subselect_start:
yyerror(ER(ER_SYNTAX_ERROR)); yyerror(ER(ER_SYNTAX_ERROR));
YYABORT; 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)) if (mysql_new_select(Lex, 1))
YYABORT; YYABORT;
}; };
subselect_end: subselect_end:
')'
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->pop_context(); lex->pop_context();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment