468
539
variables, but for now this is probably good enough.
469
540
Don't reset warnings when executing a stored routine.
471
if (all_tables || ! lex->is_single_level_stmt())
542
if (all_tables || !lex->is_single_level_stmt())
473
543
drizzle_reset_errors(session, 0);
476
assert(session->transaction.stmt.hasModifiedNonTransData() == false);
478
/* now we are ready to execute the statement */
479
res= lex->statement->execute();
545
status_var_increment(session->status_var.com_stat[lex->sql_command]);
547
assert(session->transaction.stmt.modified_non_trans_table == false);
549
switch (lex->sql_command) {
550
case SQLCOM_SHOW_STATUS:
552
system_status_var old_status_var= session->status_var;
553
session->initial_status_var= &old_status_var;
554
res= execute_sqlcom_select(session, all_tables);
555
/* Don't log SHOW STATUS commands to slow query log */
556
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
557
SERVER_QUERY_NO_GOOD_INDEX_USED);
559
restore status variables, as we don't want 'show status' to cause
562
pthread_mutex_lock(&LOCK_status);
563
add_diff_to_status(&global_status_var, &session->status_var,
565
session->status_var= old_status_var;
566
pthread_mutex_unlock(&LOCK_status);
569
case SQLCOM_SHOW_DATABASES:
570
case SQLCOM_SHOW_TABLES:
571
case SQLCOM_SHOW_TABLE_STATUS:
572
case SQLCOM_SHOW_OPEN_TABLES:
573
case SQLCOM_SHOW_FIELDS:
574
case SQLCOM_SHOW_KEYS:
575
case SQLCOM_SHOW_VARIABLES:
578
session->status_var.last_query_cost= 0.0;
579
res= execute_sqlcom_select(session, all_tables);
582
case SQLCOM_EMPTY_QUERY:
586
case SQLCOM_SHOW_WARNS:
588
res= mysqld_show_warnings(session, (uint32_t)
589
((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
590
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
591
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
595
case SQLCOM_SHOW_ERRORS:
597
res= mysqld_show_warnings(session, (uint32_t)
598
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
601
case SQLCOM_ASSIGN_TO_KEYCACHE:
603
assert(first_table == all_tables && first_table != 0);
604
res= mysql_assign_to_keycache(session, first_table, &lex->ident);
607
case SQLCOM_SHOW_ENGINE_STATUS:
609
res = ha_show_status(session, lex->create_info.db_type, HA_ENGINE_STATUS);
612
case SQLCOM_CREATE_TABLE:
614
/* If CREATE TABLE of non-temporary table, do implicit commit */
615
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
617
if (! session->endActiveTransaction())
623
assert(first_table == all_tables && first_table != 0);
625
// Skip first table, which is the table we are creating
626
TableList *create_table= lex->unlink_first_table(&link_to_local);
627
TableList *select_tables= lex->query_tables;
629
Code below (especially in mysql_create_table() and select_create
630
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
631
use a copy of this structure to make execution prepared statement-
632
safe. A shallow copy is enough as this code won't modify any memory
633
referenced from this structure.
635
HA_CREATE_INFO create_info(lex->create_info);
637
We need to copy alter_info for the same reasons of re-execution
638
safety, only in case of Alter_info we have to do (almost) a deep
641
Alter_info alter_info(lex->alter_info, session->mem_root);
643
if (session->is_fatal_error)
645
/* If out of memory when creating a copy of alter_info. */
647
goto end_with_restore_list;
650
if ((res= create_table_precheck(session, select_tables, create_table)))
651
goto end_with_restore_list;
653
/* Might have been updated in create_table_precheck */
654
create_info.alias= create_table->alias;
657
/* Fix names if symlinked tables */
658
if (append_file_to_dir(session, &create_info.data_file_name,
659
create_table->table_name) ||
660
append_file_to_dir(session, &create_info.index_file_name,
661
create_table->table_name))
662
goto end_with_restore_list;
665
The create-select command will open and read-lock the select table
666
and then create, open and write-lock the new table. If a global
667
read lock steps in, we get a deadlock. The write lock waits for
668
the global read lock, while the global read lock waits for the
669
select table to be closed. So we wait until the global readlock is
670
gone before starting both steps. Note that
671
wait_if_global_read_lock() sets a protection against a new global
672
read lock when it succeeds. This needs to be released by
673
start_waiting_global_read_lock(). We protect the normal CREATE
674
TABLE in the same way. That way we avoid that a new table is
675
created during a gobal read lock.
677
if (!session->locked_tables &&
678
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
681
goto end_with_restore_list;
683
if (select_lex->item_list.elements) // With select
685
select_result *result;
687
select_lex->options|= SELECT_NO_UNLOCK;
688
unit->set_limit(select_lex);
690
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
692
lex->link_first_table_back(create_table, link_to_local);
693
create_table->create= true;
696
if (!(res= open_and_lock_tables(session, lex->query_tables)))
699
Is table which we are changing used somewhere in other parts
702
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
704
TableList *duplicate;
705
create_table= lex->unlink_first_table(&link_to_local);
706
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
708
update_non_unique_table_error(create_table, "CREATE", duplicate);
710
goto end_with_restore_list;
715
select_create is currently not re-execution friendly and
716
needs to be created for every execution of a PS/SP.
718
if ((result= new select_create(create_table,
721
select_lex->item_list,
727
CREATE from SELECT give its Select_Lex for SELECT,
728
and item_list belong to SELECT
730
res= handle_select(session, lex, result, 0);
734
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
735
create_table= lex->unlink_first_table(&link_to_local);
740
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
741
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
742
session->options|= OPTION_KEEP_LOG;
744
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
745
res= mysql_create_like_table(session, create_table, select_tables,
749
res= mysql_create_table(session, create_table->db,
750
create_table->table_name, &create_info,
757
/* put tables back for PS rexecuting */
758
end_with_restore_list:
759
lex->link_first_table_back(create_table, link_to_local);
762
case SQLCOM_CREATE_INDEX:
764
case SQLCOM_DROP_INDEX:
766
CREATE INDEX and DROP INDEX are implemented by calling ALTER
767
TABLE with proper arguments.
769
In the future ALTER TABLE will notice that the request is to
770
only add indexes and create these one by one for the existing
771
table without having to do a full rebuild.
774
/* Prepare stack copies to be re-execution safe */
775
HA_CREATE_INFO create_info;
776
Alter_info alter_info(lex->alter_info, session->mem_root);
778
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
781
assert(first_table == all_tables && first_table != 0);
782
if (! session->endActiveTransaction())
785
memset(&create_info, 0, sizeof(create_info));
786
create_info.db_type= 0;
787
create_info.row_type= ROW_TYPE_NOT_USED;
788
create_info.default_table_charset= session->variables.collation_database;
790
res= mysql_alter_table(session, first_table->db, first_table->table_name,
791
&create_info, first_table, &alter_info,
792
0, (order_st*) 0, 0);
795
case SQLCOM_ALTER_TABLE:
796
assert(first_table == all_tables && first_table != 0);
799
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
800
so we have to use a copy of this structure to make execution
801
prepared statement- safe. A shallow copy is enough as no memory
802
referenced from this structure will be modified.
804
HA_CREATE_INFO create_info(lex->create_info);
805
Alter_info alter_info(lex->alter_info, session->mem_root);
807
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
812
/* Must be set in the parser */
813
assert(select_lex->db);
817
memset(&tmp_table, 0, sizeof(tmp_table));
818
tmp_table.table_name= lex->name.str;
819
tmp_table.db=select_lex->db;
822
/* Don't yet allow changing of symlinks with ALTER TABLE */
823
if (create_info.data_file_name)
824
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
825
"DATA DIRECTORY option ignored");
826
if (create_info.index_file_name)
827
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
828
"INDEX DIRECTORY option ignored");
829
create_info.data_file_name= create_info.index_file_name= NULL;
830
/* ALTER TABLE ends previous transaction */
831
if (! session->endActiveTransaction())
834
if (!session->locked_tables &&
835
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
841
res= mysql_alter_table(session, select_lex->db, lex->name.str,
845
select_lex->order_list.elements,
846
(order_st *) select_lex->order_list.first,
850
case SQLCOM_RENAME_TABLE:
852
assert(first_table == all_tables && first_table != 0);
854
for (table= first_table; table; table= table->next_local->next_local)
856
TableList old_list, new_list;
858
we do not need initialize old_list and new_list because we will
859
come table[0] and table->next[0] there
862
new_list= table->next_local[0];
865
if (! session->endActiveTransaction() || drizzle_rename_tables(session, first_table, 0))
871
case SQLCOM_SHOW_CREATE:
872
assert(first_table == all_tables && first_table != 0);
874
res= drizzled_show_create(session, first_table);
877
case SQLCOM_CHECKSUM:
879
assert(first_table == all_tables && first_table != 0);
880
res = mysql_checksum_table(session, first_table, &lex->check_opt);
885
assert(first_table == all_tables && first_table != 0);
886
res= mysql_repair_table(session, first_table, &lex->check_opt);
887
/* ! we write after unlocking the table */
889
Presumably, REPAIR and binlog writing doesn't require synchronization
891
write_bin_log(session, true, session->query, session->query_length);
892
select_lex->table_list.first= (unsigned char*) first_table;
893
lex->query_tables=all_tables;
898
assert(first_table == all_tables && first_table != 0);
899
res = mysql_check_table(session, first_table, &lex->check_opt);
900
select_lex->table_list.first= (unsigned char*) first_table;
901
lex->query_tables=all_tables;
906
assert(first_table == all_tables && first_table != 0);
907
res= mysql_analyze_table(session, first_table, &lex->check_opt);
908
/* ! we write after unlocking the table */
909
write_bin_log(session, true, session->query, session->query_length);
910
select_lex->table_list.first= (unsigned char*) first_table;
911
lex->query_tables=all_tables;
915
case SQLCOM_OPTIMIZE:
917
assert(first_table == all_tables && first_table != 0);
918
res= mysql_optimize_table(session, first_table, &lex->check_opt);
919
/* ! we write after unlocking the table */
920
write_bin_log(session, true, session->query, session->query_length);
921
select_lex->table_list.first= (unsigned char*) first_table;
922
lex->query_tables=all_tables;
926
assert(first_table == all_tables && first_table != 0);
927
if ((res= update_precheck(session, all_tables)))
929
assert(select_lex->offset_limit == 0);
930
unit->set_limit(select_lex);
931
res= mysql_update(session, all_tables,
932
select_lex->item_list,
935
select_lex->order_list.elements,
936
(order_st *) select_lex->order_list.first,
937
unit->select_limit_cnt,
938
lex->duplicates, lex->ignore);
940
case SQLCOM_UPDATE_MULTI:
942
assert(first_table == all_tables && first_table != 0);
943
if ((res= update_precheck(session, all_tables)))
946
if ((res= mysql_multi_update_prepare(session)))
949
res= mysql_multi_update(session, all_tables,
950
&select_lex->item_list,
954
lex->duplicates, lex->ignore, unit, select_lex);
960
assert(first_table == all_tables && first_table != 0);
961
if ((res= insert_precheck(session, all_tables)))
964
if (!session->locked_tables &&
965
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
971
res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
972
lex->update_list, lex->value_list,
973
lex->duplicates, lex->ignore);
977
case SQLCOM_REPLACE_SELECT:
978
case SQLCOM_INSERT_SELECT:
980
select_result *sel_result;
981
assert(first_table == all_tables && first_table != 0);
982
if ((res= insert_precheck(session, all_tables)))
985
/* Fix lock for first table */
986
if (first_table->lock_type == TL_WRITE_DELAYED)
987
first_table->lock_type= TL_WRITE;
989
/* Don't unlock tables until command is written to binary log */
990
select_lex->options|= SELECT_NO_UNLOCK;
992
unit->set_limit(select_lex);
994
if (! session->locked_tables &&
995
! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
1001
if (!(res= open_and_lock_tables(session, all_tables)))
1003
/* Skip first table, which is the table we are inserting in */
1004
TableList *second_table= first_table->next_local;
1005
select_lex->table_list.first= (unsigned char*) second_table;
1006
select_lex->context.table_list=
1007
select_lex->context.first_name_resolution_table= second_table;
1008
res= mysql_insert_select_prepare(session);
1009
if (!res && (sel_result= new select_insert(first_table,
1017
res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
1019
Invalidate the table in the query cache if something changed
1020
after unlocking when changes become visible.
1021
TODO: this is workaround. right way will be move invalidating in
1022
the unlock procedure.
1024
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
1027
/* INSERT ... SELECT should invalidate only the very first table */
1028
TableList *save_table= first_table->next_local;
1029
first_table->next_local= 0;
1030
first_table->next_local= save_table;
1034
/* revert changes for SP */
1035
select_lex->table_list.first= (unsigned char*) first_table;
1040
case SQLCOM_TRUNCATE:
1041
if (! session->endActiveTransaction())
1046
assert(first_table == all_tables && first_table != 0);
1048
Don't allow this within a transaction because we want to use
1051
if (session->locked_tables || session->active_transaction())
1053
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1054
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1058
res= mysql_truncate(session, first_table, 0);
1063
assert(first_table == all_tables && first_table != 0);
1064
assert(select_lex->offset_limit == 0);
1065
unit->set_limit(select_lex);
1067
if (!session->locked_tables &&
1068
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1074
res = mysql_delete(session, all_tables, select_lex->where,
1075
&select_lex->order_list,
1076
unit->select_limit_cnt, select_lex->options,
1080
case SQLCOM_DELETE_MULTI:
1082
assert(first_table == all_tables && first_table != 0);
1083
TableList *aux_tables=
1084
(TableList *)session->lex->auxiliary_table_list.first;
1085
multi_delete *del_result;
1087
if (!session->locked_tables &&
1088
!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1094
if ((res= multi_delete_precheck(session, all_tables)))
1097
/* condition will be true on SP re-excuting */
1098
if (select_lex->item_list.elements != 0)
1099
select_lex->item_list.empty();
1100
if (session->add_item_to_list(new Item_null()))
1103
session->set_proc_info("init");
1104
if ((res= open_and_lock_tables(session, all_tables)))
1107
if ((res= mysql_multi_delete_prepare(session)))
1110
if (!session->is_fatal_error &&
1111
(del_result= new multi_delete(aux_tables, lex->table_count)))
1113
res= mysql_select(session, &select_lex->ref_pointer_array,
1114
select_lex->get_table_list(),
1115
select_lex->with_wild,
1116
select_lex->item_list,
1118
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
1119
select_lex->options | session->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE,
1120
del_result, unit, select_lex);
1121
res|= session->is_error();
1123
del_result->abort();
1130
case SQLCOM_DROP_TABLE:
1132
assert(first_table == all_tables && first_table != 0);
1133
if (!lex->drop_temporary)
1135
if (! session->endActiveTransaction())
1140
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
1141
session->options|= OPTION_KEEP_LOG;
1143
/* DDL and binlog write order protected by LOCK_open */
1144
res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
1147
case SQLCOM_SHOW_PROCESSLIST:
1148
mysqld_list_processes(session, NULL, lex->verbose);
1150
case SQLCOM_SHOW_ENGINE_LOGS:
1152
res= ha_show_status(session, lex->create_info.db_type, HA_ENGINE_LOGS);
1155
case SQLCOM_CHANGE_DB:
1157
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
1159
if (!mysql_change_db(session, &db_str, false))
1167
assert(first_table == all_tables && first_table != 0);
1168
res= mysql_load(session, lex->exchange, first_table, lex->field_list,
1169
lex->update_list, lex->value_list, lex->duplicates, lex->ignore);
1173
case SQLCOM_SET_OPTION:
1175
List<set_var_base> *lex_var_list= &lex->var_list;
1177
if (lex->autocommit && ! session->endActiveTransaction())
1180
if (open_and_lock_tables(session, all_tables))
1182
if (!(res= sql_set_variables(session, lex_var_list)))
1189
We encountered some sort of error, but no message was sent.
1190
Send something semi-generic here since we don't know which
1191
assignment in the list caused the error.
1193
if (!session->is_error())
1194
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
1201
case SQLCOM_UNLOCK_TABLES:
1203
It is critical for mysqldump --single-transaction --master-data that
1204
UNLOCK TABLES does not implicitely commit a connection which has only
1205
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
1206
false, mysqldump will not work.
1208
unlock_locked_tables(session);
1209
if (session->options & OPTION_TABLE_LOCK)
1211
(void) session->endActiveTransaction();
1212
session->options&= ~(OPTION_TABLE_LOCK);
1214
if (session->global_read_lock)
1215
unlock_global_read_lock(session);
1218
case SQLCOM_LOCK_TABLES:
1220
We try to take transactional locks if
1221
- only transactional locks are requested (lex->lock_transactional) and
1222
- no non-transactional locks exist (!session->locked_tables).
1224
if (lex->lock_transactional && !session->locked_tables)
1228
All requested locks are transactional and no non-transactional
1231
if ((rc= try_transactional_lock(session, all_tables)) == -1)
1239
Non-transactional locking has been requested or
1240
non-transactional locks exist already or transactional locks are
1241
not supported by all storage engines. Take non-transactional
1246
One or more requested locks are non-transactional and/or
1247
non-transactional locks exist or a storage engine does not support
1248
transactional locks. Check if at least one transactional lock is
1249
requested. If yes, warn about the conversion to non-transactional
1250
locks or abort in strict mode.
1252
if (check_transactional_lock(session, all_tables))
1254
unlock_locked_tables(session);
1255
/* we must end the trasaction first, regardless of anything */
1256
if (! session->endActiveTransaction())
1258
session->in_lock_tables=1;
1259
session->options|= OPTION_TABLE_LOCK;
1261
if (!(res= simple_open_n_lock_tables(session, all_tables)))
1263
session->locked_tables=session->lock;
1265
(void) set_handler_table_locks(session, all_tables, false);
1271
Need to end the current transaction, so the storage engine (InnoDB)
1272
can free its locks if LOCK TABLES locked some tables before finding
1273
that it can't lock a table in its list
1275
ha_autocommit_or_rollback(session, 1);
1276
(void) session->endActiveTransaction();
1277
session->options&= ~(OPTION_TABLE_LOCK);
1279
session->in_lock_tables=0;
1281
case SQLCOM_CREATE_DB:
1284
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
1285
it, we need to use a copy of LEX::create_info to make execution
1286
prepared statement- safe.
1288
HA_CREATE_INFO create_info(lex->create_info);
1289
if (! session->endActiveTransaction())
1295
if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
1296
check_db_name(&lex->name))
1298
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1301
res= mysql_create_db(session,(lower_case_table_names == 2 ? alias :
1302
lex->name.str), &create_info, 0);
1305
case SQLCOM_DROP_DB:
1307
if (! session->endActiveTransaction())
1312
if (check_db_name(&lex->name))
1314
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1317
if (session->locked_tables || session->active_transaction())
1319
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1320
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1323
res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists, 0);
1326
case SQLCOM_ALTER_DB:
1328
LEX_STRING *db= &lex->name;
1329
HA_CREATE_INFO create_info(lex->create_info);
1330
if (check_db_name(db))
1332
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
1335
if (session->locked_tables || session->active_transaction())
1337
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
1338
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1341
res= mysql_alter_db(session, db->str, &create_info);
1344
case SQLCOM_SHOW_CREATE_DB:
1346
if (check_db_name(&lex->name))
1348
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1351
res= mysqld_show_create_db(session, lex->name.str, &lex->create_info);
1356
bool write_to_binlog;
1359
reload_cache() will tell us if we are allowed to write to the
1362
if (!reload_cache(session, lex->type, first_table, &write_to_binlog))
1365
We WANT to write and we CAN write.
1366
! we write after unlocking the table.
1369
Presumably, RESET and binlog writing doesn't require synchronization
1371
write_bin_log(session, false, session->query, session->query_length);
1379
Item *it= (Item *)lex->value_list.head();
1381
if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
1383
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
1387
sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
1391
if (session->transaction.xid_state.xa_state != XA_NOTR)
1393
my_error(ER_XAER_RMFAIL, MYF(0),
1394
xa_state_names[session->transaction.xid_state.xa_state]);
1398
Breakpoints for backup testing.
1400
if (! session->startTransaction())
1405
if (! session->endTransaction(lex->tx_release ? COMMIT_RELEASE : lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
1409
case SQLCOM_ROLLBACK:
1410
if (! session->endTransaction(lex->tx_release ? ROLLBACK_RELEASE : lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
1414
case SQLCOM_RELEASE_SAVEPOINT:
1417
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
1419
if (my_strnncoll(system_charset_info,
1420
(unsigned char *)lex->ident.str, lex->ident.length,
1421
(unsigned char *)sv->name, sv->length) == 0)
1426
if (ha_release_savepoint(session, sv))
1427
res= true; // cannot happen
1430
session->transaction.savepoints=sv->prev;
1433
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
1436
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
1439
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
1441
if (my_strnncoll(system_charset_info,
1442
(unsigned char *)lex->ident.str, lex->ident.length,
1443
(unsigned char *)sv->name, sv->length) == 0)
1448
if (ha_rollback_to_savepoint(session, sv))
1449
res= true; // cannot happen
1452
if ((session->options & OPTION_KEEP_LOG) || session->transaction.all.modified_non_trans_table)
1453
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1454
ER_WARNING_NOT_COMPLETE_ROLLBACK,
1455
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1458
session->transaction.savepoints=sv;
1461
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
1464
case SQLCOM_SAVEPOINT:
1465
if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) || !opt_using_transactions)
1469
SAVEPOINT **sv, *newsv;
1470
for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
1472
if (my_strnncoll(system_charset_info,
1473
(unsigned char *)lex->ident.str, lex->ident.length,
1474
(unsigned char *)(*sv)->name, (*sv)->length) == 0)
1477
if (*sv) /* old savepoint of the same name exists */
1480
ha_release_savepoint(session, *sv); // it cannot fail
1483
else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
1484
savepoint_alloc_size)) == 0)
1486
my_error(ER_OUT_OF_RESOURCES, MYF(0));
1489
newsv->name=strmake_root(&session->transaction.mem_root,
1490
lex->ident.str, lex->ident.length);
1491
newsv->length=lex->ident.length;
1493
if we'll get an error here, don't add new savepoint to the list.
1494
we'll lose a little bit of memory in transaction mem_root, but it'll
1495
be free'd when transaction ends anyway
1497
if (ha_savepoint(session, newsv))
1501
newsv->prev=session->transaction.savepoints;
1502
session->transaction.savepoints=newsv;
1508
assert(0); /* Impossible */
480
1512
session->set_proc_info("query end");
482
1515
The return value for ROW_COUNT() is "implementation dependent" if the
483
1516
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
484
1517
wants. We also keep the last value in case of SQLCOM_CALL or
487
if (! (sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
1520
if (!(sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
489
1521
session->row_count_func= -1;
1529
if (need_start_waiting)
1532
Release the protection against the global read lock and wake
1533
everyone, who might want to set a global read lock.
1535
start_waiting_global_read_lock(session);
492
return (res || session->is_error());
1537
return(res || session->is_error());
494
1540
bool execute_sqlcom_select(Session *session, TableList *all_tables)
496
1542
LEX *lex= session->lex;