12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
#include "config.h"
39
39
#include <drizzled/statement.h>
40
40
#include <drizzled/statement/alter_table.h>
41
41
#include "drizzled/probes.h"
42
#include "drizzled/session/cache.h"
42
#include "drizzled/session_list.h"
43
43
#include "drizzled/global_charset_info.h"
45
45
#include "drizzled/plugin/logging.h"
46
46
#include "drizzled/plugin/query_rewrite.h"
47
#include "drizzled/plugin/query_cache.h"
48
47
#include "drizzled/plugin/authorization.h"
49
48
#include "drizzled/optimizer/explain_plan.h"
50
49
#include "drizzled/pthread_globals.h"
51
#include "drizzled/plugin/event_observer.h"
53
51
#include <limits.h>
56
54
#include <algorithm>
57
#include <boost/date_time.hpp>
58
56
#include "drizzled/internal/my_sys.h"
60
58
using namespace std;
171
169
Query_id &query_id= Query_id::get_query_id();
173
DRIZZLE_COMMAND_START(session->thread_id, command);
171
DRIZZLE_COMMAND_START(session->thread_id,
175
174
session->command= command;
176
175
session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
184
183
/* Increase id and count all other statements. */
186
session->status_var.questions++;
185
statistic_increment(session->status_var.questions, &LOCK_status);
190
189
/* TODO: set session->lex->sql_command to SQLCOM_END here */
192
191
plugin::Logging::preDo(session);
193
if (unlikely(plugin::EventObserver::beforeStatement(*session)))
195
// We should do something about an error...
198
193
session->server_status&=
199
194
~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
221
if (not session->readAndStoreQuery(packet, packet_length))
216
if (! session->readAndStoreQuery(packet, packet_length))
222
217
break; // fatal error is set
223
DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
218
DRIZZLE_QUERY_START(session->query.c_str(),
224
219
session->thread_id,
225
const_cast<const char *>(session->schema()->c_str()));
220
const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
227
mysql_parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
222
plugin::QueryRewriter::rewriteQuery(session->db, session->query);
223
mysql_parse(session, session->query.c_str(), session->query.length());
269
265
if (! session->main_da.is_set())
270
266
session->send_kill_message();
272
if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
268
if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
274
session->setKilled(Session::NOT_KILLED);
275
session->setAbort(false);
270
session->killed= Session::NOT_KILLED;
271
session->mysys_var->abort= 0;
278
274
/* Can not be true, but do not take chances in production. */
310
306
session->close_thread_tables();
312
308
plugin::Logging::postDo(session);
313
if (unlikely(plugin::EventObserver::afterStatement(*session)))
315
// We should do something about an error...
318
310
/* Store temp state for processlist */
319
311
session->set_proc_info("cleaning up");
320
312
session->command= COM_SLEEP;
321
session->resetQueryString();
313
memset(session->process_list_info, 0, PROCESS_LIST_WIDTH);
314
session->query.clear();
323
316
session->set_proc_info(NULL);
324
317
session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
374
366
session->make_lex_string(&table, schema_table_name, false);
376
368
if (! sel->add_table_to_list(session, new Table_ident(db, table),
377
NULL, table_options, TL_READ))
437
430
Select_Lex *select_lex= &lex->select_lex;
438
431
/* list of all tables in query */
439
432
TableList *all_tables;
433
/* A peek into the query string */
434
size_t proc_info_len= session->query.length() > PROCESS_LIST_WIDTH ?
435
PROCESS_LIST_WIDTH : session->query.length();
437
memcpy(session->process_list_info, session->query.c_str(), proc_info_len);
438
session->process_list_info[proc_info_len]= '\0';
442
441
In many cases first table of main Select_Lex have special meaning =>
478
477
/* now we are ready to execute the statement */
479
478
res= lex->statement->execute();
480
480
session->set_proc_info("query end");
482
483
The return value for ROW_COUNT() is "implementation dependent" if the
483
484
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
539
541
if (!result && !(result= new select_send()))
542
/* Init the Query Cache plugin */
543
plugin::QueryCache::prepareResultset(session);
544
543
res= handle_select(session, lex, result, 0);
545
/* Send the Resultset to the cache */
546
plugin::QueryCache::setResultset(session);
548
544
if (result != lex->result)
717
713
void mysql_parse(Session *session, const char *inBuf, uint32_t length)
719
boost::posix_time::ptime start_time=boost::posix_time::microsec_clock::local_time();
720
session->lex->start(session);
722
716
session->reset_for_next_command();
723
/* Check if the Query is Cached if and return true if yes
724
* TODO the plugin has to make sure that the query is cacheble
725
* by setting the query_safe_cache param to TRUE
728
if (plugin::QueryCache::isCached(session))
730
res= plugin::QueryCache::sendCachedResultset(session);
736
718
LEX *lex= session->lex;
737
720
Lex_input_stream lip(session, inBuf, length);
738
722
bool err= parse_sql(session, &lip);
742
if (not session->is_error())
727
if (! session->is_error())
744
DRIZZLE_QUERY_EXEC_START(session->getQueryString()->c_str(),
729
DRIZZLE_QUERY_EXEC_START(session->query.c_str(),
745
730
session->thread_id,
746
const_cast<const char *>(session->schema()->c_str()));
747
// Implement Views here --Brian
731
const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
748
732
/* Actually execute the query */
751
mysql_execute_command(session);
755
// Just try to catch any random failures that could have come
733
mysql_execute_command(session);
759
734
DRIZZLE_QUERY_EXEC_DONE(0);
765
740
assert(session->is_error());
767
743
lex->unit.cleanup();
768
744
session->set_proc_info("freeing items");
769
745
session->end_statement();
770
746
session->cleanup_after_query();
771
boost::posix_time::ptime end_time=boost::posix_time::microsec_clock::local_time();
772
session->status_var.execution_time_nsec+=(end_time-start_time).total_microseconds();
899
875
TableList *Select_Lex::add_table_to_list(Session *session,
902
const bitset<NUM_OF_TABLE_OPTIONS>& table_options,
903
thr_lock_type lock_type,
904
List<Index_hint> *index_hints_arg,
878
uint32_t table_options,
879
thr_lock_type lock_type,
880
List<Index_hint> *index_hints_arg,
883
register TableList *ptr;
908
884
TableList *previous_table_ref; /* The table preceding the current one. */
910
886
LEX *lex= session->lex;
913
889
return NULL; // End of memory
914
890
alias_str= alias ? alias->str : table->table.str;
915
if (! table_options.test(TL_OPTION_ALIAS) &&
891
if (!test(table_options & TL_OPTION_ALIAS) &&
916
892
check_table_name(table->table.str, table->table.length))
918
894
my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
946
922
if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
949
924
if (table->db.str)
951
ptr->setIsFqtn(true);
952
ptr->setSchemaName(table->db.str);
927
ptr->db= table->db.str;
953
928
ptr->db_length= table->db.length;
955
else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
930
else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
958
ptr->setIsFqtn(false);
960
935
ptr->alias= alias_str;
961
ptr->setIsAlias(alias ? true : false);
962
ptr->setTableName(table->table.str);
936
ptr->is_alias= alias ? true : false;
937
if (table->table.length)
938
table->table.length= my_casedn_str(files_charset_info, table->table.str);
939
ptr->table_name=table->table.str;
963
940
ptr->table_name_length=table->table.length;
964
941
ptr->lock_type= lock_type;
965
ptr->force_index= table_options.test(TL_OPTION_FORCE_INDEX);
966
ptr->ignore_leaves= table_options.test(TL_OPTION_IGNORE_LEAVES);
942
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
943
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
967
944
ptr->derived= table->sel;
968
945
ptr->select_lex= lex->current_select;
969
946
ptr->index_hints= index_hints_arg;
977
954
tables=tables->next_local)
979
956
if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
980
!strcasecmp(ptr->getSchemaName(), tables->getSchemaName()))
957
!strcasecmp(ptr->db, tables->db))
982
959
my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
1046
1023
if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1047
1024
sizeof(nested_join_st))))
1049
ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1050
nested_join= ptr->getNestedJoin();
1026
nested_join= ptr->nested_join=
1027
((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
1051
1029
join_list->push_front(ptr);
1052
ptr->setEmbedding(embedding);
1053
ptr->setJoinList(join_list);
1030
ptr->embedding= embedding;
1031
ptr->join_list= join_list;
1054
1032
ptr->alias= (char*) "(nested_join)";
1055
1033
embedding= ptr;
1056
1034
join_list= &nested_join->join_list;
1081
1059
assert(embedding);
1082
1060
ptr= embedding;
1083
join_list= ptr->getJoinList();
1084
embedding= ptr->getEmbedding();
1085
nested_join= ptr->getNestedJoin();
1061
join_list= ptr->join_list;
1062
embedding= ptr->embedding;
1063
nested_join= ptr->nested_join;
1086
1064
if (nested_join->join_list.elements == 1)
1088
1066
TableList *embedded= nested_join->join_list.head();
1089
1067
join_list->pop();
1090
embedded->setJoinList(join_list);
1091
embedded->setEmbedding(embedding);
1068
embedded->join_list= join_list;
1069
embedded->embedding= embedding;
1092
1070
join_list->push_front(embedded);
1121
1099
List<TableList> *embedded_list;
1123
1101
if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1124
sizeof(nested_join_st))))
1102
sizeof(nested_join_st))))
1126
ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1127
nested_join= ptr->getNestedJoin();
1128
ptr->setEmbedding(embedding);
1129
ptr->setJoinList(join_list);
1104
nested_join= ptr->nested_join=
1105
((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
1107
ptr->embedding= embedding;
1108
ptr->join_list= join_list;
1130
1109
ptr->alias= (char*) "(nest_last_join)";
1131
1110
embedded_list= &nested_join->join_list;
1132
1111
embedded_list->empty();
1134
1113
for (uint32_t i=0; i < 2; i++)
1136
1115
TableList *table= join_list->pop();
1137
table->setJoinList(embedded_list);
1138
table->setEmbedding(ptr);
1116
table->join_list= embedded_list;
1117
table->embedding= ptr;
1139
1118
embedded_list->push_back(table);
1140
1119
if (table->natural_join)
1171
1150
void Select_Lex::add_joined_table(TableList *table)
1173
1152
join_list->push_front(table);
1174
table->setJoinList(join_list);
1175
table->setEmbedding(embedding);
1153
table->join_list= join_list;
1154
table->embedding= embedding;
1399
@param session Thread class
1401
@param only_kill_query Should it kill the query or the connection
1404
This is written such that we have a short lock on LOCK_thread_count
1408
kill_one_thread(Session *, ulong id, bool only_kill_query)
1411
uint32_t error= ER_NO_SUCH_THREAD;
1412
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1414
for (SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
1416
if ((*it)->thread_id == id)
1419
pthread_mutex_lock(&tmp->LOCK_delete); // Lock from delete
1423
pthread_mutex_unlock(&LOCK_thread_count);
1427
if (tmp->isViewable())
1429
tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
1433
pthread_mutex_unlock(&tmp->LOCK_delete);
1440
kills a thread and sends response
1444
session Thread class
1446
only_kill_query Should it kill the query or the connection
1449
void sql_kill(Session *session, ulong id, bool only_kill_query)
1452
if (!(error= kill_one_thread(session, id, only_kill_query)))
1455
my_error(error, MYF(0), id);
1418
1460
Check if the select is a simple select (not an union).
1587
CREATE TABLE query pre-check.
1589
@param session Thread handler
1590
@param tables Global table list
1591
@param create_table Table which will be created
1599
bool create_table_precheck(TableIdentifier &identifier)
1601
if (not plugin::StorageEngine::canCreateTable(identifier))
1603
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", identifier.getSchemaName().c_str());
1607
if (not plugin::StorageEngine::doesSchemaExist(identifier))
1609
my_error(ER_BAD_DB_ERROR, MYF(0), identifier.getSchemaName().c_str());
1545
1618
negate given expression.
1547
1620
@param session thread handler