468
478
variables, but for now this is probably good enough.
469
479
Don't reset warnings when executing a stored routine.
471
if (all_tables || ! lex->is_single_level_stmt())
481
if (all_tables || !lex->is_single_level_stmt())
473
482
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();
484
status_var_increment(session->status_var.com_stat[lex->sql_command]);
486
assert(session->transaction.stmt.modified_non_trans_table == false);
489
switch (lex->sql_command) {
490
case SQLCOM_EMPTY_QUERY:
494
case SQLCOM_SHOW_WARNS:
496
res= mysqld_show_warnings(session, (uint32_t)
497
((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
498
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
499
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
503
case SQLCOM_SHOW_ERRORS:
505
res= mysqld_show_warnings(session, (uint32_t)
506
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
509
case SQLCOM_ASSIGN_TO_KEYCACHE:
511
assert(first_table == all_tables && first_table != 0);
512
res= mysql_assign_to_keycache(session, first_table, &lex->ident);
515
case SQLCOM_SHOW_ENGINE_STATUS:
517
res = ha_show_status(session, lex->show_engine, HA_ENGINE_STATUS);
520
case SQLCOM_CREATE_TABLE:
522
/* If CREATE TABLE of non-temporary table, do implicit commit */
523
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
525
if (! session->endActiveTransaction())
531
assert(first_table == all_tables && first_table != 0);
533
// Skip first table, which is the table we are creating
534
TableList *create_table= lex->unlink_first_table(&link_to_local);
535
TableList *select_tables= lex->query_tables;
537
Code below (especially in mysql_create_table() and select_create
538
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
539
use a copy of this structure to make execution prepared statement-
540
safe. A shallow copy is enough as this code won't modify any memory
541
referenced from this structure.
543
HA_CREATE_INFO create_info(lex->create_info);
545
We need to copy alter_info for the same reasons of re-execution
546
safety, only in case of Alter_info we have to do (almost) a deep
549
Alter_info alter_info(lex->alter_info, session->mem_root);
551
if (session->is_fatal_error)
553
/* If out of memory when creating a copy of alter_info. */
555
goto end_with_restore_list;
558
if ((res= create_table_precheck(session, select_tables, create_table)))
559
goto end_with_restore_list;
561
/* Might have been updated in create_table_precheck */
562
create_info.alias= create_table->alias;
565
/* Fix names if symlinked tables */
566
if (append_file_to_dir(session, &create_info.data_file_name,
567
create_table->table_name) ||
568
append_file_to_dir(session, &create_info.index_file_name,
569
create_table->table_name))
570
goto end_with_restore_list;
573
The create-select command will open and read-lock the select table
574
and then create, open and write-lock the new table. If a global
575
read lock steps in, we get a deadlock. The write lock waits for
576
the global read lock, while the global read lock waits for the
577
select table to be closed. So we wait until the global readlock is
578
gone before starting both steps. Note that
579
wait_if_global_read_lock() sets a protection against a new global
580
read lock when it succeeds. This needs to be released by
581
start_waiting_global_read_lock(). We protect the normal CREATE
582
TABLE in the same way. That way we avoid that a new table is
583
created during a gobal read lock.
585
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
588
goto end_with_restore_list;
590
if (select_lex->item_list.elements) // With select
592
select_result *result;
594
select_lex->options|= SELECT_NO_UNLOCK;
595
unit->set_limit(select_lex);
597
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
599
lex->link_first_table_back(create_table, link_to_local);
600
create_table->create= true;
603
if (!(res= session->open_and_lock_tables(lex->query_tables)))
606
Is table which we are changing used somewhere in other parts
609
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
611
TableList *duplicate;
612
create_table= lex->unlink_first_table(&link_to_local);
613
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
615
my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->alias);
617
goto end_with_restore_list;
622
select_create is currently not re-execution friendly and
623
needs to be created for every execution of a PS/SP.
625
if ((result= new select_create(create_table,
627
lex->create_table_proto,
629
select_lex->item_list,
635
CREATE from SELECT give its Select_Lex for SELECT,
636
and item_list belong to SELECT
638
res= handle_select(session, lex, result, 0);
642
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
643
create_table= lex->unlink_first_table(&link_to_local);
648
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
649
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
650
session->options|= OPTION_KEEP_LOG;
652
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
653
res= mysql_create_like_table(session, create_table, select_tables,
657
res= mysql_create_table(session, create_table->db,
658
create_table->table_name, &create_info,
659
lex->create_table_proto,
666
/* put tables back for PS rexecuting */
667
end_with_restore_list:
668
lex->link_first_table_back(create_table, link_to_local);
671
case SQLCOM_CREATE_INDEX:
673
case SQLCOM_DROP_INDEX:
675
CREATE INDEX and DROP INDEX are implemented by calling ALTER
676
TABLE with proper arguments.
678
In the future ALTER TABLE will notice that the request is to
679
only add indexes and create these one by one for the existing
680
table without having to do a full rebuild.
683
/* Prepare stack copies to be re-execution safe */
684
HA_CREATE_INFO create_info;
685
Alter_info alter_info(lex->alter_info, session->mem_root);
687
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
690
assert(first_table == all_tables && first_table != 0);
691
if (! session->endActiveTransaction())
694
memset(&create_info, 0, sizeof(create_info));
695
create_info.db_type= 0;
696
create_info.row_type= ROW_TYPE_NOT_USED;
697
create_info.default_table_charset= get_default_db_collation(session->db);
699
res= mysql_alter_table(session, first_table->db, first_table->table_name,
700
&create_info, first_table, &alter_info,
701
0, (order_st*) 0, 0);
704
case SQLCOM_ALTER_TABLE:
705
assert(first_table == all_tables && first_table != 0);
708
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
709
so we have to use a copy of this structure to make execution
710
prepared statement- safe. A shallow copy is enough as no memory
711
referenced from this structure will be modified.
713
HA_CREATE_INFO create_info(lex->create_info);
714
Alter_info alter_info(lex->alter_info, session->mem_root);
716
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
721
/* Must be set in the parser */
722
assert(select_lex->db);
726
memset(&tmp_table, 0, sizeof(tmp_table));
727
tmp_table.table_name= lex->name.str;
728
tmp_table.db=select_lex->db;
731
/* Don't yet allow changing of symlinks with ALTER TABLE */
732
if (create_info.data_file_name)
733
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
734
"DATA DIRECTORY option ignored");
735
if (create_info.index_file_name)
736
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
737
"INDEX DIRECTORY option ignored");
738
create_info.data_file_name= create_info.index_file_name= NULL;
739
/* ALTER TABLE ends previous transaction */
740
if (! session->endActiveTransaction())
743
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
749
res= mysql_alter_table(session, select_lex->db, lex->name.str,
753
select_lex->order_list.elements,
754
(order_st *) select_lex->order_list.first,
758
case SQLCOM_RENAME_TABLE:
760
assert(first_table == all_tables && first_table != 0);
762
for (table= first_table; table; table= table->next_local->next_local)
764
TableList old_list, new_list;
766
we do not need initialize old_list and new_list because we will
767
come table[0] and table->next[0] there
770
new_list= table->next_local[0];
773
if (! session->endActiveTransaction() || drizzle_rename_tables(session, first_table))
779
case SQLCOM_SHOW_CREATE:
780
assert(first_table == all_tables && first_table != 0);
782
res= drizzled_show_create(session, first_table);
785
case SQLCOM_CHECKSUM:
787
assert(first_table == all_tables && first_table != 0);
788
res = mysql_checksum_table(session, first_table, &lex->check_opt);
793
assert(first_table == all_tables && first_table != 0);
794
res = mysql_check_table(session, first_table, &lex->check_opt);
795
select_lex->table_list.first= (unsigned char*) first_table;
796
lex->query_tables=all_tables;
801
assert(first_table == all_tables && first_table != 0);
802
res= mysql_analyze_table(session, first_table, &lex->check_opt);
803
/* ! we write after unlocking the table */
804
write_bin_log(session, true, session->query, session->query_length);
805
select_lex->table_list.first= (unsigned char*) first_table;
806
lex->query_tables=all_tables;
810
case SQLCOM_OPTIMIZE:
812
assert(first_table == all_tables && first_table != 0);
813
res= mysql_optimize_table(session, first_table, &lex->check_opt);
814
/* ! we write after unlocking the table */
815
write_bin_log(session, true, session->query, session->query_length);
816
select_lex->table_list.first= (unsigned char*) first_table;
817
lex->query_tables=all_tables;
821
assert(first_table == all_tables && first_table != 0);
822
if ((res= update_precheck(session, all_tables)))
824
assert(select_lex->offset_limit == 0);
825
unit->set_limit(select_lex);
826
res= mysql_update(session, all_tables,
827
select_lex->item_list,
830
select_lex->order_list.elements,
831
(order_st *) select_lex->order_list.first,
832
unit->select_limit_cnt,
833
lex->duplicates, lex->ignore);
835
case SQLCOM_UPDATE_MULTI:
837
assert(first_table == all_tables && first_table != 0);
838
if ((res= update_precheck(session, all_tables)))
841
if ((res= mysql_multi_update_prepare(session)))
844
res= mysql_multi_update(session, all_tables,
845
&select_lex->item_list,
849
lex->duplicates, lex->ignore, unit, select_lex);
855
assert(first_table == all_tables && first_table != 0);
856
if ((res= insert_precheck(session, all_tables)))
859
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
865
res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
866
lex->update_list, lex->value_list,
867
lex->duplicates, lex->ignore);
871
case SQLCOM_REPLACE_SELECT:
872
case SQLCOM_INSERT_SELECT:
874
select_result *sel_result;
875
assert(first_table == all_tables && first_table != 0);
876
if ((res= insert_precheck(session, all_tables)))
879
/* Don't unlock tables until command is written to binary log */
880
select_lex->options|= SELECT_NO_UNLOCK;
882
unit->set_limit(select_lex);
884
if (! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
890
if (!(res= session->open_and_lock_tables(all_tables)))
892
/* Skip first table, which is the table we are inserting in */
893
TableList *second_table= first_table->next_local;
894
select_lex->table_list.first= (unsigned char*) second_table;
895
select_lex->context.table_list=
896
select_lex->context.first_name_resolution_table= second_table;
897
res= mysql_insert_select_prepare(session);
898
if (!res && (sel_result= new select_insert(first_table,
906
res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
908
Invalidate the table in the query cache if something changed
909
after unlocking when changes become visible.
910
TODO: this is workaround. right way will be move invalidating in
911
the unlock procedure.
913
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
916
/* INSERT ... SELECT should invalidate only the very first table */
917
TableList *save_table= first_table->next_local;
918
first_table->next_local= 0;
919
first_table->next_local= save_table;
923
/* revert changes for SP */
924
select_lex->table_list.first= (unsigned char*) first_table;
929
case SQLCOM_TRUNCATE:
930
if (! session->endActiveTransaction())
935
assert(first_table == all_tables && first_table != 0);
937
Don't allow this within a transaction because we want to use
940
if (session->inTransaction())
942
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
946
res= mysql_truncate(session, first_table, 0);
951
assert(first_table == all_tables && first_table != 0);
952
assert(select_lex->offset_limit == 0);
953
unit->set_limit(select_lex);
955
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
961
res = mysql_delete(session, all_tables, select_lex->where,
962
&select_lex->order_list,
963
unit->select_limit_cnt, select_lex->options,
967
case SQLCOM_DELETE_MULTI:
969
assert(first_table == all_tables && first_table != 0);
970
TableList *aux_tables=
971
(TableList *)session->lex->auxiliary_table_list.first;
972
multi_delete *del_result;
974
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
980
if ((res= multi_delete_precheck(session, all_tables)))
983
/* condition will be true on SP re-excuting */
984
if (select_lex->item_list.elements != 0)
985
select_lex->item_list.empty();
986
if (session->add_item_to_list(new Item_null()))
989
session->set_proc_info("init");
990
if ((res= session->open_and_lock_tables(all_tables)))
993
if ((res= mysql_multi_delete_prepare(session)))
996
if (!session->is_fatal_error &&
997
(del_result= new multi_delete(aux_tables, lex->table_count)))
999
res= mysql_select(session, &select_lex->ref_pointer_array,
1000
select_lex->get_table_list(),
1001
select_lex->with_wild,
1002
select_lex->item_list,
1004
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
1005
select_lex->options | session->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE,
1006
del_result, unit, select_lex);
1007
res|= session->is_error();
1009
del_result->abort();
1016
case SQLCOM_DROP_TABLE:
1018
assert(first_table == all_tables && first_table != 0);
1019
if (!lex->drop_temporary)
1021
if (! session->endActiveTransaction())
1026
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
1027
session->options|= OPTION_KEEP_LOG;
1029
/* DDL and binlog write order protected by LOCK_open */
1030
res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
1033
case SQLCOM_SHOW_PROCESSLIST:
1034
mysqld_list_processes(session, NULL, lex->verbose);
1036
case SQLCOM_CHANGE_DB:
1038
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
1040
if (!mysql_change_db(session, &db_str, false))
1048
assert(first_table == all_tables && first_table != 0);
1049
res= mysql_load(session, lex->exchange, first_table, lex->field_list,
1050
lex->update_list, lex->value_list, lex->duplicates, lex->ignore);
1054
case SQLCOM_SET_OPTION:
1056
List<set_var_base> *lex_var_list= &lex->var_list;
1058
if (session->open_and_lock_tables(all_tables))
1060
if (!(res= sql_set_variables(session, lex_var_list)))
1067
We encountered some sort of error, but no message was sent.
1068
Send something semi-generic here since we don't know which
1069
assignment in the list caused the error.
1071
if (!session->is_error())
1072
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
1079
case SQLCOM_UNLOCK_TABLES:
1081
It is critical for mysqldump --single-transaction --master-data that
1082
UNLOCK TABLES does not implicitely commit a connection which has only
1083
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
1084
false, mysqldump will not work.
1086
if (session->global_read_lock)
1087
unlock_global_read_lock(session);
1090
case SQLCOM_CREATE_DB:
1093
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
1094
it, we need to use a copy of LEX::create_info to make execution
1095
prepared statement- safe.
1097
HA_CREATE_INFO create_info(lex->create_info);
1098
if (! session->endActiveTransaction())
1104
if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
1105
check_db_name(&lex->name))
1107
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1110
res= mysql_create_db(session,(lex->name.str), &create_info);
1113
case SQLCOM_DROP_DB:
1115
if (! session->endActiveTransaction())
1120
if (check_db_name(&lex->name))
1122
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1125
if (session->inTransaction())
1127
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1130
res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists);
1133
case SQLCOM_ALTER_DB:
1135
LEX_STRING *db= &lex->name;
1136
HA_CREATE_INFO create_info(lex->create_info);
1137
if (check_db_name(db))
1139
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
1142
if (session->inTransaction())
1144
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1147
res= mysql_alter_db(session, db->str, &create_info);
1150
case SQLCOM_SHOW_CREATE_DB:
1152
if (check_db_name(&lex->name))
1154
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1157
res= mysqld_show_create_db(session, lex->name.str,
1158
lex->create_info.options &
1159
HA_LEX_CREATE_IF_NOT_EXISTS);
1165
reload_cache() will tell us if we are allowed to write to the
1168
if (!reload_cache(session, lex->type, first_table))
1171
We WANT to write and we CAN write.
1172
! we write after unlocking the table.
1175
Presumably, RESET and binlog writing doesn't require synchronization
1177
write_bin_log(session, false, session->query, session->query_length);
1185
Item *it= (Item *)lex->value_list.head();
1187
if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
1189
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
1193
sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
1197
if (session->transaction.xid_state.xa_state != XA_NOTR)
1199
my_error(ER_XAER_RMFAIL, MYF(0),
1200
xa_state_names[session->transaction.xid_state.xa_state]);
1204
Breakpoints for backup testing.
1206
if (! session->startTransaction())
1211
if (! session->endTransaction(lex->tx_release ? COMMIT_RELEASE : lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
1215
case SQLCOM_ROLLBACK:
1216
if (! session->endTransaction(lex->tx_release ? ROLLBACK_RELEASE : lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
1220
case SQLCOM_RELEASE_SAVEPOINT:
1223
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
1225
if (my_strnncoll(system_charset_info,
1226
(unsigned char *)lex->ident.str, lex->ident.length,
1227
(unsigned char *)sv->name, sv->length) == 0)
1232
if (ha_release_savepoint(session, sv))
1233
res= true; // cannot happen
1236
session->transaction.savepoints=sv->prev;
1239
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
1242
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
1245
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
1247
if (my_strnncoll(system_charset_info,
1248
(unsigned char *)lex->ident.str, lex->ident.length,
1249
(unsigned char *)sv->name, sv->length) == 0)
1254
if (ha_rollback_to_savepoint(session, sv))
1255
res= true; // cannot happen
1258
if ((session->options & OPTION_KEEP_LOG) || session->transaction.all.modified_non_trans_table)
1259
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1260
ER_WARNING_NOT_COMPLETE_ROLLBACK,
1261
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1264
session->transaction.savepoints=sv;
1267
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
1270
case SQLCOM_SAVEPOINT:
1271
if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
1275
SAVEPOINT **sv, *newsv;
1276
for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
1278
if (my_strnncoll(system_charset_info,
1279
(unsigned char *)lex->ident.str, lex->ident.length,
1280
(unsigned char *)(*sv)->name, (*sv)->length) == 0)
1283
if (*sv) /* old savepoint of the same name exists */
1286
ha_release_savepoint(session, *sv); // it cannot fail
1289
else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
1290
savepoint_alloc_size)) == 0)
1292
my_error(ER_OUT_OF_RESOURCES, MYF(0));
1295
newsv->name=strmake_root(&session->transaction.mem_root,
1296
lex->ident.str, lex->ident.length);
1297
newsv->length=lex->ident.length;
1299
if we'll get an error here, don't add new savepoint to the list.
1300
we'll lose a little bit of memory in transaction mem_root, but it'll
1301
be free'd when transaction ends anyway
1303
if (ha_savepoint(session, newsv))
1307
newsv->prev=session->transaction.savepoints;
1308
session->transaction.savepoints=newsv;
1315
* This occurs now because we have extracted some commands in
1316
* to their own classes and thus there is no matching case
1317
* label in this switch statement for those commands. Pretty soon
1318
* this entire switch statement will be gone along with this
1321
comm_not_executed= true;
1325
* The following conditional statement is only temporary until
1326
* the mongo switch statement that occurs afterwards has been
1327
* fully removed. Once that switch statement is gone, every
1328
* command will have its own class and we won't need this
1331
if (comm_not_executed)
1333
/* now we are ready to execute the command */
1334
res= lex->command->execute();
480
1337
session->set_proc_info("query end");
482
1340
The return value for ROW_COUNT() is "implementation dependent" if the
483
1341
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
484
1342
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)))
1345
if (!(sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
489
1346
session->row_count_func= -1;
1354
if (need_start_waiting)
1357
Release the protection against the global read lock and wake
1358
everyone, who might want to set a global read lock.
1360
start_waiting_global_read_lock(session);
492
return (res || session->is_error());
1362
return(res || session->is_error());
494
1365
bool execute_sqlcom_select(Session *session, TableList *all_tables)
496
1367
LEX *lex= session->lex;