21
21
* @file Implementation of the Session class and API
26
#include <drizzled/copy_field.h>
27
#include <drizzled/data_home.h>
28
#include <drizzled/display.h>
29
#include <drizzled/drizzled.h>
25
#include <drizzled/session.h>
26
#include "drizzled/session_list.h"
30
28
#include <drizzled/error.h>
31
29
#include <drizzled/gettext.h>
32
#include <drizzled/identifier.h>
33
#include <drizzled/internal/iocache.h>
34
#include <drizzled/internal/thread_var.h>
35
#include <drizzled/internal_error_handler.h>
30
#include <drizzled/query_id.h>
31
#include <drizzled/data_home.h>
32
#include <drizzled/sql_base.h>
33
#include <drizzled/lock.h>
36
34
#include <drizzled/item/cache.h>
37
#include <drizzled/item/empty_string.h>
38
35
#include <drizzled/item/float.h>
39
36
#include <drizzled/item/return_int.h>
40
#include <drizzled/lock.h>
41
#include <drizzled/plugin/authentication.h>
37
#include <drizzled/item/empty_string.h>
38
#include <drizzled/show.h>
42
39
#include <drizzled/plugin/client.h>
43
#include <drizzled/plugin/event_observer.h>
44
#include <drizzled/plugin/logging.h>
45
#include <drizzled/plugin/query_rewrite.h>
46
#include <drizzled/plugin/scheduler.h>
47
#include <drizzled/plugin/transactional_storage_engine.h>
48
#include <drizzled/probes.h>
49
#include <drizzled/pthread_globals.h>
50
#include <drizzled/query_id.h>
51
#include <drizzled/refresh_version.h>
52
#include <drizzled/select_dump.h>
53
#include <drizzled/select_exists_subselect.h>
54
#include <drizzled/select_export.h>
55
#include <drizzled/select_max_min_finder_subselect.h>
56
#include <drizzled/select_singlerow_subselect.h>
57
#include <drizzled/select_subselect.h>
58
#include <drizzled/select_to_file.h>
59
#include <drizzled/session.h>
60
#include <drizzled/session/cache.h>
61
#include <drizzled/show.h>
62
#include <drizzled/sql_base.h>
63
#include <drizzled/table/singular.h>
64
#include <drizzled/table_proto.h>
65
#include <drizzled/tmp_table_param.h>
66
#include <drizzled/transaction_services.h>
67
#include <drizzled/user_var_entry.h>
68
#include <drizzled/util/functors.h>
69
#include <plugin/myisam/myisam.h>
40
#include "drizzled/plugin/scheduler.h"
41
#include "drizzled/plugin/authentication.h"
42
#include "drizzled/plugin/logging.h"
43
#include "drizzled/plugin/transactional_storage_engine.h"
44
#include "drizzled/probes.h"
45
#include "drizzled/table_proto.h"
46
#include "drizzled/db.h"
47
#include "drizzled/pthread_globals.h"
48
#include "drizzled/transaction_services.h"
49
#include "drizzled/drizzled.h"
51
#include "drizzled/table_share_instance.h"
53
#include "plugin/myisam/myisam.h"
54
#include "drizzled/internal/iocache.h"
55
#include "drizzled/internal/thread_var.h"
56
#include "drizzled/plugin/event_observer.h"
71
59
#include <algorithm>
76
#include <boost/filesystem.hpp>
77
#include <boost/checked_delete.hpp>
79
#include <drizzled/util/backtrace.h>
81
#include <drizzled/schema.h>
83
62
using namespace std;
85
namespace fs=boost::filesystem;
94
71
char empty_c_string[1]= {0}; /* used for not defined db */
96
73
const char * const Session::DEFAULT_WHERE= "field list";
74
extern pthread_key_t THR_Session;
75
extern pthread_key_t THR_Mem_root;
98
77
bool Key_part_spec::operator==(const Key_part_spec& other) const
100
79
return length == other.length &&
101
80
field_name.length == other.field_name.length &&
102
!my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
81
!strcmp(field_name.str, other.field_name.str);
105
84
Open_tables_state::Open_tables_state(uint64_t version_arg) :
105
int session_tablespace_op(const Session *session)
107
return test(session->tablespace_op);
111
Set the process info field of the Session structure.
113
This function is used by plug-ins. Internally, the
114
Session::set_proc_info() function should be used.
116
@see Session::set_proc_info
118
void set_session_proc_info(Session *session, const char *info)
120
session->set_proc_info(info);
123
const char *get_session_proc_info(Session *session)
125
return session->get_proc_info();
126
128
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
128
130
return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
139
141
return session->options & test_options;
142
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
144
int session_sql_command(const Session *session)
146
return (int) session->lex->sql_command;
149
enum_tx_isolation session_tx_isolation(const Session *session)
151
return (enum_tx_isolation)session->variables.tx_isolation;
154
Session::Session(plugin::Client *client_arg) :
143
155
Open_tables_state(refresh_version),
144
156
mem_root(&main_mem_root),
147
query(new std::string),
148
_schema(new std::string("")),
149
159
client(client_arg),
151
161
scheduler_arg(NULL),
152
162
lock_id(&main_lock_id),
154
security_ctx(identifier::User::make_shared()),
155
_where(Session::DEFAULT_WHERE),
156
dbug_sentry(Session_SENTRY_MAGIC),
158
command(COM_CONNECT),
160
_epoch(boost::gregorian::date(1970,1,1)),
161
_connect_time(boost::posix_time::microsec_clock::universal_time()),
163
164
ha_data(plugin::num_trx_monitored_objects),
166
concurrent_execute_allowed(true),
167
165
arg_of_last_insert_id_function(false),
168
166
first_successful_insert_id_in_prev_stmt(0),
169
167
first_successful_insert_id_in_cur_stmt(0),
170
168
limit_found_rows(0),
171
options(session_startup_options),
174
examined_row_count(0),
178
statement_id_counter(0),
182
_global_read_lock(NONE),
183
count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
185
170
some_tables_deleted(false),
186
171
no_errors(false),
188
173
is_fatal_error(false),
189
174
transaction_rollback_request(false),
190
175
is_fatal_sub_stmt_error(0),
176
derived_tables_processing(false),
191
177
tablespace_op(false),
192
derived_tables_processing(false),
195
180
transaction_message(NULL),
196
181
statement_message(NULL),
197
session_event_observers(NULL),
198
_catalog(catalog_arg),
182
session_event_observers(NULL)
184
memset(process_list_info, 0, PROCESS_LIST_WIDTH);
201
185
client->setSession(this);
206
190
will be re-initialized in init_for_queries().
208
192
memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
194
count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
209
199
cuted_fields= sent_row_count= row_count= 0L;
201
statement_id_counter= 0UL;
210
202
// Must be reset to handle error with Session's created for init of mysqld
211
203
lex->current_select= 0;
204
start_time=(time_t) 0;
206
utime_after_lock= 0L;
212
207
memset(&variables, 0, sizeof(variables));
213
213
scoreboard_index= -1;
214
cleanup_done= abort_on_warning= no_warnings_for_error= false;
216
/* query_cache init */
214
dbug_sentry=Session_SENTRY_MAGIC;
215
cleanup_done= abort_on_warning= no_warnings_for_error= false;
220
217
/* Variables with default values */
221
218
proc_info="login";
219
where= Session::DEFAULT_WHERE;
220
command= COM_CONNECT;
223
222
plugin_sessionvar_init(this);
299
boost_unique_lock_t scopedLock(mysys_var->mutex);
300
pthread_mutex_lock(&mysys_var->mutex);
300
301
if (mysys_var->current_cond)
302
mysys_var->current_mutex->lock();
303
mysys_var->current_cond->notify_all();
304
mysys_var->current_mutex->unlock();
303
pthread_mutex_lock(mysys_var->current_mutex);
304
pthread_cond_broadcast(mysys_var->current_cond);
305
pthread_mutex_unlock(mysys_var->current_mutex);
307
pthread_mutex_unlock(&mysys_var->mutex);
308
310
void Session::pop_internal_handler()
360
360
this->checkSentry();
362
if (client and client->isConnected())
362
if (client->isConnected())
364
assert(security_ctx);
365
364
if (global_system_variables.log_warnings)
367
errmsg_printf(error::WARN, ER(ER_FORCING_CLOSE),
368
internal::my_progname,
370
security_ctx->username().c_str());
365
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
367
(getSecurityContext().getUser().c_str() ?
368
getSecurityContext().getUser().c_str() : ""));
369
disconnect(0, false);
376
372
/* Close connection */
380
boost::checked_delete(client);
384
376
if (cleanup_done == false)
392
384
dbug_sentry= Session_SENTRY_GONE;
394
386
main_mem_root.free_root(MYF(0));
395
currentMemRoot().release();
396
currentSession().release();
387
pthread_setspecific(THR_Session, 0);
398
389
plugin::Logging::postEndDo(this);
399
390
plugin::EventObserver::deregisterSessionEvents(*this);
402
void Session::setClient(plugin::Client *client_arg)
405
client->setSession(this);
408
void Session::awake(Session::killed_state_t state_to_set)
410
if ((state_to_set == Session::KILL_QUERY) and (command == COM_SLEEP))
392
/* Ensure that no one is using Session */
393
LOCK_delete.unlock();
396
void Session::awake(Session::killed_state state_to_set)
413
398
this->checkSentry();
415
setKilled(state_to_set);
416
scheduler->killSession(this);
399
safe_mutex_assert_owner(&LOCK_delete);
401
killed= state_to_set;
418
402
if (state_to_set != Session::KILL_QUERY)
404
scheduler->killSession(this);
420
405
DRIZZLE_CONNECTION_DONE(thread_id);
425
boost_unique_lock_t scopedLock(mysys_var->mutex);
409
pthread_mutex_lock(&mysys_var->mutex);
428
411
This broadcast could be up in the air if the victim thread
429
412
exits the cond in the time between read and broadcast, but that is
430
413
ok since all we want to do is to make the victim thread get out
527
508
if (initGlobals() || authenticate())
533
514
prepareForQueries();
535
while (not client->haveError() && getKilled() != KILL_CONNECTION)
516
while (! client->haveError() && killed != KILL_CONNECTION)
537
if (not executeStatement())
518
if (! executeStatement())
544
bool Session::schedule(Session::shared_ptr &arg)
525
bool Session::schedule()
546
arg->scheduler= plugin::Scheduler::getScheduler();
547
assert(arg->scheduler);
551
long current_connections= connection_count;
553
if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
555
current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
558
current_global_counters.connections++;
559
arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
561
session::Cache::singleton().insert(arg);
563
if (unlikely(plugin::EventObserver::connectSession(*arg)))
565
// We should do something about an error...
568
if (plugin::Scheduler::getScheduler()->addSession(arg))
570
DRIZZLE_CONNECTION_START(arg->getSessionId());
527
scheduler= plugin::Scheduler::getScheduler();
530
connection_count.increment();
532
if (connection_count > current_global_counters.max_used_connections)
534
current_global_counters.max_used_connections= connection_count;
537
thread_id= variables.pseudo_thread_id= global_thread_id++;
539
LOCK_thread_count.lock();
540
getSessionList().push_back(this);
541
LOCK_thread_count.unlock();
543
if (scheduler->addSession(this))
545
DRIZZLE_CONNECTION_START(thread_id);
571
546
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
573
arg->setKilled(Session::KILL_CONNECTION);
548
killed= Session::KILL_CONNECTION;
575
arg->status_var.aborted_connects++;
550
status_var.aborted_connects++;
577
552
/* Can't use my_error() since store_globals has not been called. */
578
553
/* TODO replace will better error message */
579
554
snprintf(error_message_buff, sizeof(error_message_buff),
580
555
ER(ER_CANT_CREATE_THREAD), 1);
581
arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
556
client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
591
Is this session viewable by the current user?
593
bool Session::isViewable(identifier::User::const_reference user_arg) const
595
return plugin::Authorization::isAuthorized(user_arg, *this, false);
599
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
564
const char* Session::enter_cond(boost::condition_variable &cond, boost::mutex &mutex, const char* msg)
601
566
const char* old_msg = get_proc_info();
602
567
safe_mutex_assert_owner(mutex);
603
mysys_var->current_mutex = &mutex;
604
mysys_var->current_cond = &cond;
568
mysys_var->current_mutex = mutex.native_handle();
569
mysys_var->current_cond = cond.native_handle();
605
570
this->set_proc_info(msg);
614
579
locked (if that would not be the case, you'll get a deadlock if someone
615
580
does a Session::awake() on you).
617
mysys_var->current_mutex->unlock();
618
boost_unique_lock_t scopedLock(mysys_var->mutex);
582
pthread_mutex_unlock(mysys_var->current_mutex);
583
pthread_mutex_lock(&mysys_var->mutex);
619
584
mysys_var->current_mutex = 0;
620
585
mysys_var->current_cond = 0;
621
586
this->set_proc_info(old_msg);
587
pthread_mutex_unlock(&mysys_var->mutex);
624
590
bool Session::authenticate()
626
593
if (client->authenticate())
647
615
/* Change database if necessary */
648
if (not in_db.empty())
616
if (in_db && in_db[0])
650
identifier::Schema identifier(in_db);
651
if (schema::change(*this, identifier))
618
SchemaIdentifier identifier(in_db);
619
if (mysql_change_db(this, identifier))
653
/* change_db() has pushed the error message. */
621
/* mysql_change_db() has pushed the error message. */
658
password= not passwd_str.empty();
626
password= test(passwd_len); // remember for error messages
660
628
/* Ready to handle queries */
677
645
main_da.reset_diagnostics_area();
679
647
if (client->readCommand(&l_packet, &packet_length) == false)
684
if (getKilled() == KILL_CONNECTION)
687
650
if (packet_length == 0)
690
l_command= static_cast<enum_server_command>(l_packet[0]);
653
l_command= (enum enum_server_command) (unsigned char) l_packet[0];
692
655
if (command >= COM_END)
693
656
command= COM_END; // Wrong command
695
658
assert(packet_length);
696
return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
659
return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
699
662
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
705
668
in_packet_length--;
707
670
const char *pos= in_packet + in_packet_length; /* Point at end null */
708
while (in_packet_length > 0 && (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
671
while (in_packet_length > 0 &&
672
(pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
711
675
in_packet_length--;
714
std::string *new_query= new std::string(in_packet, in_packet + in_packet_length);
715
// We can not be entirely sure _schema has a value
718
plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
720
query.reset(new_query);
721
_state.reset(new session::State(in_packet, in_packet_length));
678
query.assign(in_packet, in_packet + in_packet_length);
838
796
first_successful_insert_id_in_cur_stmt= 0;
839
797
substitute_null_with_insert_id= true;
842
799
arg_of_last_insert_id_function= false;
844
800
/* Free Items that were created during this execution */
848
_where= Session::DEFAULT_WHERE;
803
where= Session::DEFAULT_WHERE;
850
805
/* Reset the temporary shares we built */
851
for_each(temporary_shares.begin(),
852
temporary_shares.end(),
806
for (std::vector<TableShareInstance *>::iterator iter= temporary_shares.begin();
807
iter != temporary_shares.end(); iter++)
854
811
temporary_shares.clear();
931
888
Handling writing to file
932
889
************************************************************************/
934
void select_to_file::send_error(drizzled::error_t errcode,const char *err)
891
void select_to_file::send_error(uint32_t errcode,const char *err)
936
893
my_message(errcode, err, MYF(0));
939
(void) cache->end_io_cache();
896
(void) end_io_cache(cache);
940
897
(void) internal::my_close(file, MYF(0));
941
(void) internal::my_delete(path.file_string().c_str(), MYF(0)); // Delete file on error
898
(void) internal::my_delete(path, MYF(0)); // Delete file on error
1019
static int create_file(Session *session,
1020
fs::path &target_path,
1021
file_exchange *exchange,
1022
internal::IO_CACHE *cache)
976
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1024
fs::path to_file(exchange->file_name);
1027
if (not to_file.has_root_directory())
979
uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
981
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
982
option|= MY_REPLACE_DIR; // Force use of db directory
985
if (!internal::dirname_length(exchange->file_name))
1029
target_path= fs::system_complete(getDataHomeCatalog());
1030
util::string::const_shared_ptr schema(session->schema());
1031
if (schema and not schema->empty())
1033
int count_elements= 0;
1034
for (fs::path::iterator iter= to_file.begin();
1035
iter != to_file.end();
1036
++iter, ++count_elements)
1039
if (count_elements == 1)
1041
target_path /= *schema;
1044
target_path /= to_file;
987
strcpy(path, data_home_real);
988
if (! session->db.empty())
989
strncat(path, session->db.c_str(), FN_REFLEN-strlen(data_home_real)-1);
990
(void) internal::fn_format(path, exchange->file_name, path, "", option);
1048
target_path = exchange->file_name;
1051
if (not secure_file_priv.string().empty())
1053
if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1055
/* Write only allowed to dir or subdir specified by secure_file_priv */
1056
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1061
if (!access(target_path.file_string().c_str(), F_OK))
993
(void) internal::fn_format(path, exchange->file_name, data_home_real, "", option);
995
if (opt_secure_file_priv &&
996
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
998
/* Write only allowed to dir or subdir specified by secure_file_priv */
999
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1003
if (!access(path, F_OK))
1063
1005
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1066
1008
/* Create the file world readable */
1067
if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1009
if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1069
1011
(void) fchmod(file, 0666); // Because of umask()
1070
if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1012
if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1072
1014
internal::my_close(file, MYF(0));
1073
internal::my_delete(target_path.file_string().c_str(), MYF(0)); // Delete file on error, it was just created
1015
internal::my_delete(path, MYF(0)); // Delete file on error, it was just created
1300
1238
for (; length > sizeof(space) ; length-=sizeof(space))
1302
1240
if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1305
1243
if (my_b_write(cache,(unsigned char*) space,length))
1309
1247
if (res && enclosed)
1311
1249
if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1312
1250
exchange->enclosed->length()))
1315
1253
if (--items_left)
1317
1255
if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1318
1256
field_term_length))
1322
1260
if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1323
1261
exchange->line_term->length()))
1485
1424
bool select_max_min_finder_subselect::cmp_decimal()
1487
1426
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1488
type::Decimal cval, *cvalue= cache->val_decimal(&cval);
1489
type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
1427
my_decimal cval, *cvalue= cache->val_decimal(&cval);
1428
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1491
1430
return (cache->null_value && !maxmin->null_value) ||
1492
1431
(!cache->null_value && !maxmin->null_value &&
1493
class_decimal_cmp(cvalue, mvalue) > 0) ;
1432
my_decimal_cmp(cvalue, mvalue) > 0) ;
1494
1433
return (maxmin->null_value && !cache->null_value) ||
1495
1434
(!cache->null_value && !maxmin->null_value &&
1496
class_decimal_cmp(cvalue,mvalue) < 0);
1435
my_decimal_cmp(cvalue,mvalue) < 0);
1499
1438
bool select_max_min_finder_subselect::cmp_str()
1535
1474
void Session::end_statement()
1537
1476
/* Cleanup SQL processing state to reuse this statement in next query. */
1539
query_cache_key= ""; // reset the cache key
1540
resetResultsetMessage();
1543
1480
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1546
if (_schema and _schema->empty())
1548
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1551
else if (not _schema)
1553
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1558
*p_db= strmake(_schema->c_str(), _schema->size());
1559
*p_db_length= _schema->size();
1484
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1487
*p_db= strmake(db.c_str(), db.length());
1488
*p_db_length= db.length();
1600
void Session::set_db(const std::string &new_db)
1528
bool Session::set_db(const std::string &new_db)
1602
1530
/* Do not reallocate memory if current chunk is big enough. */
1603
1531
if (new_db.length())
1605
_schema.reset(new std::string(new_db));
1609
_schema.reset(new std::string(""));
1543
Check the killed state of a user thread
1544
@param session user thread
1545
@retval 0 the user thread is active
1546
@retval 1 the user thread has been killed
1548
int session_killed(const Session *session)
1550
return(session->killed);
1554
const struct charset_info_st *session_charset(Session *session)
1556
return(session->charset());
1615
1560
Mark transaction to rollback and mark error as fatal to a sub-statement.
1617
1562
@param session Thread handle
1618
1563
@param all true <=> rollback main transaction.
1620
void Session::markTransactionForRollback(bool all)
1565
void mark_transaction_to_rollback(Session *session, bool all)
1622
is_fatal_sub_stmt_error= true;
1623
transaction_rollback_request= all;
1569
session->is_fatal_sub_stmt_error= true;
1570
session->transaction_rollback_request= all;
1626
void Session::disconnect(enum error_t errcode)
1574
void Session::disconnect(uint32_t errcode, bool should_lock)
1628
1576
/* Allow any plugins to cleanup their session variables */
1629
1577
plugin_sessionvar_cleanup(this);
1631
1579
/* If necessary, log any aborted or unauthorized connections */
1632
if (getKilled() || client->wasAborted())
1580
if (killed || client->wasAborted())
1634
1582
status_var.aborted_threads++;
1637
1585
if (client->wasAborted())
1639
if (not getKilled() && variables.log_warnings > 1)
1587
if (! killed && variables.log_warnings > 1)
1641
errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
1589
SecurityContext *sctx= &security_ctx;
1591
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1643
, (_schema->empty() ? "unconnected" : _schema->c_str())
1644
, security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
1645
, security_ctx->address().c_str()
1593
, (db.empty() ? "unconnected" : db.c_str())
1594
, sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1595
, sctx->getIp().c_str()
1646
1596
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1650
setKilled(Session::KILL_CONNECTION);
1600
/* Close out our connection to the client */
1602
LOCK_thread_count.lock();
1603
killed= Session::KILL_CONNECTION;
1652
1604
if (client->isConnected())
1654
if (errcode != EE_OK)
1656
1608
/*my_error(errcode, ER(errcode));*/
1657
1609
client->sendError(errcode, ER(errcode));
1659
1611
client->close();
1614
(void) LOCK_thread_count.unlock();
1663
1617
void Session::reset_for_next_command()
1741
1695
If this is needed, use close_temporary_table()
1744
void Open_tables_state::nukeTable(Table *table)
1698
void Session::nukeTable(Table *table)
1746
1700
plugin::StorageEngine *table_type= table->getShare()->db_type();
1748
1702
table->free_io_cache();
1749
1703
table->delete_table();
1751
identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1705
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1752
1706
rm_temporary_table(table_type, identifier);
1754
boost::checked_delete(table->getMutableShare());
1708
delete table->getMutableShare();
1756
boost::checked_delete(table);
1710
/* This makes me sad, but we're allocating it via malloc */
1759
1714
/** Clear most status variables. */
1767
1722
flush_status_time= time((time_t*) 0);
1768
1723
current_global_counters.max_used_connections= 1; /* We set it to one, because we know we exist */
1769
current_global_counters.connections= 0;
1772
1726
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1774
return getVariable(std::string(name.str, name.length), create_if_not_exists);
1777
user_var_entry *Session::getVariable(const std::string &name, bool create_if_not_exists)
1782
UserVars::iterator iter= user_vars.find(name);
1783
if (iter != user_vars.end())
1784
return (*iter).second;
1786
if (not create_if_not_exists)
1789
1728
user_var_entry *entry= NULL;
1790
entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1795
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1797
if (not returnable.second)
1799
boost::checked_delete(entry);
1729
UserVarsRange ppp= user_vars.equal_range(std::string(name.str, name.length));
1731
for (UserVars::iterator iter= ppp.first;
1732
iter != ppp.second; ++iter)
1734
entry= (*iter).second;
1737
if ((entry == NULL) && create_if_not_exists)
1739
entry= new (nothrow) user_var_entry(name.str, query_id);
1744
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(std::string(name.str, name.length), entry));
1746
if (not returnable.second)
1805
void Session::setVariable(const std::string &name, const std::string &value)
1807
user_var_entry *updateable_var= getVariable(name.c_str(), true);
1810
updateable_var->update_hash(false,
1811
(void*)value.c_str(),
1812
static_cast<uint32_t>(value.length()), STRING_RESULT,
1814
DERIVATION_IMPLICIT, false);
1818
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1756
void Session::mark_temp_tables_as_free_for_reuse()
1820
1758
for (Table *table= temporary_tables ; table ; table= table->getNext())
1822
if (table->query_id == getQueryId())
1760
if (table->query_id == query_id)
1824
1762
table->query_id= 0;
1825
1763
table->cursor->ha_reset();
1883
1822
handled either before writing a query log event (inside
1884
1823
binlog_query()) or when preparing a pending event.
1825
mysql_unlock_tables(this, lock);
1890
Note that we need to hold table::Cache::singleton().mutex() while changing the
1829
Note that we need to hold LOCK_open while changing the
1891
1830
open_tables list. Another thread may work on it.
1892
(See: table::Cache::singleton().removeTable(), wait_completed_table())
1831
(See: remove_table_from_cache(), mysql_wait_completed_table())
1893
1832
Closing a MERGE child before the parent would be fatal if the
1894
1833
other thread tries to abort the MERGE lock in between.
1924
1863
if (not lock_tables(tables, counter, &need_reopen))
1927
1865
if (not need_reopen)
1930
1867
close_tables_for_reopen(&tables);
1933
if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
1869
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1870
(fill_derived_tables() &&
1871
mysql_handle_derived(lex, &mysql_derived_filling))))
1877
bool Session::openTables(TableList *tables, uint32_t flags)
1880
bool ret= fill_derived_tables();
1881
assert(ret == false);
1882
if (open_tables_from_list(&tables, &counter, flags) ||
1883
mysql_handle_derived(lex, &mysql_derived_prepare))
1942
1893
might be an issue (lame engines).
1945
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
1896
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1947
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1898
if (plugin::StorageEngine::dropTable(*this, identifier))
1949
1900
if (not best_effort)
1952
identifier.getSQLPath(path);
1953
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1954
path.c_str(), errno);
1902
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1903
identifier.getSQLPath().c_str(), errno);
1963
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
1912
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
1965
drizzled::error_t error;
1968
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
1916
if (plugin::StorageEngine::dropTable(*this, *base, identifier))
1971
identifier.getSQLPath(path);
1972
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1973
path.c_str(), error);
1918
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1919
identifier.getSQLPath().c_str(), errno);
2006
1952
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2010
1955
cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2015
table::Singular *Session::getInstanceTable()
2017
temporary_shares.push_back(new table::Singular()); // This will not go into the tableshare cache, so no key is used.
2019
table::Singular *tmp_share= temporary_shares.back();
2028
Create a reduced Table object with properly set up Field list from a
2029
list of field definitions.
2031
The created table doesn't have a table Cursor associated with
2032
it, has no keys, no group/distinct, no copy_funcs array.
2033
The sole purpose of this Table object is to use the power of Field
2034
class to read/write data to/from table->getInsertRecord(). Then one can store
2035
the record in any container (RB tree, hash, etc).
2036
The table is created in Session mem_root, so are the table's fields.
2037
Consequently, if you don't BLOB fields, you don't need to free it.
2039
@param session connection handle
2040
@param field_list list of column definitions
2043
0 if out of memory, Table object in case of success
2045
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
2047
temporary_shares.push_back(new table::Singular(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2049
table::Singular *tmp_share= temporary_shares.back();
2058
static const std::string NONE= "NONE";
2059
static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
2060
static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
2062
const std::string &type(drizzled::Session::global_read_lock_t type)
2068
case Session::GOT_GLOBAL_READ_LOCK:
2069
return GOT_GLOBAL_READ_LOCK;
2070
case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
2071
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
2075
size_t max_string_length(drizzled::Session::global_read_lock_t)
2077
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT.size();
2080
} /* namespace display */
1959
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
1961
table_message_cache.insert(make_pair(identifier.getPath(), table_message));
1966
bool Session::removeTableMessage(const TableIdentifier &identifier)
1968
TableMessageCache::iterator iter;
1970
iter= table_message_cache.find(identifier.getPath());
1972
if (iter == table_message_cache.end())
1975
table_message_cache.erase(iter);
1980
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
1982
TableMessageCache::iterator iter;
1984
iter= table_message_cache.find(identifier.getPath());
1986
if (iter == table_message_cache.end())
1989
table_message.CopyFrom(((*iter).second));
1994
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
1996
TableMessageCache::iterator iter;
1998
iter= table_message_cache.find(identifier.getPath());
2000
if (iter == table_message_cache.end())
2008
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2010
TableMessageCache::iterator iter;
2012
table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2014
iter= table_message_cache.find(to.getPath());
2016
if (iter == table_message_cache.end())
2021
(*iter).second.set_schema(to.getSchemaName());
2022
(*iter).second.set_name(to.getTableName());
2027
TableShareInstance *Session::getTemporaryShare(TableIdentifier::Type type_arg)
2029
temporary_shares.push_back(new TableShareInstance(type_arg)); // This will not go into the tableshare cache, so no key is used.
2031
TableShareInstance *tmp_share= temporary_shares.back();
2082
2038
} /* namespace drizzled */