Unchecked changes, so that I could run mysql-test.
If I ruined anything, write your complaints to sasha@mysql.com
This commit is contained in:
parent
26d04064d3
commit
376638b15b
@ -422,3 +422,4 @@ vio/test-sslserver
|
||||
vio/viotest-ssl
|
||||
Docs/#manual.texi#
|
||||
Docs/texi2dvi.out
|
||||
libmysqld/examples/link_sources
|
||||
|
@ -375,7 +375,7 @@ void multi_delete::send_error(uint errcode,const char *err)
|
||||
if ((table_being_deleted->table->file->has_transactions() &&
|
||||
table_being_deleted == delete_tables) ||
|
||||
!some_table_is_not_transaction_safe(delete_tables->next))
|
||||
ha_rollback(thd);
|
||||
ha_rollback_stmt(thd);
|
||||
else if (do_delete)
|
||||
VOID(do_deletes(true));
|
||||
}
|
||||
@ -454,29 +454,45 @@ int multi_delete::do_deletes (bool from_send_error)
|
||||
|
||||
bool multi_delete::send_eof()
|
||||
{
|
||||
thd->proc_info="deleting from reference tables";
|
||||
int error = do_deletes(false);
|
||||
thd->proc_info="deleting from reference tables"; /* out: 1 if error, 0 if success */
|
||||
int error = do_deletes(false); /* do_deletes returns 0 if success */
|
||||
|
||||
/* reset used flags */
|
||||
delete_tables->table->no_keyread=0;
|
||||
|
||||
thd->proc_info="end";
|
||||
if (error && error != -1)
|
||||
if (error)
|
||||
{
|
||||
::send_error(&thd->net);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Write the SQL statement to the binlog if we deleted
|
||||
rows and we succeeded, or also in an error case when there
|
||||
was a non-transaction-safe table involved, since
|
||||
modifications in it cannot be rolled back. */
|
||||
|
||||
if (deleted &&
|
||||
(error <= 0 || some_table_is_not_transaction_safe(delete_tables)))
|
||||
(!error || some_table_is_not_transaction_safe(delete_tables)))
|
||||
{
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
Query_log_event qinfo(thd, thd->query);
|
||||
if (mysql_bin_log.write(&qinfo) &&
|
||||
|
||||
/* mysql_bin_log is not open if binlogging or replication
|
||||
is not used */
|
||||
|
||||
if (mysql_bin_log.is_open() && mysql_bin_log.write(&qinfo) &&
|
||||
!some_table_is_not_transaction_safe(delete_tables))
|
||||
error=1; // Rollback
|
||||
VOID(ha_autocommit_or_rollback(thd,error >= 0));
|
||||
error=1; /* Log write failed: roll back
|
||||
the SQL statement */
|
||||
if (deleted)
|
||||
{
|
||||
/* 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));
|
||||
}
|
||||
}
|
||||
|
||||
::send_ok(&thd->net,deleted);
|
||||
return 0;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ typedef struct st_lex_master_info
|
||||
} LEX_MASTER_INFO;
|
||||
|
||||
|
||||
enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE};
|
||||
enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, NOT_A_SELECT};
|
||||
|
||||
/* The state of the lex parsing for selects */
|
||||
|
||||
@ -118,7 +118,7 @@ typedef struct st_select_lex {
|
||||
ignore_index, *ignore_index_ptr;
|
||||
List<Item_func_match> ftfunc_list;
|
||||
uint in_sum_expr, sort_default;
|
||||
bool create_refs;
|
||||
bool create_refs, braces;
|
||||
st_select_lex *next;
|
||||
} SELECT_LEX;
|
||||
|
||||
|
@ -2888,7 +2888,7 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
|
||||
*new_table_list=0; // end result list
|
||||
for (sl= &lex->select_lex; sl; sl=sl->next)
|
||||
{
|
||||
if (sl->order_list.first && sl->next)
|
||||
if (sl->order_list.first && sl->next && !sl->braces)
|
||||
{
|
||||
net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY");
|
||||
return 1;
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
int mysql_union(THD *thd, LEX *lex,select_result *result)
|
||||
{
|
||||
SELECT_LEX *sl, *last_sl;
|
||||
SELECT_LEX *sl, *last_sl, lex_sl;
|
||||
ORDER *order;
|
||||
List<Item> item_list;
|
||||
TABLE *table;
|
||||
@ -38,7 +38,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
||||
DBUG_ENTER("mysql_union");
|
||||
|
||||
/* Fix tables 'to-be-unioned-from' list to point at opened tables */
|
||||
for (sl=&lex->select_lex; sl; sl=sl->next)
|
||||
for (sl=&lex->select_lex; sl && sl->linkage != NOT_A_SELECT; sl=sl->next)
|
||||
{
|
||||
for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
|
||||
cursor;
|
||||
@ -46,6 +46,14 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
||||
cursor->table= ((TABLE_LIST*) cursor->table)->table;
|
||||
}
|
||||
|
||||
if (sl)
|
||||
{
|
||||
lex_sl=*sl;
|
||||
sl=(SELECT_LEX *)NULL;
|
||||
}
|
||||
else
|
||||
lex_sl.linkage=UNSPECIFIED_TYPE;
|
||||
|
||||
/* Find last select part as it's here ORDER BY and GROUP BY is stored */
|
||||
for (last_sl= &lex->select_lex;
|
||||
last_sl->next;
|
||||
@ -60,7 +68,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
||||
sl->item_list,
|
||||
sl->where,
|
||||
sl->ftfunc_list,
|
||||
(ORDER*) 0,
|
||||
(sl->braces) ? (ORDER*) 0 : (ORDER *) sl->order_list.first,
|
||||
(ORDER*) sl->group_list.first,
|
||||
sl->having,
|
||||
(ORDER*) NULL,
|
||||
@ -71,7 +79,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
order = (ORDER *) last_sl->order_list.first;
|
||||
order = (lex_sl.linkage == UNSPECIFIED_TYPE) ? (ORDER *) last_sl->order_list.first : (ORDER *) lex_sl.order_list.first;
|
||||
|
||||
{
|
||||
Item *item;
|
||||
List_iterator<Item> it(lex->select_lex.item_list);
|
||||
@ -118,7 +127,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
||||
sl->item_list,
|
||||
sl->where,
|
||||
sl->ftfunc_list,
|
||||
(ORDER*) 0,
|
||||
(sl->braces) ? (ORDER*) 0 : (ORDER *)sl->order_list.first,
|
||||
(ORDER*) sl->group_list.first,
|
||||
sl->having,
|
||||
(ORDER*) NULL,
|
||||
@ -149,10 +158,21 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
|
||||
(void) it.replace(new Item_field(*field));
|
||||
}
|
||||
if (!thd->fatal_error) // Check if EOM
|
||||
{
|
||||
if (lex_sl.linkage == NOT_A_SELECT && ( lex_sl.select_limit || lex_sl.offset_limit))
|
||||
{
|
||||
thd->offset_limit=lex_sl.offset_limit;
|
||||
thd->select_limit=lex_sl.select_limit+lex_sl.offset_limit;
|
||||
if (thd->select_limit < lex_sl.select_limit)
|
||||
thd->select_limit= HA_POS_ERROR; // no limit
|
||||
if (thd->select_limit == HA_POS_ERROR)
|
||||
thd->options&= ~OPTION_FOUND_ROWS;
|
||||
}
|
||||
res=mysql_select(thd,&result_table_list,
|
||||
item_list, NULL, ftfunc_list, order,
|
||||
(ORDER*) NULL, NULL, (ORDER*) NULL,
|
||||
thd->options, result);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
|
@ -1340,6 +1340,13 @@ select:
|
||||
Lex->sql_command= SQLCOM_SELECT;
|
||||
}
|
||||
select_part2;
|
||||
|
|
||||
'(' SELECT_SYM
|
||||
{
|
||||
Lex->sql_command= SQLCOM_SELECT;
|
||||
}
|
||||
select_part3;
|
||||
|
||||
|
||||
select_part2:
|
||||
{
|
||||
@ -1349,6 +1356,15 @@ select_part2:
|
||||
}
|
||||
select_options select_item_list select_into select_lock_type union
|
||||
|
||||
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:
|
||||
limit_clause {}
|
||||
| select_from
|
||||
@ -3480,7 +3496,11 @@ rollback:
|
||||
|
||||
|
||||
union:
|
||||
/* empty */ {}
|
||||
/* empty */
|
||||
{
|
||||
if (Lex->select->braces || Select->linkage == NOT_A_SELECT)
|
||||
YYABORT;
|
||||
}
|
||||
| union_list
|
||||
|
||||
union_list:
|
||||
@ -3497,6 +3517,16 @@ union_list:
|
||||
lex->select->linkage=UNION_TYPE;
|
||||
}
|
||||
SELECT_SYM select_part2
|
||||
| '(' SELECT_SYM select_part3 optional_order_or_limit
|
||||
|
||||
optional_order_or_limit:
|
||||
/* emty */ {}
|
||||
|
|
||||
{
|
||||
mysql_new_select(Lex);
|
||||
Lex->select->linkage=NOT_A_SELECT;
|
||||
}
|
||||
order_clause limit_clause
|
||||
|
||||
union_option:
|
||||
/* empty */ {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user