summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authorunknown <serg@serg.mylan>2005-01-16 13:16:23 +0100
committerunknown <serg@serg.mylan>2005-01-16 13:16:23 +0100
commit88bd301d36dd00735f6380d37a93594cc8539fe1 (patch)
tree58ca68b7179b2df96e7b2f14a1da686cc9d2b959 /sql/sql_parse.cc
parent83e58bc0eaa2856e54b08c84417192b07db68a86 (diff)
downloadmariadb-git-88bd301d36dd00735f6380d37a93594cc8539fe1.tar.gz
XA (not completely polished out yet)
include/my_pthread.h: cleanup. don't use gcc extensions innobase/include/trx0sys.ic: Jan's fix for innobase_xa_prepare innobase/read/read0read.c: Jan's fix for innobase_xa_prepare innobase/trx/trx0trx.c: Jan's fix for innobase_xa_prepare mysql-test/include/varchar.inc: test fix mysql-test/r/ctype_ucs.result: new log event - all binlog positions are changed :( mysql-test/r/drop_temp_table.result: new log event - all binlog positions are changed :( mysql-test/r/insert_select.result: new log event - all binlog positions are changed :( mysql-test/r/mix_innodb_myisam_binlog.result: new log event - all binlog positions are changed :( mysql-test/r/myisam.result: test fix mysql-test/r/rpl000015.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_change_master.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_charset.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_error_ignored_table.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_flush_log_loop.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_flush_tables.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_loaddata.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_loaddata_rule_m.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_loaddata_rule_s.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_log.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_log_pos.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_max_relay_size.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_relayrotate.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_replicate_do.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_reset_slave.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_rotate_logs.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_server_id1.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_server_id2.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_temporary.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_timezone.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_until.result: new log event - all binlog positions are changed :( mysql-test/r/rpl_user_variables.result: new log event - all binlog positions are changed :( mysql-test/r/user_var.result: new log event - all binlog positions are changed :( mysql-test/t/ctype_ucs.test: new log event - all binlog positions are changed :( mysql-test/t/mix_innodb_myisam_binlog.test: new log event - all binlog positions are changed :( mysql-test/t/mysqlbinlog.test: new log event - all binlog positions are changed :( mysql-test/t/mysqlbinlog2.test: new log event - all binlog positions are changed :( mysql-test/t/rpl_charset.test: new log event - all binlog positions are changed :( mysql-test/t/rpl_error_ignored_table.test: new log event - all binlog positions are changed :( mysql-test/t/rpl_loaddata_rule_m.test: new log event - all binlog positions are changed :( mysql-test/t/rpl_loaddata_rule_s.test: new log event - all binlog positions are changed :( mysql-test/t/rpl_log.test: new log event - all binlog positions are changed :( mysql-test/t/rpl_log_pos.test: new log event - all binlog positions are changed :( mysql-test/t/rpl_user_variables.test: new log event - all binlog positions are changed :( mysql-test/t/user_var.test: new log event - all binlog positions are changed :( mysys/hash.c: typo fixed sql/ha_berkeley.cc: handlerton framework sql/ha_berkeley.h: handlerton framework sql/ha_innodb.cc: handlerton framework sql/ha_innodb.h: handlerton framework sql/handler.cc: new transaction handling, handlerton framework, two-phase commit, XA support sql/handler.h: new transaction handling, handlerton framework, two-phase commit, XA support sql/lex.h: XA commands sql/log.cc: new transaction handling, handlerton framework, two-phase commit, XA support, tc-logging, TC_LOG_MMAP class sql/log_event.cc: Xid_log_event sql/log_event.h: Xid_log_event, LOG_EVENT_BINLOG_CLOSED_F flag sql/mysql_priv.h: wrapper for query_id++ sql/mysqld.cc: new command-line options --log-tc, --log-tc-size, --tc-heuristic-recover, new status variables Tc_log_page_size, Tc_log_max_pages_used, Tc_log_page_waits. init/stop tc logging sql/set_var.h: warning fixed sql/share/errmsg.txt: XA error messages sql/sp_head.cc: s/query_id++/next_query_id()/ sql/sql_base.cc: typo fixed. new transaction handling. sql/sql_class.cc: cleanup of THD.transaction sql/sql_class.h: TC_LOG classes, new status variables, new savepoint handling, XA support sql/sql_insert.cc: comments sql/sql_lex.cc: s/found_colon/found_semicolon/ sql/sql_lex.h: SQLCOM_XA_xxx, XA related changes in Lex sql/sql_parse.cc: cleanup, XA commands, new savepoint handling sql/sql_repl.cc: two functions moved to log.cc sql/sql_repl.h: two functions moved to log.cc sql/sql_trigger.cc: s/lex.name_and_length/lex.ident/ sql/sql_yacc.yy: XA commands, cleanup
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc343
1 files changed, 256 insertions, 87 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 78b453ae46b..f0559204559 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -535,23 +535,23 @@ void init_update_queries(void)
uc_update_queries[SQLCOM_CREATE_TABLE]=1;
uc_update_queries[SQLCOM_CREATE_INDEX]=1;
uc_update_queries[SQLCOM_ALTER_TABLE]=1;
- uc_update_queries[SQLCOM_UPDATE]=1;
- uc_update_queries[SQLCOM_INSERT]=1;
- uc_update_queries[SQLCOM_INSERT_SELECT]=1;
- uc_update_queries[SQLCOM_DELETE]=1;
+ uc_update_queries[SQLCOM_UPDATE]=2;
+ uc_update_queries[SQLCOM_UPDATE_MULTI]=2;
+ uc_update_queries[SQLCOM_INSERT]=2;
+ uc_update_queries[SQLCOM_INSERT_SELECT]=2;
+ uc_update_queries[SQLCOM_DELETE]=2;
+ uc_update_queries[SQLCOM_DELETE_MULTI]=2;
uc_update_queries[SQLCOM_TRUNCATE]=1;
uc_update_queries[SQLCOM_DROP_TABLE]=1;
uc_update_queries[SQLCOM_LOAD]=1;
uc_update_queries[SQLCOM_CREATE_DB]=1;
uc_update_queries[SQLCOM_DROP_DB]=1;
- uc_update_queries[SQLCOM_REPLACE]=1;
- uc_update_queries[SQLCOM_REPLACE_SELECT]=1;
+ uc_update_queries[SQLCOM_REPLACE]=2;
+ uc_update_queries[SQLCOM_REPLACE_SELECT]=2;
uc_update_queries[SQLCOM_RENAME_TABLE]=1;
uc_update_queries[SQLCOM_BACKUP_TABLE]=1;
uc_update_queries[SQLCOM_RESTORE_TABLE]=1;
- uc_update_queries[SQLCOM_DELETE_MULTI]=1;
uc_update_queries[SQLCOM_DROP_INDEX]=1;
- uc_update_queries[SQLCOM_UPDATE_MULTI]=1;
uc_update_queries[SQLCOM_CREATE_VIEW]=1;
uc_update_queries[SQLCOM_DROP_VIEW]=1;
}
@@ -559,7 +559,7 @@ void init_update_queries(void)
bool is_update_query(enum enum_sql_command command)
{
DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
- return uc_update_queries[command];
+ return uc_update_queries[command] > 0;
}
/*
@@ -1147,24 +1147,25 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
We don't need to obtain LOCK_thread_count here because in bootstrap
mode we have only one thread.
*/
- thd->query_id=query_id++;
- if (mqh_used && thd->user_connect && check_mqh(thd, SQLCOM_END))
- {
- thd->net.error = 0;
- close_thread_tables(thd); // Free tables
- free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
- break;
- }
+ thd->query_id=next_query_id();
mysql_parse(thd,thd->query,length);
close_thread_tables(thd); // Free tables
if (thd->is_fatal_error)
break;
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
+#ifdef USING_TRANSACTIONS
free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
+#endif
}
/* thd->fatal_error should be set in case something went wrong */
end:
+ bootstrap_error= thd->is_fatal_error;
+
+ net_end(&thd->net);
+ thd->cleanup();
+ delete thd;
+
#ifndef EMBEDDED_LIBRARY
(void) pthread_mutex_lock(&LOCK_thread_count);
thread_count--;
@@ -1173,7 +1174,7 @@ end:
my_thread_end();
pthread_exit(0);
#endif
- DBUG_RETURN(0); // Never reached
+ DBUG_RETURN(0);
}
/* This works because items are allocated with sql_alloc() */
@@ -1239,7 +1240,6 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
my_error(ER_GET_ERRNO, MYF(0), error);
err:
- close_thread_tables(thd);
DBUG_RETURN(error);
}
@@ -1355,7 +1355,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id=query_id;
if (command != COM_STATISTICS && command != COM_PING)
- query_id++;
+ next_query_id();
thread_running++;
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count));
@@ -1511,9 +1511,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
DBUG_PRINT("query",("%-.4096s",thd->query));
mysql_parse(thd,thd->query, thd->query_length);
- while (!thd->killed && thd->lex->found_colon && !thd->net.report_error)
+ while (!thd->killed && thd->lex->found_semicolon && !thd->net.report_error)
{
- char *packet= thd->lex->found_colon;
+ char *packet= thd->lex->found_semicolon;
/*
Multiple queries exits, execute them individually
in embedded server - just store them to be executed later
@@ -1533,7 +1533,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_length= length;
thd->query= packet;
- thd->query_id= query_id++;
+ thd->query_id= next_query_id();
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count));
#ifndef EMBEDDED_LIBRARY
@@ -1845,6 +1845,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->proc_info="closing tables";
close_thread_tables(thd); /* Free tables */
}
+ /*
+ assume handlers auto-commit (if some doesn't - transaction handling
+ in MySQL should be redesigned to support it; it's a big change,
+ and it's not worth it - better to commit explicitly only writing
+ transactions, read-only ones should better take care of themselves.
+ saves some work in 2pc too)
+ see also sql_base.cc - close_thread_tables()
+ */
+ bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt));
+ if (!thd->active_transaction())
+ thd->transaction.xid.null();
/* report error issued during command execution */
if (thd->killed_errno() && !thd->net.report_error)
@@ -2407,7 +2418,7 @@ mysql_execute_command(THD *thd)
{
if (check_global_access(thd, REPL_SLAVE_ACL))
goto error;
- res = show_binlog_events(thd);
+ res = mysql_show_binlog_events(thd);
break;
}
#endif
@@ -2442,7 +2453,7 @@ mysql_execute_command(THD *thd)
check_access(thd, INDEX_ACL, first_table->db,
&first_table->grant.privilege, 0, 0))
goto error;
- res= mysql_assign_to_keycache(thd, first_table, &lex->name_and_length);
+ res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
break;
}
case SQLCOM_PRELOAD_KEYS:
@@ -3056,7 +3067,7 @@ create_error:
first_table->ancestor && first_table->ancestor->next_local);
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
first_table->view_db.str, first_table->view_name.str);
- res= -1;
+ res= FALSE;
break;
}
@@ -3080,7 +3091,6 @@ create_error:
}
else
res= TRUE;
- close_thread_tables(thd);
break;
}
case SQLCOM_DROP_TABLE:
@@ -3375,12 +3385,6 @@ create_error:
}
if (check_access(thd,SELECT_ACL,lex->name,0,1,0))
break;
- if (thd->locked_tables || thd->active_transaction())
- {
- my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
- ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
- goto error;
- }
res=mysqld_show_create_db(thd,lex->name,&lex->create_info);
break;
}
@@ -3611,18 +3615,12 @@ create_error:
*/
if (check_db_used(thd, all_tables))
goto error;
- res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->backup_dir,
+ res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
select_lex->select_limit, select_lex->offset_limit);
break;
case SQLCOM_BEGIN:
- if (thd->locked_tables)
- {
- thd->lock=thd->locked_tables;
- thd->locked_tables=0; // Will be automatically closed
- close_thread_tables(thd); // Free tables
- }
if (end_active_trans(thd))
goto error;
else
@@ -3634,6 +3632,7 @@ create_error:
!(res= ha_start_consistent_snapshot(thd)))
send_ok(thd);
}
+ unlock_locked_tables(thd); // imply UNLOCK TABLES
break;
case SQLCOM_COMMIT:
/*
@@ -3654,29 +3653,27 @@ create_error:
}
case SQLCOM_ROLLBACK:
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
- if (!ha_rollback(thd))
- {
- /*
- If a non-transactional table was updated, warn; don't warn if this is a
- slave thread (because when a slave thread executes a ROLLBACK, it has
- been read from the binary log, so it's 100% sure and normal to produce
- error ER_WARNING_NOT_COMPLETE_ROLLBACK. If we sent the warning to the
- slave SQL thread, it would not stop the thread but just be printed in
- the error log; but we don't want users to wonder why they have this
- message in the error log, so we don't send it.
- */
- if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread)
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARNING_NOT_COMPLETE_ROLLBACK,
- ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
- send_ok(thd);
- }
- else
+ if (ha_rollback(thd))
res= TRUE;
+ else
+ send_ok(thd);
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
break;
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
- if (!ha_rollback_to_savepoint(thd, lex->savepoint_name))
+ {
+ SAVEPOINT **sv;
+ for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
+ {
+ if (my_strnncoll(system_charset_info,
+ (uchar *)lex->ident.str, lex->ident.length,
+ (uchar *)(*sv)->name, (*sv)->length) == 0)
+ break;
+ }
+ if (*sv)
+ {
+ if (ha_rollback_to_savepoint(thd, *sv))
+ res= TRUE; // cannot happen
+ else
{
if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
@@ -3684,14 +3681,59 @@ create_error:
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
send_ok(thd);
}
+ *sv= 0;
+ }
else
- goto error;
+ {
+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
+ res= TRUE;
+ }
break;
+ }
case SQLCOM_SAVEPOINT:
- if (!ha_savepoint(thd, lex->savepoint_name))
+ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
+ !opt_using_transactions)
send_ok(thd);
else
- goto error;
+ {
+ SAVEPOINT **sv, *newsv;
+ for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
+ {
+ if (my_strnncoll(system_charset_info,
+ (uchar *)lex->ident.str, lex->ident.length,
+ (uchar *)(*sv)->name, (*sv)->length) == 0)
+ break;
+ }
+ if (*sv) /* old savepoint of the same name exists */
+ {
+ newsv=*sv;
+ ha_release_savepoint(thd, *sv); // it cannot fail
+ *sv=(*sv)->prev;
+ }
+ else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
+ savepoint_alloc_size)) == 0)
+ {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ res= TRUE;
+ break;
+ }
+ newsv->name=strmake_root(&thd->transaction.mem_root,
+ lex->ident.str, lex->ident.length);
+ newsv->length=lex->ident.length;
+ /*
+ if we'll get an error here, don't add new savepoint to the list.
+ we'll lose a little bit of memory in transaction mem_root, but it'll
+ be free'd when transaction ends anyway
+ */
+ if (ha_savepoint(thd, newsv))
+ res= TRUE;
+ else
+ {
+ newsv->prev=thd->transaction.savepoints;
+ thd->transaction.savepoints=newsv;
+ send_ok(thd);
+ }
+ }
break;
case SQLCOM_CREATE_PROCEDURE:
case SQLCOM_CREATE_SPFUNCTION:
@@ -4013,7 +4055,156 @@ create_error:
res= mysql_create_or_drop_trigger(thd, all_tables, 0);
break;
}
- default: /* Impossible */
+ case SQLCOM_XA_START:
+ res= FALSE;
+ if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_RESUME)
+ {
+ if (! thd->transaction.xid.eq(&thd->lex->ident))
+ {
+ my_error(ER_XAER_NOTA, MYF(0));
+ break;
+ }
+ thd->transaction.xa_state=XA_ACTIVE;
+ send_ok(thd);
+ res=0;
+ break;
+ }
+ if (thd->lex->ident.length > MAXGTRIDSIZE || thd->lex->xa_opt != XA_NONE)
+ { // JOIN is not supported yet. TODO
+ my_error(ER_XAER_INVAL, MYF(0));
+ break;
+ }
+ if (thd->transaction.xa_state != XA_NOTR)
+ {
+ my_error(ER_XAER_RMFAIL, MYF(0));
+ break;
+ }
+ if (thd->active_transaction() || thd->locked_tables)
+ {
+ my_error(ER_XAER_OUTSIDE, MYF(0));
+ break;
+ }
+ DBUG_ASSERT(thd->transaction.xid.is_null());
+ thd->transaction.xa_state=XA_ACTIVE;
+ thd->transaction.xid.set(&thd->lex->ident);
+ thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
+ OPTION_BEGIN);
+ thd->server_status|= SERVER_STATUS_IN_TRANS;
+ send_ok(thd);
+ res=0;
+ break;
+ case SQLCOM_XA_END:
+ /* fake it */
+ res= FALSE;
+ if (thd->lex->xa_opt != XA_NONE)
+ { // SUSPEND and FOR MIGRATE are not supported yet. TODO
+ my_error(ER_XAER_INVAL, MYF(0));
+ break;
+ }
+ if (thd->transaction.xa_state != XA_ACTIVE)
+ {
+ my_error(ER_XAER_RMFAIL, MYF(0));
+ break;
+ }
+ if (!thd->transaction.xid.eq(&thd->lex->ident))
+ {
+ my_error(ER_XAER_NOTA, MYF(0));
+ break;
+ }
+ thd->transaction.xa_state=XA_IDLE;
+ send_ok(thd);
+ res=0;
+ break;
+ case SQLCOM_XA_PREPARE:
+ res= FALSE;
+ if (thd->transaction.xa_state != XA_IDLE)
+ {
+ my_error(ER_XAER_RMFAIL, MYF(0));
+ break;
+ }
+ if (!thd->transaction.xid.eq(&thd->lex->ident))
+ {
+ my_error(ER_XAER_NOTA, MYF(0));
+ break;
+ }
+ if (ha_prepare(thd))
+ {
+ my_error(ER_XA_RBROLLBACK, MYF(0));
+ thd->transaction.xa_state=XA_NOTR;
+ break;
+ }
+ res=0;
+ thd->transaction.xa_state=XA_PREPARED;
+ send_ok(thd);
+ break;
+ case SQLCOM_XA_COMMIT:
+ if (!thd->transaction.xid.eq(&thd->lex->ident))
+ {
+ if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 1)))
+ my_error(ER_XAER_NOTA, MYF(0));
+ break;
+ }
+ if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE)
+ {
+ if (res=ha_commit(thd))
+ {
+ my_error(res==1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
+ res= FALSE;
+ }
+ else
+ send_ok(thd);
+ }
+ else
+ if (thd->transaction.xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE)
+ {
+ if (ha_commit_one_phase(thd, 1))
+ {
+ my_error(ER_XAER_RMERR, MYF(0));
+ res= FALSE;
+ }
+ else
+ send_ok(thd);
+ }
+ else
+ {
+ res= FALSE;
+ my_error(ER_XAER_RMFAIL, MYF(0));
+ break;
+ }
+ thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
+ thd->transaction.xa_state=XA_NOTR;
+ break;
+ case SQLCOM_XA_ROLLBACK:
+ if (!thd->transaction.xid.eq(&thd->lex->ident))
+ {
+ if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 0)))
+ my_error(ER_XAER_NOTA, MYF(0));
+ break;
+ }
+ if (thd->transaction.xa_state != XA_IDLE &&
+ thd->transaction.xa_state != XA_PREPARED)
+ {
+ res= FALSE;
+ my_error(ER_XAER_RMFAIL, MYF(0));
+ break;
+ }
+ if (ha_rollback(thd))
+ {
+ my_error(ER_XAER_RMERR, MYF(0));
+ res= FALSE;
+ }
+ else
+ send_ok(thd);
+ thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
+ thd->transaction.xa_state=XA_NOTR;
+ break;
+ case SQLCOM_XA_RECOVER:
+ res= mysql_xa_recover(thd);
+ break;
+ default:
+ DBUG_ASSERT(0); /* Impossible */
send_ok(thd);
break;
}
@@ -4048,20 +4239,8 @@ create_error:
the statement is not DELETE, INSERT or UPDATE (or a CALL executing
such a statement), but -1 is what JDBC and ODBC wants.
*/
- switch (lex->sql_command) {
- case SQLCOM_UPDATE:
- case SQLCOM_UPDATE_MULTI:
- case SQLCOM_REPLACE:
- case SQLCOM_INSERT:
- case SQLCOM_REPLACE_SELECT:
- case SQLCOM_INSERT_SELECT:
- case SQLCOM_DELETE:
- case SQLCOM_DELETE_MULTI:
- case SQLCOM_CALL:
- break;
- default:
+ if (lex->sql_command != SQLCOM_CALL && uc_update_queries[lex->sql_command]<2)
thd->row_count_func= -1;
- }
DBUG_RETURN(res || thd->net.report_error);
@@ -4830,17 +5009,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
new_field->charset=cs;
new_field->geom_type= (Field::geometry_type) uint_geom_type;
- if (!comment)
- {
- new_field->comment.str=0;
- new_field->comment.length=0;
- }
- else
- {
- /* In this case comment is always of type Item_string */
- new_field->comment.str= (char*) comment->str;
- new_field->comment.length=comment->length;
- }
+ new_field->comment=*comment;
/*
Set flag if this field doesn't have a default value
Enum values has always the first value as a default (set in