diff options
author | unknown <Sinisa@sinisa.nasamreza.org> | 2001-10-19 17:46:51 +0300 |
---|---|---|
committer | unknown <Sinisa@sinisa.nasamreza.org> | 2001-10-19 17:46:51 +0300 |
commit | f9b331ff8a647dbb689061ec1cc0a03d73b53446 (patch) | |
tree | ffa740e9e5f57bb711a2e6efb4a1928e20b968ea | |
parent | 61b7f807ad961ed24976757b1bf25ad74cec8d29 (diff) | |
parent | 7b440a7326886fdd35bcf59ae048194f87cb7cdf (diff) | |
download | mariadb-git-f9b331ff8a647dbb689061ec1cc0a03d73b53446.tar.gz |
Merge sinisa@work.mysql.com:/home/bk/mysql-4.0
into sinisa.nasamreza.org:/mnt/hdc/Sinisa/mysql-4.0
BitKeeper/etc/ignore:
auto-union
-rw-r--r-- | .bzrignore | 3 | ||||
-rw-r--r-- | sql/sql_delete.cc | 32 | ||||
-rw-r--r-- | sql/sql_lex.h | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_union.cc | 30 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 32 |
6 files changed, 85 insertions, 18 deletions
diff --git a/.bzrignore b/.bzrignore index ca408bae677..0703a1d2f25 100644 --- a/.bzrignore +++ b/.bzrignore @@ -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 diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 8ba293c82f9..b8d4f00533e 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -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; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 83652d1f818..9f9fe6c79b3 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -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; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e10214bc895..8d1835c7b90 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -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; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index c0ec6c81575..0d8a6dc4ed1 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -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: diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5dae9eeb3cb..4174e6ba345 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -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 */ {} |