468
473
variables, but for now this is probably good enough.
469
474
Don't reset warnings when executing a stored routine.
471
if (all_tables || ! lex->is_single_level_stmt())
476
if (all_tables || !lex->is_single_level_stmt())
473
477
drizzle_reset_errors(session, 0);
476
479
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();
481
assert(session->transaction.stmt.modified_non_trans_table == false);
483
switch (lex->sql_command) {
484
case SQLCOM_SHOW_STATUS:
486
system_status_var old_status_var= session->status_var;
487
session->initial_status_var= &old_status_var;
488
res= execute_sqlcom_select(session, all_tables);
489
/* Don't log SHOW STATUS commands to slow query log */
490
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
491
SERVER_QUERY_NO_GOOD_INDEX_USED);
493
restore status variables, as we don't want 'show status' to cause
496
pthread_mutex_lock(&LOCK_status);
497
add_diff_to_status(&global_status_var, &session->status_var,
499
session->status_var= old_status_var;
500
pthread_mutex_unlock(&LOCK_status);
503
case SQLCOM_SHOW_DATABASES:
504
case SQLCOM_SHOW_TABLES:
505
case SQLCOM_SHOW_TABLE_STATUS:
506
case SQLCOM_SHOW_OPEN_TABLES:
507
case SQLCOM_SHOW_FIELDS:
508
case SQLCOM_SHOW_KEYS:
509
case SQLCOM_SHOW_VARIABLES:
512
session->status_var.last_query_cost= 0.0;
513
res= execute_sqlcom_select(session, all_tables);
516
case SQLCOM_EMPTY_QUERY:
520
case SQLCOM_SHOW_WARNS:
522
res= mysqld_show_warnings(session, (uint32_t)
523
((1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE) |
524
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN) |
525
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR)
529
case SQLCOM_SHOW_ERRORS:
531
res= mysqld_show_warnings(session, (uint32_t)
532
(1L << (uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR));
535
case SQLCOM_ASSIGN_TO_KEYCACHE:
537
assert(first_table == all_tables && first_table != 0);
538
res= mysql_assign_to_keycache(session, first_table, &lex->ident);
541
case SQLCOM_SHOW_ENGINE_STATUS:
543
res = ha_show_status(session, lex->show_engine, HA_ENGINE_STATUS);
546
case SQLCOM_CREATE_TABLE:
548
/* If CREATE TABLE of non-temporary table, do implicit commit */
549
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
551
if (! session->endActiveTransaction())
557
assert(first_table == all_tables && first_table != 0);
559
// Skip first table, which is the table we are creating
560
TableList *create_table= lex->unlink_first_table(&link_to_local);
561
TableList *select_tables= lex->query_tables;
563
Code below (especially in mysql_create_table() and select_create
564
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
565
use a copy of this structure to make execution prepared statement-
566
safe. A shallow copy is enough as this code won't modify any memory
567
referenced from this structure.
569
HA_CREATE_INFO create_info(lex->create_info);
571
We need to copy alter_info for the same reasons of re-execution
572
safety, only in case of Alter_info we have to do (almost) a deep
575
Alter_info alter_info(lex->alter_info, session->mem_root);
577
if (session->is_fatal_error)
579
/* If out of memory when creating a copy of alter_info. */
581
goto end_with_restore_list;
584
if ((res= create_table_precheck(session, select_tables, create_table)))
585
goto end_with_restore_list;
587
/* Might have been updated in create_table_precheck */
588
create_info.alias= create_table->alias;
591
/* Fix names if symlinked tables */
592
if (append_file_to_dir(session, &create_info.data_file_name,
593
create_table->table_name) ||
594
append_file_to_dir(session, &create_info.index_file_name,
595
create_table->table_name))
596
goto end_with_restore_list;
599
The create-select command will open and read-lock the select table
600
and then create, open and write-lock the new table. If a global
601
read lock steps in, we get a deadlock. The write lock waits for
602
the global read lock, while the global read lock waits for the
603
select table to be closed. So we wait until the global readlock is
604
gone before starting both steps. Note that
605
wait_if_global_read_lock() sets a protection against a new global
606
read lock when it succeeds. This needs to be released by
607
start_waiting_global_read_lock(). We protect the normal CREATE
608
TABLE in the same way. That way we avoid that a new table is
609
created during a gobal read lock.
611
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
614
goto end_with_restore_list;
616
if (select_lex->item_list.elements) // With select
618
select_result *result;
620
select_lex->options|= SELECT_NO_UNLOCK;
621
unit->set_limit(select_lex);
623
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
625
lex->link_first_table_back(create_table, link_to_local);
626
create_table->create= true;
629
if (!(res= session->open_and_lock_tables(lex->query_tables)))
632
Is table which we are changing used somewhere in other parts
635
if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
637
TableList *duplicate;
638
create_table= lex->unlink_first_table(&link_to_local);
639
if ((duplicate= unique_table(session, create_table, select_tables, 0)))
641
my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->alias);
643
goto end_with_restore_list;
648
select_create is currently not re-execution friendly and
649
needs to be created for every execution of a PS/SP.
651
if ((result= new select_create(create_table,
653
lex->create_table_proto,
655
select_lex->item_list,
661
CREATE from SELECT give its Select_Lex for SELECT,
662
and item_list belong to SELECT
664
res= handle_select(session, lex, result, 0);
668
else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
669
create_table= lex->unlink_first_table(&link_to_local);
674
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
675
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
676
session->options|= OPTION_KEEP_LOG;
678
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
679
res= mysql_create_like_table(session, create_table, select_tables,
683
res= mysql_create_table(session, create_table->db,
684
create_table->table_name, &create_info,
685
lex->create_table_proto,
692
/* put tables back for PS rexecuting */
693
end_with_restore_list:
694
lex->link_first_table_back(create_table, link_to_local);
697
case SQLCOM_CREATE_INDEX:
699
case SQLCOM_DROP_INDEX:
701
CREATE INDEX and DROP INDEX are implemented by calling ALTER
702
TABLE with proper arguments.
704
In the future ALTER TABLE will notice that the request is to
705
only add indexes and create these one by one for the existing
706
table without having to do a full rebuild.
709
/* Prepare stack copies to be re-execution safe */
710
HA_CREATE_INFO create_info;
711
Alter_info alter_info(lex->alter_info, session->mem_root);
713
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
716
assert(first_table == all_tables && first_table != 0);
717
if (! session->endActiveTransaction())
720
memset(&create_info, 0, sizeof(create_info));
721
create_info.db_type= 0;
722
create_info.row_type= ROW_TYPE_NOT_USED;
723
create_info.default_table_charset= get_default_db_collation(session->db);
725
res= mysql_alter_table(session, first_table->db, first_table->table_name,
726
&create_info, first_table, &alter_info,
727
0, (order_st*) 0, 0);
730
case SQLCOM_ALTER_TABLE:
731
assert(first_table == all_tables && first_table != 0);
734
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
735
so we have to use a copy of this structure to make execution
736
prepared statement- safe. A shallow copy is enough as no memory
737
referenced from this structure will be modified.
739
HA_CREATE_INFO create_info(lex->create_info);
740
Alter_info alter_info(lex->alter_info, session->mem_root);
742
if (session->is_fatal_error) /* out of memory creating a copy of alter_info */
747
/* Must be set in the parser */
748
assert(select_lex->db);
752
memset(&tmp_table, 0, sizeof(tmp_table));
753
tmp_table.table_name= lex->name.str;
754
tmp_table.db=select_lex->db;
757
/* Don't yet allow changing of symlinks with ALTER TABLE */
758
if (create_info.data_file_name)
759
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
760
"DATA DIRECTORY option ignored");
761
if (create_info.index_file_name)
762
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
763
"INDEX DIRECTORY option ignored");
764
create_info.data_file_name= create_info.index_file_name= NULL;
765
/* ALTER TABLE ends previous transaction */
766
if (! session->endActiveTransaction())
769
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
775
res= mysql_alter_table(session, select_lex->db, lex->name.str,
779
select_lex->order_list.elements,
780
(order_st *) select_lex->order_list.first,
784
case SQLCOM_RENAME_TABLE:
786
assert(first_table == all_tables && first_table != 0);
788
for (table= first_table; table; table= table->next_local->next_local)
790
TableList old_list, new_list;
792
we do not need initialize old_list and new_list because we will
793
come table[0] and table->next[0] there
796
new_list= table->next_local[0];
799
if (! session->endActiveTransaction() || drizzle_rename_tables(session, first_table))
805
case SQLCOM_SHOW_CREATE:
806
assert(first_table == all_tables && first_table != 0);
808
res= drizzled_show_create(session, first_table);
811
case SQLCOM_CHECKSUM:
813
assert(first_table == all_tables && first_table != 0);
814
res = mysql_checksum_table(session, first_table, &lex->check_opt);
819
assert(first_table == all_tables && first_table != 0);
820
res = mysql_check_table(session, first_table, &lex->check_opt);
821
select_lex->table_list.first= (unsigned char*) first_table;
822
lex->query_tables=all_tables;
827
assert(first_table == all_tables && first_table != 0);
828
res= mysql_analyze_table(session, first_table, &lex->check_opt);
829
/* ! we write after unlocking the table */
830
write_bin_log(session, true, session->query, session->query_length);
831
select_lex->table_list.first= (unsigned char*) first_table;
832
lex->query_tables=all_tables;
836
case SQLCOM_OPTIMIZE:
838
assert(first_table == all_tables && first_table != 0);
839
res= mysql_optimize_table(session, first_table, &lex->check_opt);
840
/* ! we write after unlocking the table */
841
write_bin_log(session, true, session->query, session->query_length);
842
select_lex->table_list.first= (unsigned char*) first_table;
843
lex->query_tables=all_tables;
847
assert(first_table == all_tables && first_table != 0);
848
if ((res= update_precheck(session, all_tables)))
850
assert(select_lex->offset_limit == 0);
851
unit->set_limit(select_lex);
852
res= mysql_update(session, all_tables,
853
select_lex->item_list,
856
select_lex->order_list.elements,
857
(order_st *) select_lex->order_list.first,
858
unit->select_limit_cnt,
859
lex->duplicates, lex->ignore);
861
case SQLCOM_UPDATE_MULTI:
863
assert(first_table == all_tables && first_table != 0);
864
if ((res= update_precheck(session, all_tables)))
867
if ((res= mysql_multi_update_prepare(session)))
870
res= mysql_multi_update(session, all_tables,
871
&select_lex->item_list,
875
lex->duplicates, lex->ignore, unit, select_lex);
881
assert(first_table == all_tables && first_table != 0);
882
if ((res= insert_precheck(session, all_tables)))
885
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
891
res= mysql_insert(session, all_tables, lex->field_list, lex->many_values,
892
lex->update_list, lex->value_list,
893
lex->duplicates, lex->ignore);
897
case SQLCOM_REPLACE_SELECT:
898
case SQLCOM_INSERT_SELECT:
900
select_result *sel_result;
901
assert(first_table == all_tables && first_table != 0);
902
if ((res= insert_precheck(session, all_tables)))
905
/* Don't unlock tables until command is written to binary log */
906
select_lex->options|= SELECT_NO_UNLOCK;
908
unit->set_limit(select_lex);
910
if (! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
916
if (!(res= session->open_and_lock_tables(all_tables)))
918
/* Skip first table, which is the table we are inserting in */
919
TableList *second_table= first_table->next_local;
920
select_lex->table_list.first= (unsigned char*) second_table;
921
select_lex->context.table_list=
922
select_lex->context.first_name_resolution_table= second_table;
923
res= mysql_insert_select_prepare(session);
924
if (!res && (sel_result= new select_insert(first_table,
932
res= handle_select(session, lex, sel_result, OPTION_SETUP_TABLES_DONE);
934
Invalidate the table in the query cache if something changed
935
after unlocking when changes become visible.
936
TODO: this is workaround. right way will be move invalidating in
937
the unlock procedure.
939
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
942
/* INSERT ... SELECT should invalidate only the very first table */
943
TableList *save_table= first_table->next_local;
944
first_table->next_local= 0;
945
first_table->next_local= save_table;
949
/* revert changes for SP */
950
select_lex->table_list.first= (unsigned char*) first_table;
955
case SQLCOM_TRUNCATE:
956
if (! session->endActiveTransaction())
961
assert(first_table == all_tables && first_table != 0);
963
Don't allow this within a transaction because we want to use
966
if (session->inTransaction())
968
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
972
res= mysql_truncate(session, first_table, 0);
977
assert(first_table == all_tables && first_table != 0);
978
assert(select_lex->offset_limit == 0);
979
unit->set_limit(select_lex);
981
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
987
res = mysql_delete(session, all_tables, select_lex->where,
988
&select_lex->order_list,
989
unit->select_limit_cnt, select_lex->options,
993
case SQLCOM_DELETE_MULTI:
995
assert(first_table == all_tables && first_table != 0);
996
TableList *aux_tables=
997
(TableList *)session->lex->auxiliary_table_list.first;
998
multi_delete *del_result;
1000
if (!(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
1006
if ((res= multi_delete_precheck(session, all_tables)))
1009
/* condition will be true on SP re-excuting */
1010
if (select_lex->item_list.elements != 0)
1011
select_lex->item_list.empty();
1012
if (session->add_item_to_list(new Item_null()))
1015
session->set_proc_info("init");
1016
if ((res= session->open_and_lock_tables(all_tables)))
1019
if ((res= mysql_multi_delete_prepare(session)))
1022
if (!session->is_fatal_error &&
1023
(del_result= new multi_delete(aux_tables, lex->table_count)))
1025
res= mysql_select(session, &select_lex->ref_pointer_array,
1026
select_lex->get_table_list(),
1027
select_lex->with_wild,
1028
select_lex->item_list,
1030
0, (order_st *)NULL, (order_st *)NULL, (Item *)NULL,
1031
select_lex->options | session->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE,
1032
del_result, unit, select_lex);
1033
res|= session->is_error();
1035
del_result->abort();
1042
case SQLCOM_DROP_TABLE:
1044
assert(first_table == all_tables && first_table != 0);
1045
if (!lex->drop_temporary)
1047
if (! session->endActiveTransaction())
1052
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
1053
session->options|= OPTION_KEEP_LOG;
1055
/* DDL and binlog write order protected by LOCK_open */
1056
res= mysql_rm_table(session, first_table, lex->drop_if_exists, lex->drop_temporary);
1059
case SQLCOM_SHOW_PROCESSLIST:
1060
mysqld_list_processes(session, NULL, lex->verbose);
1062
case SQLCOM_CHANGE_DB:
1064
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
1066
if (!mysql_change_db(session, &db_str, false))
1074
assert(first_table == all_tables && first_table != 0);
1075
res= mysql_load(session, lex->exchange, first_table, lex->field_list,
1076
lex->update_list, lex->value_list, lex->duplicates, lex->ignore);
1080
case SQLCOM_SET_OPTION:
1082
List<set_var_base> *lex_var_list= &lex->var_list;
1084
if (session->open_and_lock_tables(all_tables))
1086
if (!(res= sql_set_variables(session, lex_var_list)))
1093
We encountered some sort of error, but no message was sent.
1094
Send something semi-generic here since we don't know which
1095
assignment in the list caused the error.
1097
if (!session->is_error())
1098
my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
1105
case SQLCOM_UNLOCK_TABLES:
1107
It is critical for mysqldump --single-transaction --master-data that
1108
UNLOCK TABLES does not implicitely commit a connection which has only
1109
done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
1110
false, mysqldump will not work.
1112
if (session->global_read_lock)
1113
unlock_global_read_lock(session);
1116
case SQLCOM_CREATE_DB:
1119
As mysql_create_db() may modify HA_CREATE_INFO structure passed to
1120
it, we need to use a copy of LEX::create_info to make execution
1121
prepared statement- safe.
1123
HA_CREATE_INFO create_info(lex->create_info);
1124
if (! session->endActiveTransaction())
1130
if (!(alias=session->strmake(lex->name.str, lex->name.length)) ||
1131
check_db_name(&lex->name))
1133
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1136
res= mysql_create_db(session,(lex->name.str), &create_info);
1139
case SQLCOM_DROP_DB:
1141
if (! session->endActiveTransaction())
1146
if (check_db_name(&lex->name))
1148
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1151
if (session->inTransaction())
1153
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1156
res= mysql_rm_db(session, lex->name.str, lex->drop_if_exists);
1159
case SQLCOM_ALTER_DB:
1161
LEX_STRING *db= &lex->name;
1162
HA_CREATE_INFO create_info(lex->create_info);
1163
if (check_db_name(db))
1165
my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
1168
if (session->inTransaction())
1170
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1173
res= mysql_alter_db(session, db->str, &create_info);
1176
case SQLCOM_SHOW_CREATE_DB:
1178
if (check_db_name(&lex->name))
1180
my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
1183
res= mysqld_show_create_db(session, lex->name.str, &lex->create_info);
1189
reload_cache() will tell us if we are allowed to write to the
1192
if (!reload_cache(session, lex->type, first_table))
1195
We WANT to write and we CAN write.
1196
! we write after unlocking the table.
1199
Presumably, RESET and binlog writing doesn't require synchronization
1201
write_bin_log(session, false, session->query, session->query_length);
1209
Item *it= (Item *)lex->value_list.head();
1211
if ((!it->fixed && it->fix_fields(lex->session, &it)) || it->check_cols(1))
1213
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
1217
sql_kill(session, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
1221
if (session->transaction.xid_state.xa_state != XA_NOTR)
1223
my_error(ER_XAER_RMFAIL, MYF(0),
1224
xa_state_names[session->transaction.xid_state.xa_state]);
1228
Breakpoints for backup testing.
1230
if (! session->startTransaction())
1235
if (! session->endTransaction(lex->tx_release ? COMMIT_RELEASE : lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
1239
case SQLCOM_ROLLBACK:
1240
if (! session->endTransaction(lex->tx_release ? ROLLBACK_RELEASE : lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
1244
case SQLCOM_RELEASE_SAVEPOINT:
1247
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
1249
if (my_strnncoll(system_charset_info,
1250
(unsigned char *)lex->ident.str, lex->ident.length,
1251
(unsigned char *)sv->name, sv->length) == 0)
1256
if (ha_release_savepoint(session, sv))
1257
res= true; // cannot happen
1260
session->transaction.savepoints=sv->prev;
1263
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
1266
case SQLCOM_ROLLBACK_TO_SAVEPOINT:
1269
for (sv=session->transaction.savepoints; sv; sv=sv->prev)
1271
if (my_strnncoll(system_charset_info,
1272
(unsigned char *)lex->ident.str, lex->ident.length,
1273
(unsigned char *)sv->name, sv->length) == 0)
1278
if (ha_rollback_to_savepoint(session, sv))
1279
res= true; // cannot happen
1282
if ((session->options & OPTION_KEEP_LOG) || session->transaction.all.modified_non_trans_table)
1283
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1284
ER_WARNING_NOT_COMPLETE_ROLLBACK,
1285
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1288
session->transaction.savepoints=sv;
1291
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
1294
case SQLCOM_SAVEPOINT:
1295
if (!(session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
1299
SAVEPOINT **sv, *newsv;
1300
for (sv=&session->transaction.savepoints; *sv; sv=&(*sv)->prev)
1302
if (my_strnncoll(system_charset_info,
1303
(unsigned char *)lex->ident.str, lex->ident.length,
1304
(unsigned char *)(*sv)->name, (*sv)->length) == 0)
1307
if (*sv) /* old savepoint of the same name exists */
1310
ha_release_savepoint(session, *sv); // it cannot fail
1313
else if ((newsv=(SAVEPOINT *) alloc_root(&session->transaction.mem_root,
1314
savepoint_alloc_size)) == 0)
1316
my_error(ER_OUT_OF_RESOURCES, MYF(0));
1319
newsv->name=strmake_root(&session->transaction.mem_root,
1320
lex->ident.str, lex->ident.length);
1321
newsv->length=lex->ident.length;
1323
if we'll get an error here, don't add new savepoint to the list.
1324
we'll lose a little bit of memory in transaction mem_root, but it'll
1325
be free'd when transaction ends anyway
1327
if (ha_savepoint(session, newsv))
1331
newsv->prev=session->transaction.savepoints;
1332
session->transaction.savepoints=newsv;
1338
assert(0); /* Impossible */
483
1342
session->set_proc_info("query end");