468
475
variables, but for now this is probably good enough.
469
476
Don't reset warnings when executing a stored routine.
471
if (all_tables || ! lex->is_single_level_stmt())
478
if (all_tables || !lex->is_single_level_stmt())
473
479
drizzle_reset_errors(session, 0);
476
481
status_var_increment(session->status_var.com_stat[lex->sql_command]);
478
assert(session->transaction.stmt.hasModifiedNonTransData() == false);
480
/* now we are ready to execute the statement */
481
res= lex->statement->execute();
483
assert(session->transaction.stmt.modified_non_trans_table == false);
485
switch (lex->sql_command) {
486
case SQLCOM_SHOW_STATUS:
488
system_status_var old_status_var= session->status_var;
489
session->initial_status_var= &old_status_var;
490
res= execute_sqlcom_select(session, all_tables);
491
/* Don't log SHOW STATUS commands to slow query log */
492
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
493
SERVER_QUERY_NO_GOOD_INDEX_USED);
495
restore status variables, as we don't want 'show status' to cause
498
pthread_mutex_lock(&LOCK_status);
499
add_diff_to_status(&global_status_var, &session->status_var,
501
session->status_var= old_status_var;
502
pthread_mutex_unlock(&LOCK_status);
505
case SQLCOM_SHOW_DATABASES:
506
case SQLCOM_SHOW_TABLES:
507
case SQLCOM_SHOW_TABLE_STATUS:
508
case SQLCOM_SHOW_OPEN_TABLES:
509
case SQLCOM_SHOW_FIELDS:
510
case SQLCOM_SHOW_KEYS:
511
case SQLCOM_SHOW_VARIABLES:
514
session->status_var.last_query_cost= 0.0;
515
res= execute_sqlcom_select(session, all_tables);
518
case SQLCOM_EMPTY_QUERY:
522
case SQLCOM_SHOW_WARNS:
524
res= mysqld_show_warnings(session, (uint32_t)
525
((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
526
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
527
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
531
case SQLCOM_SHOW_ERRORS:
533
res= mysqld_show_warnings(session, (uint32_t)
534
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
537
case SQLCOM_ASSIGN_TO_KEYCACHE:
539
assert(first_table == all_tables && first_table != 0);
540
res= mysql_assign_to_keycache(session, first_table, &lex->ident);
543
case SQLCOM_SHOW_ENGINE_STATUS:
545
res = ha_show_status(session, lex->show_engine, HA_ENGINE_STATUS);
548
case SQLCOM_CREATE_TABLE:
550
/* If CREATE TABLE of non-temporary table, do implicit commit */
551
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
553
if (! session->endActiveTransaction())
559
assert(first_table == all_tables && first_table != 0);
561
// Skip first table, which is the table we are creating
562
TableList *create_table= lex->unlink_first_table(&link_to_local);
563
TableList *select_tables= lex->query_tables;
565
Code below (especially in mysql_create_table() and select_create
566
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
567
use a copy of this structure to make execution prepared statement-
568
safe. A shallow copy is enough as this code won't modify any memory
569
referenced from this structure.
571
HA_CREATE_INFO create_info(lex->create_info);
573
We need to copy alter_info for the same reasons of re-execution
574
safety, only in case of Alter_info we have to do (almost) a deep
577
Alter_info alter_info(lex->alter_info, session->mem_root);
579
if (session->is_fatal_error)
581
/* If out of memory when creating a copy of alter_info. */
583
goto end_with_restore_list;
586
if ((res= create_table_precheck(session, select_tables, create_table)))
587
goto end_with_restore_list;
589
/* Might have been updated in create_table_precheck */
590
create_info.alias= create_table->alias;
593
/* Fix names if symlinked tables */
594
if (append_file_to_dir(session, &create_info.data_file_name,
595
create_table->table_name) ||
596
append_file_to_dir(session, &create_info.index_file_name,
597
create_table->table_name))
598
goto end_with_restore_list;
601
The create-select command will open and read-lock the select table
602
and then create, open and write-lock the new table. If a global
603
read lock steps in, we get a deadlock. The write lock waits for
604
the global read lock, while the global read lock waits for the
605
select table to be closed. So we wait until the global readlock is
606
gone before starting both steps. Note that
607
wait_if_global_read_lock() sets a protection against a new global
608
read lock when it succeeds. This needs to be released by
609
start_waiting_global_read_lock(). We protect the normal CREATE
610
TABLE in the same way. That way we avoid that a new table is
611
created during a gobal read lock.
613
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
616
goto end_with_restore_list;
618
if (select_lex->item_list.elements) // With select
620
select_result *result;
622
select_lex->options|= SELECT_NO_UNLOCK;
623
unit->set_limit(select_lex);
625
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
627
lex->link_first_table_back(create_table, link_to_local);
628
create_table->create= true;
631
if (!(res= session->open_and_lock_tables(lex->query_tables)))
634
Is table which we are changing used somewhere in other parts
637
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
639
TableList *duplicate;
640
create_table= lex->unlink_first_table(&link_to_local);
641
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
643
my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->alias);
645
goto end_with_restore_list;
650
select_create is currently not re-execution friendly and
651
needs to be created for every execution of a PS/SP.
653
if ((result= new select_create(create_table,
655
lex->create_table_proto,
657
select_lex->item_list,
663
CREATE from SELECT give its Select_Lex for SELECT,
664
and item_list belong to SELECT
666
res= handle_select(session, lex, result, 0);
670
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
671
create_table= lex->unlink_first_table(&link_to_local);
676
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
677
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
678
session->options|= OPTION_KEEP_LOG;
680
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
681
res= mysql_create_like_table(session, create_table, select_tables,
685
res= mysql_create_table(session, create_table->db,
686
create_table->table_name, &create_info,
687
lex->create_table_proto,
694
/* put tables back for PS rexecuting */
695
end_with_restore_list:
696
lex->link_first_table_back(create_table, link_to_local);
699
case SQLCOM_CREATE_INDEX:
701
case SQLCOM_DROP_INDEX:
703
CREATE INDEX and DROP INDEX are implemented by calling ALTER
704
TABLE with proper arguments.
706
In the future ALTER TABLE will notice that the request is to
707
only add indexes and create these one by one for the existing
708
table without having to do a full rebuild.
711
/* Prepare stack copies to be re-execution safe */
712
HA_CREATE_INFO create_info;
713
Alter_info alter_info(lex->alter_info, session->mem_root);
715
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
718
assert(first_table == all_tables && first_table != 0);
719
if (! session->endActiveTransaction())
722
memset(&create_info, 0, sizeof(create_info));
723
create_info.db_type= 0;
724
create_info.row_type= ROW_TYPE_NOT_USED;
725
create_info.default_table_charset= get_default_db_collation(session->db);
727
res= mysql_alter_table(session, first_table->db, first_table->table_name,
728
&create_info, first_table, &alter_info,
729
0, (order_st*) 0, 0);
732
case SQLCOM_ALTER_TABLE:
733
assert(first_table == all_tables && first_table != 0);
736
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
737
so we have to use a copy of this structure to make execution
738
prepared statement- safe. A shallow copy is enough as no memory
739
referenced from this structure will be modified.
741
HA_CREATE_INFO create_info(lex->create_info);
742
Alter_info alter_info(lex->alter_info, session->mem_root);
744
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
749
/* Must be set in the parser */
750
assert(select_lex->db);
754
memset(&tmp_table, 0, sizeof(tmp_table));
755
tmp_table.table_name= lex->name.str;
756
tmp_table.db=select_lex->db;
759
/* Don't yet allow changing of symlinks with ALTER TABLE */
760
if (create_info.data_file_name)
761
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
762
"DATA DIRECTORY option ignored");
763
if (create_info.index_file_name)
764
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
765
"INDEX DIRECTORY option ignored");
766
create_info.data_file_name= create_info.index_file_name= NULL;
767
/* ALTER TABLE ends previous transaction */
768
if (! session->endActiveTransaction())
771
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
777
res= mysql_alter_table(session, select_lex->db, lex->name.str,
781
select_lex->order_list.elements,
782
(order_st *) select_lex->order_list.first,
786
case SQLCOM_RENAME_TABLE:
788
assert(first_table == all_tables && first_table != 0);
790
for (table= first_table; table; table= table->next_local->next_local)
792
TableList old_list, new_list;
794
we do not need initialize old_list and new_list because we will
795
come table[0] and table->next[0] there
798
new_list= table->next_local[0];
801
if (! session->endActiveTransaction() || drizzle_rename_tables(session, first_table))
807
case SQLCOM_SHOW_CREATE:
808
assert(first_table == all_tables && first_table != 0);
810
res= drizzled_show_create(session, first_table);
813
case SQLCOM_CHECKSUM:
815
assert(first_table == all_tables && first_table != 0);
816
res = mysql_checksum_table(session, first_table, &lex->check_opt);
821
assert(first_table == all_tables && first_table != 0);
822
res = mysql_check_table(session, first_table, &lex->check_opt);
823
select_lex->table_list.first= (unsigned char*) first_table;
824
lex->query_tables=all_tables;
829
assert(first_table == all_tables && first_table != 0);
830
res= mysql_analyze_table(session, first_table, &lex->check_opt);
831
/* ! we write after unlocking the table */
832
write_bin_log(session, true, session->query, session->query_length);
833
select_lex->table_list.first= (unsigned char*) first_table;
834
lex->query_tables=all_tables;
838
case SQLCOM_OPTIMIZE:
840
assert(first_table == all_tables && first_table != 0);
841
res= mysql_optimize_table(session, first_table, &lex->check_opt);
842
/* ! we write after unlocking the table */
843
write_bin_log(session, true, session->query, session->query_length);
844
select_lex->table_list.first= (unsigned char*) first_table;
845
lex->query_tables=all_tables;
849
assert(first_table == all_tables && first_table != 0);
850
if ((res= update_precheck(session, all_tables)))
852
assert(select_lex->offset_limit == 0);
853
unit->set_limit(select_lex);
854
res= mysql_update(session, all_tables,
855
select_lex->item_list,
858
select_lex->order_list.elements,
859
(order_st *) select_lex->order_list.first,
860
unit->select_limit_cnt,
861
lex->duplicates, lex->ignore);
863
case SQLCOM_UPDATE_MULTI:
865
assert(first_table == all_tables && first_table != 0);
866
if ((res= update_precheck(session, all_tables)))
869
if ((res= mysql_multi_update_prepare(session)))
872
res= mysql_multi_update(session, all_tables,
873
&select_lex->item_list,
877
lex->duplicates, lex->ignore, unit, select_lex);
883
assert(first_table == all_tables && first_table != 0);
884
if ((res= insert_precheck(session, all_tables)))
887
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
893
res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
894
lex->update_list, lex->value_list,
895
lex->duplicates, lex->ignore);
899
case SQLCOM_REPLACE_SELECT:
900
case SQLCOM_INSERT_SELECT:
902
select_result *sel_result;
903
assert(first_table == all_tables && first_table != 0);
904
if ((res= insert_precheck(session, all_tables)))
907
/* Don't unlock tables until command is written to binary log */
908
select_lex->options|= SELECT_NO_UNLOCK;
910
unit->set_limit(select_lex);
912
if (! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
918
if (!(res= session->open_and_lock_tables(all_tables)))
920
/* Skip first table, which is the table we are inserting in */
921
TableList *second_table= first_table->next_local;
922
select_lex->table_list.first= (unsigned char*) second_table;
923
select_lex->context.table_list=
924
select_lex->context.first_name_resolution_table= second_table;
925
res= mysql_insert_select_prepare(session);
926
if (!res && (sel_result= new select_insert(first_table,
934
res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
936
Invalidate the table in the query cache if something changed
937
after unlocking when changes become visible.
938
TODO: this is workaround. right way will be move invalidating in
939
the unlock procedure.
941
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
944
/* INSERT ... SELECT should invalidate only the very first table */
945
TableList *save_table= first_table->next_local;
946
first_table->next_local= 0;
947
first_table->next_local= save_table;
951
/* revert changes for SP */
952
select_lex->table_list.first= (unsigned char*) first_table;
957
case SQLCOM_TRUNCATE:
958
if (! session->endActiveTransaction())
963
assert(first_table == all_tables && first_table != 0);
965
Don't allow this within a transaction because we want to use
968
if (session->inTransaction())
970
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
974
res= mysql_truncate(session, first_table, 0);
979
assert(first_table == all_tables && first_table != 0);
980
assert(select_lex->offset_limit == 0);
981
unit->set_limit(select_lex);
983
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
989
res = mysql_delete(session, all_tables, select_lex->where,
990
&select_lex->order_list,
991
unit->select_limit_cnt, select_lex->options,
995
case SQLCOM_DELETE_MULTI:
997
assert(first_table == all_tables && first_table != 0);
998
TableList *aux_tables=
999
(TableList *)session->lex->auxiliary_table_list.first;
1000
multi_delete *del_result;
1002
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1008
if ((res= multi_delete_precheck(session, all_tables)))
1011
/* condition will be true on SP re-excuting */
1012
if (select_lex->item_list.elements != 0)
1013
select_lex->item_list.empty();
1014
if (session->add_item_to_list(new Item_null()))
1017
session->set_proc_info("init");
1018
if ((res= session->open_and_lock_tables(all_tables)))
1021
if ((res= mysql_multi_delete_prepare(session)))
1024
if (!session->is_fatal_error &&
1025
(del_result= new multi_delete(aux_tables, lex->table_count)))
1027
res= mysql_select(session, &select_lex->ref_pointer_array,
1028
select_lex->get_table_list(),
1029
select_lex->with_wild,
1030
select_lex->item_list,
1032
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
1033
select_lex->options | session->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE,
1034
del_result, unit, select_lex);
1035
res|= session->is_error();
1037
del_result->abort();
1044
case SQLCOM_DROP_TABLE:
1046
assert(first_table == all_tables && first_table != 0);
1047
if (!lex->drop_temporary)
1049
if (! session->endActiveTransaction())
1054
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
1055
session->options|= OPTION_KEEP_LOG;
1057
/* DDL and binlog write order protected by LOCK_open */
1058
res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
1061
case SQLCOM_SHOW_PROCESSLIST:
1062
mysqld_list_processes(session, NULL, lex->verbose);
1064
case SQLCOM_CHANGE_DB:
1066
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
1068
if (!mysql_change_db(session, &db_str, false))
1076
assert(first_table == all_tables && first_table != 0);
1077
res= mysql_load(session, lex->exchange, first_table, lex->field_list,
1078
lex->update_list, lex->value_list, lex->duplicates, lex->ignore);
1082
case SQLCOM_SET_OPTION:
1084
List<set_var_base> *lex_var_list= &lex->var_list;
1086
if (session->open_and_lock_tables(all_tables))
1088
if (!(res= sql_set_variables(session, lex_var_list)))
1095
We encountered some sort of error, but no message was sent.
1096
Send something semi-generic here since we don't know which
1097
assignment in the list caused the error.
1099
if (!session->is_error())
1100
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
1107
case SQLCOM_UNLOCK_TABLES:
1109
It is critical for mysqldump --single-transaction --master-data that
1110
UNLOCK TABLES does not implicitely commit a connection which has only
1111
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
1112
false, mysqldump will not work.
1114
if (session->global_read_lock)
1115
unlock_global_read_lock(session);
1118
case SQLCOM_CREATE_DB:
1121
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
1122
it, we need to use a copy of LEX::create_info to make execution
1123
prepared statement- safe.
1125
HA_CREATE_INFO create_info(lex->create_info);
1126
if (! session->endActiveTransaction())
1132
if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
1133
check_db_name(&lex->name))
1135
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1138
res= mysql_create_db(session,(lex->name.str), &create_info);
1141
case SQLCOM_DROP_DB:
1143
if (! session->endActiveTransaction())
1148
if (check_db_name(&lex->name))
1150
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1153
if (session->inTransaction())
1155
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1158
res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists);
1161
case SQLCOM_ALTER_DB:
1163
LEX_STRING *db= &lex->name;
1164
HA_CREATE_INFO create_info(lex->create_info);
1165
if (check_db_name(db))
1167
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
1170
if (session->inTransaction())
1172
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1175
res= mysql_alter_db(session, db->str, &create_info);
1178
case SQLCOM_SHOW_CREATE_DB:
1180
if (check_db_name(&lex->name))
1182
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1185
res= mysqld_show_create_db(session, lex->name.str, &lex->create_info);
1191
reload_cache() will tell us if we are allowed to write to the
1194
if (!reload_cache(session, lex->type, first_table))
1197
We WANT to write and we CAN write.
1198
! we write after unlocking the table.
1201
Presumably, RESET and binlog writing doesn't require synchronization
1203
write_bin_log(session, false, session->query, session->query_length);
1211
Item *it= (Item *)lex->value_list.head();
1213
if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
1215
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
1219
sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
1223
if (session->transaction.xid_state.xa_state != XA_NOTR)
1225
my_error(ER_XAER_RMFAIL, MYF(0),
1226
xa_state_names[session->transaction.xid_state.xa_state]);
1230
Breakpoints for backup testing.
1232
if (! session->startTransaction())
1237
if (! session->endTransaction(lex->tx_release ? COMMIT_RELEASE : lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
1241
case SQLCOM_ROLLBACK:
1242
if (! session->endTransaction(lex->tx_release ? ROLLBACK_RELEASE : lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
1246
case SQLCOM_RELEASE_SAVEPOINT:
1249
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
1251
if (my_strnncoll(system_charset_info,
1252
(unsigned char *)lex->ident.str, lex->ident.length,
1253
(unsigned char *)sv->name, sv->length) == 0)
1258
if (ha_release_savepoint(session, sv))
1259
res= true; // cannot happen
1262
session->transaction.savepoints=sv->prev;
1265
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
1268
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
1271
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
1273
if (my_strnncoll(system_charset_info,
1274
(unsigned char *)lex->ident.str, lex->ident.length,
1275
(unsigned char *)sv->name, sv->length) == 0)
1280
if (ha_rollback_to_savepoint(session, sv))
1281
res= true; // cannot happen
1284
if ((session->options & OPTION_KEEP_LOG) || session->transaction.all.modified_non_trans_table)
1285
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1286
ER_WARNING_NOT_COMPLETE_ROLLBACK,
1287
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1290
session->transaction.savepoints=sv;
1293
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
1296
case SQLCOM_SAVEPOINT:
1297
if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
1301
SAVEPOINT **sv, *newsv;
1302
for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
1304
if (my_strnncoll(system_charset_info,
1305
(unsigned char *)lex->ident.str, lex->ident.length,
1306
(unsigned char *)(*sv)->name, (*sv)->length) == 0)
1309
if (*sv) /* old savepoint of the same name exists */
1312
ha_release_savepoint(session, *sv); // it cannot fail
1315
else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
1316
savepoint_alloc_size)) == 0)
1318
my_error(ER_OUT_OF_RESOURCES, MYF(0));
1321
newsv->name=strmake_root(&session->transaction.mem_root,
1322
lex->ident.str, lex->ident.length);
1323
newsv->length=lex->ident.length;
1325
if we'll get an error here, don't add new savepoint to the list.
1326
we'll lose a little bit of memory in transaction mem_root, but it'll
1327
be free'd when transaction ends anyway
1329
if (ha_savepoint(session, newsv))
1333
newsv->prev=session->transaction.savepoints;
1334
session->transaction.savepoints=newsv;
1340
assert(0); /* Impossible */
483
1344
session->set_proc_info("query end");