Commit 386b5ad1 authored by Sinisa@sinisa.nasamreza.org's avatar Sinisa@sinisa.nasamreza.org

Merge sinisa@work.mysql.com:/home/bk/mysql-4.0

into sinisa.nasamreza.org:/mnt/hdc/Sinisa/mysql-4.0
parents 883424d2 376638b1
......@@ -57,6 +57,7 @@ Docs/manual_letter.ps
Docs/manual_toc.html
Docs/my_sys.doc
Docs/mysql.info
Docs/tex.fmt
Docs/texi2dvi.out
INSTALL-SOURCE
Logs/*
......@@ -210,6 +211,7 @@ libmysqld/derror.cc
libmysqld/errmsg.c
libmysqld/examples/completion_hash.cc
libmysqld/examples/completion_hash.h
libmysqld/examples/link_sources
libmysqld/examples/my_readline.h
libmysqld/examples/mysql
libmysqld/examples/mysql.cc
......@@ -422,4 +424,3 @@ vio/test-ssl
vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
Docs/tex.fmt
......@@ -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,11 +158,22 @@ 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:
free_tmp_table(thd,table);
......
......@@ -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 */ {}
......
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