Commit 1c908336 authored by unknown's avatar unknown

New alternate UNION syntax and bug fix for multi-table deletes


mysql-test/r/union.result:
  New results for optional UNION syntax
mysql-test/t/union.test:
  New  test for alternate syntax for UNION
sql/sql_delete.cc:
  Fixed bug in multi-table delete's with transactional tables
sql/sql_parse.cc:
  A small change to enable new UNION syntax
sql/sql_union.cc:
  New alternate UNION syntax
sql/sql_yacc.yy:
  New alternate UNION syntax
parent f9b331ff
...@@ -68,6 +68,12 @@ t2 c 1 ...@@ -68,6 +68,12 @@ t2 c 1
t2 d 1 t2 d 1
t2 e 1 t2 e 1
t2 f 1 t2 f 1
(select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4;
a b
1 a
2 b
3 c
4 d
explain select a,b from t1 union all select a,b from t2; explain select a,b from t1 union all select a,b from t2;
table type possible_keys key key_len ref rows Extra table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 4 t1 ALL NULL NULL NULL NULL 4
......
...@@ -16,6 +16,9 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select ...@@ -16,6 +16,9 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select
select a,b from t1 union select a,b from t1; select a,b from t1 union select a,b from t1;
select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b; select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b;
#test alternate syntax for unions
(select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4;
# Test some error conditions with UNION # Test some error conditions with UNION
explain select a,b from t1 union all select a,b from t2; explain select a,b from t1 union all select a,b from t2;
......
...@@ -455,11 +455,13 @@ int multi_delete::do_deletes (bool from_send_error) ...@@ -455,11 +455,13 @@ int multi_delete::do_deletes (bool from_send_error)
bool multi_delete::send_eof() bool multi_delete::send_eof()
{ {
thd->proc_info="deleting from reference tables"; /* out: 1 if error, 0 if success */ thd->proc_info="deleting from reference tables"; /* out: 1 if error, 0 if success */
/* Does deletes for the last n - 1 tables, returns 0 if ok */
int error = do_deletes(false); /* do_deletes returns 0 if success */ int error = do_deletes(false); /* do_deletes returns 0 if success */
/* reset used flags */ /* reset used flags */
delete_tables->table->no_keyread=0; delete_tables->table->no_keyread=0;
if (error == -1) error = 0;
thd->proc_info="end"; thd->proc_info="end";
if (error) if (error)
{ {
...@@ -485,12 +487,10 @@ bool multi_delete::send_eof() ...@@ -485,12 +487,10 @@ bool multi_delete::send_eof()
!some_table_is_not_transaction_safe(delete_tables)) !some_table_is_not_transaction_safe(delete_tables))
error=1; /* Log write failed: roll back error=1; /* Log write failed: roll back
the SQL statement */ the SQL statement */
if (deleted)
{ /* Commit or rollback the current SQL statement */
/* If autocommit is on we do a commit, in an error case we
roll back the current SQL statement */ VOID(ha_autocommit_or_rollback(thd,error > 0));
VOID(ha_autocommit_or_rollback(thd, error != 0));
}
} }
::send_ok(&thd->net,deleted); ::send_ok(&thd->net,deleted);
......
...@@ -2406,6 +2406,7 @@ mysql_init_query(THD *thd) ...@@ -2406,6 +2406,7 @@ mysql_init_query(THD *thd)
thd->fatal_error=0; // Safety thd->fatal_error=0; // Safety
thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0; thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
thd->sent_row_count=thd->examined_row_count=0; thd->sent_row_count=thd->examined_row_count=0;
thd->lex.sql_command=SQLCOM_SELECT;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
int mysql_union(THD *thd, LEX *lex,select_result *result) int mysql_union(THD *thd, LEX *lex,select_result *result)
{ {
SELECT_LEX *sl, *last_sl, lex_sl; SELECT_LEX *sl, *last_sl=(SELECT_LEX *)NULL, lex_sl;
ORDER *order; ORDER *order;
List<Item> item_list; List<Item> item_list;
TABLE *table; TABLE *table;
...@@ -38,7 +38,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -38,7 +38,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
DBUG_ENTER("mysql_union"); DBUG_ENTER("mysql_union");
/* Fix tables 'to-be-unioned-from' list to point at opened tables */ /* Fix tables 'to-be-unioned-from' list to point at opened tables */
for (sl=&lex->select_lex; sl && sl->linkage != NOT_A_SELECT; sl=sl->next) for (sl=&lex->select_lex; sl && sl->linkage != NOT_A_SELECT; last_sl=sl, sl=sl->next)
{ {
for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
cursor; cursor;
...@@ -50,6 +50,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -50,6 +50,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
{ {
lex_sl=*sl; lex_sl=*sl;
sl=(SELECT_LEX *)NULL; sl=(SELECT_LEX *)NULL;
if (last_sl) last_sl->next=sl;
} }
else else
lex_sl.linkage=UNSPECIFIED_TYPE; lex_sl.linkage=UNSPECIFIED_TYPE;
...@@ -68,7 +69,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -68,7 +69,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
sl->item_list, sl->item_list,
sl->where, sl->where,
sl->ftfunc_list, sl->ftfunc_list,
(sl->braces) ? (ORDER*) 0 : (ORDER *) sl->order_list.first, (sl->braces) ? (ORDER *) sl->order_list.first : (ORDER *) 0,
(ORDER*) sl->group_list.first, (ORDER*) sl->group_list.first,
sl->having, sl->having,
(ORDER*) NULL, (ORDER*) NULL,
...@@ -79,7 +80,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -79,7 +80,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
order = (lex_sl.linkage == UNSPECIFIED_TYPE) ? (ORDER *) last_sl->order_list.first : (ORDER *) lex_sl.order_list.first; order = (lex_sl.linkage == UNSPECIFIED_TYPE) ? ( (last_sl->braces) ? (ORDER *) 0 : (ORDER *) last_sl->order_list.first) : (ORDER *) lex_sl.order_list.first;
{ {
Item *item; Item *item;
...@@ -127,7 +128,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -127,7 +128,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
sl->item_list, sl->item_list,
sl->where, sl->where,
sl->ftfunc_list, sl->ftfunc_list,
(sl->braces) ? (ORDER*) 0 : (ORDER *)sl->order_list.first, (sl->braces) ? (ORDER *)sl->order_list.first : (ORDER *) 0,
(ORDER*) sl->group_list.first, (ORDER*) sl->group_list.first,
sl->having, sl->having,
(ORDER*) NULL, (ORDER*) NULL,
......
...@@ -1335,18 +1335,9 @@ table_to_table: ...@@ -1335,18 +1335,9 @@ table_to_table:
select: select:
SELECT_SYM SELECT_SYM select_part2 {Select->braces=false;} union
{ |
Lex->sql_command= SQLCOM_SELECT; '(' SELECT_SYM select_part2 ')' {Select->braces=true;} union_opt
}
select_part2;
|
'(' SELECT_SYM
{
Lex->sql_command= SQLCOM_SELECT;
}
select_part3;
select_part2: select_part2:
{ {
...@@ -1354,16 +1345,7 @@ select_part2: ...@@ -1354,16 +1345,7 @@ select_part2:
lex->lock_option=TL_READ; lex->lock_option=TL_READ;
mysql_init_select(lex); mysql_init_select(lex);
} }
select_options select_item_list select_into select_lock_type union select_options select_item_list select_into select_lock_type
select_part3:
{
LEX *lex=Lex;
lex->lock_option=TL_READ;
mysql_init_select(lex);
Select->braces = true;
}
select_options select_item_list select_into select_lock_type ')' union
select_into: select_into:
limit_clause {} limit_clause {}
...@@ -3496,11 +3478,7 @@ rollback: ...@@ -3496,11 +3478,7 @@ rollback:
union: union:
/* empty */ /* empty */ {}
{
if (Lex->select->braces || Select->linkage == NOT_A_SELECT)
YYABORT;
}
| union_list | union_list
union_list: union_list:
...@@ -3513,20 +3491,29 @@ union_list: ...@@ -3513,20 +3491,29 @@ union_list:
net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO"); net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO");
YYABORT; YYABORT;
} }
if (lex->select->linkage==NOT_A_SELECT)
YYABORT;
mysql_new_select(lex); mysql_new_select(lex);
lex->select->linkage=UNION_TYPE; lex->select->linkage=UNION_TYPE;
} }
SELECT_SYM select_part2 select
| '(' SELECT_SYM select_part3 optional_order_or_limit
union_opt:
union {}
| optional_order_or_limit {}
optional_order_or_limit: optional_order_or_limit:
/* emty */ {} /* emty */ {}
| |
{ {
mysql_new_select(Lex); LEX *lex=Lex;
Lex->select->linkage=NOT_A_SELECT; if (!lex->select->braces)
YYABORT;
mysql_new_select(lex);
mysql_init_select(lex);
lex->select->linkage=NOT_A_SELECT;
} }
order_clause limit_clause opt_order_clause limit_clause
union_option: union_option:
/* empty */ {} /* empty */ {}
......
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