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 ...@@ -57,6 +57,7 @@ Docs/manual_letter.ps
Docs/manual_toc.html Docs/manual_toc.html
Docs/my_sys.doc Docs/my_sys.doc
Docs/mysql.info Docs/mysql.info
Docs/tex.fmt
Docs/texi2dvi.out Docs/texi2dvi.out
INSTALL-SOURCE INSTALL-SOURCE
Logs/* Logs/*
...@@ -210,6 +211,7 @@ libmysqld/derror.cc ...@@ -210,6 +211,7 @@ libmysqld/derror.cc
libmysqld/errmsg.c libmysqld/errmsg.c
libmysqld/examples/completion_hash.cc libmysqld/examples/completion_hash.cc
libmysqld/examples/completion_hash.h libmysqld/examples/completion_hash.h
libmysqld/examples/link_sources
libmysqld/examples/my_readline.h libmysqld/examples/my_readline.h
libmysqld/examples/mysql libmysqld/examples/mysql
libmysqld/examples/mysql.cc libmysqld/examples/mysql.cc
...@@ -422,4 +424,3 @@ vio/test-ssl ...@@ -422,4 +424,3 @@ vio/test-ssl
vio/test-sslclient vio/test-sslclient
vio/test-sslserver vio/test-sslserver
vio/viotest-ssl vio/viotest-ssl
Docs/tex.fmt
...@@ -375,7 +375,7 @@ void multi_delete::send_error(uint errcode,const char *err) ...@@ -375,7 +375,7 @@ void multi_delete::send_error(uint errcode,const char *err)
if ((table_being_deleted->table->file->has_transactions() && if ((table_being_deleted->table->file->has_transactions() &&
table_being_deleted == delete_tables) || table_being_deleted == delete_tables) ||
!some_table_is_not_transaction_safe(delete_tables->next)) !some_table_is_not_transaction_safe(delete_tables->next))
ha_rollback(thd); ha_rollback_stmt(thd);
else if (do_delete) else if (do_delete)
VOID(do_deletes(true)); VOID(do_deletes(true));
} }
...@@ -454,29 +454,45 @@ int multi_delete::do_deletes (bool from_send_error) ...@@ -454,29 +454,45 @@ 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"; thd->proc_info="deleting from reference tables"; /* out: 1 if error, 0 if success */
int error = do_deletes(false); 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;
thd->proc_info="end"; thd->proc_info="end";
if (error && error != -1) if (error)
{ {
::send_error(&thd->net); ::send_error(&thd->net);
return 1; 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 && 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); mysql_update_log.write(thd,thd->query,thd->query_length);
Query_log_event qinfo(thd, thd->query); 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)) !some_table_is_not_transaction_safe(delete_tables))
error=1; // Rollback error=1; /* Log write failed: roll back
VOID(ha_autocommit_or_rollback(thd,error >= 0)); 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); ::send_ok(&thd->net,deleted);
return 0; return 0;
} }
......
...@@ -100,7 +100,7 @@ typedef struct st_lex_master_info ...@@ -100,7 +100,7 @@ typedef struct st_lex_master_info
} 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 */ /* The state of the lex parsing for selects */
...@@ -118,7 +118,7 @@ typedef struct st_select_lex { ...@@ -118,7 +118,7 @@ typedef struct st_select_lex {
ignore_index, *ignore_index_ptr; ignore_index, *ignore_index_ptr;
List<Item_func_match> ftfunc_list; List<Item_func_match> ftfunc_list;
uint in_sum_expr, sort_default; uint in_sum_expr, sort_default;
bool create_refs; bool create_refs, braces;
st_select_lex *next; st_select_lex *next;
} SELECT_LEX; } SELECT_LEX;
......
...@@ -2888,7 +2888,7 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) ...@@ -2888,7 +2888,7 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
*new_table_list=0; // end result list *new_table_list=0; // end result list
for (sl= &lex->select_lex; sl; sl=sl->next) 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"); net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY");
return 1; return 1;
......
...@@ -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; SELECT_LEX *sl, *last_sl, 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=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; for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
cursor; cursor;
...@@ -46,6 +46,14 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -46,6 +46,14 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
cursor->table= ((TABLE_LIST*) cursor->table)->table; 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 */ /* Find last select part as it's here ORDER BY and GROUP BY is stored */
for (last_sl= &lex->select_lex; for (last_sl= &lex->select_lex;
last_sl->next; last_sl->next;
...@@ -60,7 +68,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -60,7 +68,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,
(ORDER*) 0, (sl->braces) ? (ORDER*) 0 : (ORDER *) sl->order_list.first,
(ORDER*) sl->group_list.first, (ORDER*) sl->group_list.first,
sl->having, sl->having,
(ORDER*) NULL, (ORDER*) NULL,
...@@ -71,7 +79,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -71,7 +79,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
DBUG_RETURN(0); 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; Item *item;
List_iterator<Item> it(lex->select_lex.item_list); List_iterator<Item> it(lex->select_lex.item_list);
...@@ -118,7 +127,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -118,7 +127,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,
(ORDER*) 0, (sl->braces) ? (ORDER*) 0 : (ORDER *)sl->order_list.first,
(ORDER*) sl->group_list.first, (ORDER*) sl->group_list.first,
sl->having, sl->having,
(ORDER*) NULL, (ORDER*) NULL,
...@@ -149,11 +158,22 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -149,11 +158,22 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
(void) it.replace(new Item_field(*field)); (void) it.replace(new Item_field(*field));
} }
if (!thd->fatal_error) // Check if EOM 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, res=mysql_select(thd,&result_table_list,
item_list, NULL, ftfunc_list, order, item_list, NULL, ftfunc_list, order,
(ORDER*) NULL, NULL, (ORDER*) NULL, (ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result); thd->options, result);
} }
}
exit: exit:
free_tmp_table(thd,table); free_tmp_table(thd,table);
......
...@@ -1340,6 +1340,13 @@ select: ...@@ -1340,6 +1340,13 @@ select:
Lex->sql_command= SQLCOM_SELECT; Lex->sql_command= SQLCOM_SELECT;
} }
select_part2; select_part2;
|
'(' SELECT_SYM
{
Lex->sql_command= SQLCOM_SELECT;
}
select_part3;
select_part2: select_part2:
{ {
...@@ -1349,6 +1356,15 @@ select_part2: ...@@ -1349,6 +1356,15 @@ select_part2:
} }
select_options select_item_list select_into select_lock_type union 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: select_into:
limit_clause {} limit_clause {}
| select_from | select_from
...@@ -3480,7 +3496,11 @@ rollback: ...@@ -3480,7 +3496,11 @@ rollback:
union: union:
/* empty */ {} /* empty */
{
if (Lex->select->braces || Select->linkage == NOT_A_SELECT)
YYABORT;
}
| union_list | union_list
union_list: union_list:
...@@ -3497,6 +3517,16 @@ union_list: ...@@ -3497,6 +3517,16 @@ union_list:
lex->select->linkage=UNION_TYPE; lex->select->linkage=UNION_TYPE;
} }
SELECT_SYM select_part2 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: 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