24
24
#include "config.h"
26
#include <drizzled/copy_field.h>
27
#include "drizzled/session.h"
28
#include "drizzled/session/cache.h"
29
#include "drizzled/error.h"
30
#include "drizzled/gettext.h"
31
#include "drizzled/query_id.h"
32
#include "drizzled/data_home.h"
33
#include "drizzled/sql_base.h"
34
#include "drizzled/lock.h"
35
#include "drizzled/item/cache.h"
36
#include "drizzled/item/float.h"
37
#include "drizzled/item/return_int.h"
38
#include "drizzled/item/empty_string.h"
39
#include "drizzled/show.h"
40
#include "drizzled/plugin/client.h"
25
#include <drizzled/session.h>
26
#include "drizzled/session_list.h"
28
#include <drizzled/error.h>
29
#include <drizzled/gettext.h>
30
#include <drizzled/query_id.h>
31
#include <drizzled/data_home.h>
32
#include <drizzled/sql_base.h>
33
#include <drizzled/lock.h>
34
#include <drizzled/item/cache.h>
35
#include <drizzled/item/float.h>
36
#include <drizzled/item/return_int.h>
37
#include <drizzled/item/empty_string.h>
38
#include <drizzled/show.h>
39
#include <drizzled/plugin/client.h>
41
40
#include "drizzled/plugin/scheduler.h"
42
41
#include "drizzled/plugin/authentication.h"
43
42
#include "drizzled/plugin/logging.h"
44
43
#include "drizzled/plugin/transactional_storage_engine.h"
45
#include "drizzled/plugin/query_rewrite.h"
46
44
#include "drizzled/probes.h"
47
45
#include "drizzled/table_proto.h"
48
46
#include "drizzled/db.h"
50
48
#include "drizzled/transaction_services.h"
51
49
#include "drizzled/drizzled.h"
53
#include "drizzled/identifier.h"
55
#include <drizzled/refresh_version.h>
57
#include "drizzled/table/singular.h"
51
#include "drizzled/table_share_instance.h"
59
53
#include "plugin/myisam/myisam.h"
60
54
#include "drizzled/internal/iocache.h"
61
55
#include "drizzled/internal/thread_var.h"
62
56
#include "drizzled/plugin/event_observer.h"
64
#include "drizzled/util/functors.h"
66
#include "drizzled/display.h"
68
59
#include <algorithm>
73
#include <boost/filesystem.hpp>
74
#include <boost/checked_delete.hpp>
76
#include "drizzled/util/backtrace.h"
78
62
using namespace std;
80
namespace fs=boost::filesystem;
89
71
char empty_c_string[1]= {0}; /* used for not defined db */
91
73
const char * const Session::DEFAULT_WHERE= "field list";
74
extern pthread_key_t THR_Session;
75
extern pthread_key_t THR_Mem_root;
93
77
bool Key_part_spec::operator==(const Key_part_spec& other) const
95
79
return length == other.length &&
96
80
field_name.length == other.field_name.length &&
97
!my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
81
!strcmp(field_name.str, other.field_name.str);
100
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();
121
128
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
123
130
return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
134
141
return session->options & test_options;
137
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) :
138
155
Open_tables_state(refresh_version),
139
156
mem_root(&main_mem_root),
142
query(new std::string),
143
_schema(new std::string("")),
144
159
client(client_arg),
146
161
scheduler_arg(NULL),
147
162
lock_id(&main_lock_id),
149
security_ctx(identifier::User::make_shared()),
150
_where(Session::DEFAULT_WHERE),
151
dbug_sentry(Session_SENTRY_MAGIC),
153
command(COM_CONNECT),
155
_epoch(boost::gregorian::date(1970,1,1)),
156
_connect_time(boost::posix_time::microsec_clock::universal_time()),
158
164
ha_data(plugin::num_trx_monitored_objects),
161
concurrent_execute_allowed(true),
162
165
arg_of_last_insert_id_function(false),
163
166
first_successful_insert_id_in_prev_stmt(0),
164
167
first_successful_insert_id_in_cur_stmt(0),
165
168
limit_found_rows(0),
166
options(session_startup_options),
169
examined_row_count(0),
173
statement_id_counter(0),
177
_global_read_lock(NONE),
178
count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
180
170
some_tables_deleted(false),
181
171
no_errors(false),
183
173
is_fatal_error(false),
184
174
transaction_rollback_request(false),
185
175
is_fatal_sub_stmt_error(0),
176
derived_tables_processing(false),
186
177
tablespace_op(false),
187
derived_tables_processing(false),
190
180
transaction_message(NULL),
191
181
statement_message(NULL),
192
session_event_observers(NULL),
193
_catalog(catalog_arg),
182
session_event_observers(NULL)
184
memset(process_list_info, 0, PROCESS_LIST_WIDTH);
196
185
client->setSession(this);
201
190
will be re-initialized in init_for_queries().
203
192
memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
194
count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
204
199
cuted_fields= sent_row_count= row_count= 0L;
201
statement_id_counter= 0UL;
205
202
// Must be reset to handle error with Session's created for init of mysqld
206
203
lex->current_select= 0;
204
start_time=(time_t) 0;
206
utime_after_lock= 0L;
207
207
memset(&variables, 0, sizeof(variables));
208
213
scoreboard_index= -1;
214
dbug_sentry=Session_SENTRY_MAGIC;
209
215
cleanup_done= abort_on_warning= no_warnings_for_error= false;
211
217
/* query_cache init */
294
boost_unique_lock_t scopedLock(mysys_var->mutex);
304
pthread_mutex_lock(&mysys_var->mutex);
295
305
if (mysys_var->current_cond)
297
mysys_var->current_mutex->lock();
298
mysys_var->current_cond->notify_all();
299
mysys_var->current_mutex->unlock();
307
pthread_mutex_lock(mysys_var->current_mutex);
308
pthread_cond_broadcast(mysys_var->current_cond);
309
pthread_mutex_unlock(mysys_var->current_mutex);
311
pthread_mutex_unlock(&mysys_var->mutex);
303
314
void Session::pop_internal_handler()
355
364
this->checkSentry();
357
if (client and client->isConnected())
366
if (client->isConnected())
359
assert(security_ctx);
360
368
if (global_system_variables.log_warnings)
362
errmsg_printf(error::WARN, ER(ER_FORCING_CLOSE),
363
internal::my_progname,
365
security_ctx->username().c_str());
369
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
371
(getSecurityContext().getUser().c_str() ?
372
getSecurityContext().getUser().c_str() : ""));
373
disconnect(0, false);
371
376
/* Close connection */
375
boost::checked_delete(client);
379
380
if (cleanup_done == false)
387
388
dbug_sentry= Session_SENTRY_GONE;
389
390
main_mem_root.free_root(MYF(0));
390
currentMemRoot().release();
391
currentSession().release();
391
pthread_setspecific(THR_Session, 0);
393
393
plugin::Logging::postEndDo(this);
394
394
plugin::EventObserver::deregisterSessionEvents(*this);
397
void Session::setClient(plugin::Client *client_arg)
400
client->setSession(this);
403
void Session::awake(Session::killed_state_t state_to_set)
405
if ((state_to_set == Session::KILL_QUERY) and (command == COM_SLEEP))
396
/* Ensure that no one is using Session */
397
LOCK_delete.unlock();
400
void Session::awake(Session::killed_state state_to_set)
408
402
this->checkSentry();
410
setKilled(state_to_set);
411
scheduler->killSession(this);
403
safe_mutex_assert_owner(&LOCK_delete);
405
killed= state_to_set;
413
406
if (state_to_set != Session::KILL_QUERY)
408
scheduler->killSession(this);
415
409
DRIZZLE_CONNECTION_DONE(thread_id);
420
boost_unique_lock_t scopedLock(mysys_var->mutex);
413
pthread_mutex_lock(&mysys_var->mutex);
423
415
This broadcast could be up in the air if the victim thread
424
416
exits the cond in the time between read and broadcast, but that is
425
417
ok since all we want to do is to make the victim thread get out
522
512
if (initGlobals() || authenticate())
528
518
prepareForQueries();
530
while (not client->haveError() && getKilled() != KILL_CONNECTION)
520
while (! client->haveError() && killed != KILL_CONNECTION)
532
if (not executeStatement())
522
if (! executeStatement())
539
bool Session::schedule(Session::shared_ptr &arg)
529
bool Session::schedule()
541
arg->scheduler= plugin::Scheduler::getScheduler();
542
assert(arg->scheduler);
546
long current_connections= connection_count;
548
if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
531
scheduler= plugin::Scheduler::getScheduler();
534
connection_count.increment();
536
if (connection_count > current_global_counters.max_used_connections)
550
current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
538
current_global_counters.max_used_connections= connection_count;
553
541
current_global_counters.connections++;
554
arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
556
session::Cache::singleton().insert(arg);
558
if (unlikely(plugin::EventObserver::connectSession(*arg)))
560
// We should do something about an error...
563
if (plugin::Scheduler::getScheduler()->addSession(arg))
565
DRIZZLE_CONNECTION_START(arg->getSessionId());
542
thread_id= variables.pseudo_thread_id= global_thread_id++;
544
LOCK_thread_count.lock();
545
getSessionList().push_back(this);
546
LOCK_thread_count.unlock();
548
if (scheduler->addSession(this))
550
DRIZZLE_CONNECTION_START(thread_id);
566
551
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
568
arg->setKilled(Session::KILL_CONNECTION);
553
killed= Session::KILL_CONNECTION;
570
arg->status_var.aborted_connects++;
555
status_var.aborted_connects++;
572
557
/* Can't use my_error() since store_globals has not been called. */
573
558
/* TODO replace will better error message */
574
559
snprintf(error_message_buff, sizeof(error_message_buff),
575
560
ER(ER_CANT_CREATE_THREAD), 1);
576
arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
561
client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
586
Is this session viewable by the current user?
588
bool Session::isViewable(identifier::User::const_reference user_arg) const
590
return plugin::Authorization::isAuthorized(user_arg, this, false);
594
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
569
const char* Session::enter_cond(boost::condition_variable &cond, boost::mutex &mutex, const char* msg)
596
571
const char* old_msg = get_proc_info();
597
572
safe_mutex_assert_owner(mutex);
598
mysys_var->current_mutex = &mutex;
599
mysys_var->current_cond = &cond;
573
mysys_var->current_mutex = mutex.native_handle();
574
mysys_var->current_cond = cond.native_handle();
600
575
this->set_proc_info(msg);
609
584
locked (if that would not be the case, you'll get a deadlock if someone
610
585
does a Session::awake() on you).
612
mysys_var->current_mutex->unlock();
613
boost_unique_lock_t scopedLock(mysys_var->mutex);
587
pthread_mutex_unlock(mysys_var->current_mutex);
588
pthread_mutex_lock(&mysys_var->mutex);
614
589
mysys_var->current_mutex = 0;
615
590
mysys_var->current_cond = 0;
616
591
this->set_proc_info(old_msg);
592
pthread_mutex_unlock(&mysys_var->mutex);
619
595
bool Session::authenticate()
621
598
if (client->authenticate())
642
620
/* Change database if necessary */
643
if (not in_db.empty())
621
if (in_db && in_db[0])
645
identifier::Schema identifier(in_db);
646
if (change_db(this, identifier))
623
SchemaIdentifier identifier(in_db);
624
if (mysql_change_db(this, identifier))
648
/* change_db() has pushed the error message. */
626
/* mysql_change_db() has pushed the error message. */
653
password= not passwd_str.empty();
631
password= test(passwd_len); // remember for error messages
655
633
/* Ready to handle queries */
672
650
main_da.reset_diagnostics_area();
674
652
if (client->readCommand(&l_packet, &packet_length) == false)
679
if (getKilled() == KILL_CONNECTION)
655
if (killed == KILL_CONNECTION)
682
658
if (packet_length == 0)
685
l_command= static_cast<enum_server_command>(l_packet[0]);
661
l_command= (enum enum_server_command) (unsigned char) l_packet[0];
687
663
if (command >= COM_END)
688
664
command= COM_END; // Wrong command
690
666
assert(packet_length);
691
return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
667
return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
694
670
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
700
676
in_packet_length--;
702
678
const char *pos= in_packet + in_packet_length; /* Point at end null */
703
while (in_packet_length > 0 && (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
679
while (in_packet_length > 0 &&
680
(pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
706
683
in_packet_length--;
709
std::string *new_query= new std::string(in_packet, in_packet + in_packet_length);
710
// We can not be entirely sure _schema has a value
713
plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
715
query.reset(new_query);
716
_state.reset(new session::State(in_packet, in_packet_length));
686
query.assign(in_packet, in_packet + in_packet_length);
833
804
first_successful_insert_id_in_cur_stmt= 0;
834
805
substitute_null_with_insert_id= true;
837
807
arg_of_last_insert_id_function= false;
839
808
/* Free Items that were created during this execution */
843
_where= Session::DEFAULT_WHERE;
811
where= Session::DEFAULT_WHERE;
845
813
/* Reset the temporary shares we built */
846
for_each(temporary_shares.begin(),
847
temporary_shares.end(),
814
for (std::vector<TableShareInstance *>::iterator iter= temporary_shares.begin();
815
iter != temporary_shares.end(); iter++)
849
819
temporary_shares.clear();
926
896
Handling writing to file
927
897
************************************************************************/
929
void select_to_file::send_error(drizzled::error_t errcode,const char *err)
899
void select_to_file::send_error(uint32_t errcode,const char *err)
931
901
my_message(errcode, err, MYF(0));
934
(void) cache->end_io_cache();
904
(void) end_io_cache(cache);
935
905
(void) internal::my_close(file, MYF(0));
936
(void) internal::my_delete(path.file_string().c_str(), MYF(0)); // Delete file on error
906
(void) internal::my_delete(path, MYF(0)); // Delete file on error
1014
static int create_file(Session *session,
1015
fs::path &target_path,
1016
file_exchange *exchange,
1017
internal::IO_CACHE *cache)
984
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1019
fs::path to_file(exchange->file_name);
1022
if (not to_file.has_root_directory())
987
uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
989
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
990
option|= MY_REPLACE_DIR; // Force use of db directory
993
if (!internal::dirname_length(exchange->file_name))
1024
target_path= fs::system_complete(getDataHomeCatalog());
1025
util::string::const_shared_ptr schema(session->schema());
1026
if (schema and not schema->empty())
1028
int count_elements= 0;
1029
for (fs::path::iterator iter= to_file.begin();
1030
iter != to_file.end();
1031
++iter, ++count_elements)
1034
if (count_elements == 1)
1036
target_path /= *schema;
1039
target_path /= to_file;
995
strcpy(path, data_home_real);
996
if (! session->db.empty())
997
strncat(path, session->db.c_str(), FN_REFLEN-strlen(data_home_real)-1);
998
(void) internal::fn_format(path, exchange->file_name, path, "", option);
1043
target_path = exchange->file_name;
1046
if (not secure_file_priv.string().empty())
1048
if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1050
/* Write only allowed to dir or subdir specified by secure_file_priv */
1051
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1056
if (!access(target_path.file_string().c_str(), F_OK))
1001
(void) internal::fn_format(path, exchange->file_name, data_home_real, "", option);
1003
if (opt_secure_file_priv &&
1004
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1006
/* Write only allowed to dir or subdir specified by secure_file_priv */
1007
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1011
if (!access(path, F_OK))
1058
1013
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1061
1016
/* Create the file world readable */
1062
if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1017
if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1064
1019
(void) fchmod(file, 0666); // Because of umask()
1065
if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1020
if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1067
1022
internal::my_close(file, MYF(0));
1068
internal::my_delete(target_path.file_string().c_str(), MYF(0)); // Delete file on error, it was just created
1023
internal::my_delete(path, MYF(0)); // Delete file on error, it was just created
1295
1246
for (; length > sizeof(space) ; length-=sizeof(space))
1297
1248
if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1300
1251
if (my_b_write(cache,(unsigned char*) space,length))
1304
1255
if (res && enclosed)
1306
1257
if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1307
1258
exchange->enclosed->length()))
1310
1261
if (--items_left)
1312
1263
if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1313
1264
field_term_length))
1317
1268
if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1318
1269
exchange->line_term->length()))
1480
1432
bool select_max_min_finder_subselect::cmp_decimal()
1482
1434
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1483
type::Decimal cval, *cvalue= cache->val_decimal(&cval);
1484
type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
1435
my_decimal cval, *cvalue= cache->val_decimal(&cval);
1436
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1486
1438
return (cache->null_value && !maxmin->null_value) ||
1487
1439
(!cache->null_value && !maxmin->null_value &&
1488
class_decimal_cmp(cvalue, mvalue) > 0) ;
1440
my_decimal_cmp(cvalue, mvalue) > 0) ;
1489
1441
return (maxmin->null_value && !cache->null_value) ||
1490
1442
(!cache->null_value && !maxmin->null_value &&
1491
class_decimal_cmp(cvalue,mvalue) < 0);
1443
my_decimal_cmp(cvalue,mvalue) < 0);
1494
1446
bool select_max_min_finder_subselect::cmp_str()
1530
1482
void Session::end_statement()
1532
1484
/* Cleanup SQL processing state to reuse this statement in next query. */
1534
1486
query_cache_key= ""; // reset the cache key
1535
1487
resetResultsetMessage();
1538
1490
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1541
if (_schema and _schema->empty())
1543
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1546
else if (not _schema)
1548
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1553
*p_db= strmake(_schema->c_str(), _schema->size());
1554
*p_db_length= _schema->size();
1494
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1497
*p_db= strmake(db.c_str(), db.length());
1498
*p_db_length= db.length();
1595
void Session::set_db(const std::string &new_db)
1538
bool Session::set_db(const std::string &new_db)
1597
1540
/* Do not reallocate memory if current chunk is big enough. */
1598
1541
if (new_db.length())
1600
_schema.reset(new std::string(new_db));
1604
_schema.reset(new std::string(""));
1553
Check the killed state of a user thread
1554
@param session user thread
1555
@retval 0 the user thread is active
1556
@retval 1 the user thread has been killed
1558
int session_killed(const Session *session)
1560
return(session->killed);
1564
const struct charset_info_st *session_charset(Session *session)
1566
return(session->charset());
1610
1570
Mark transaction to rollback and mark error as fatal to a sub-statement.
1612
1572
@param session Thread handle
1613
1573
@param all true <=> rollback main transaction.
1615
void Session::markTransactionForRollback(bool all)
1575
void mark_transaction_to_rollback(Session *session, bool all)
1617
is_fatal_sub_stmt_error= true;
1618
transaction_rollback_request= all;
1579
session->is_fatal_sub_stmt_error= true;
1580
session->transaction_rollback_request= all;
1621
void Session::disconnect(enum error_t errcode)
1584
void Session::disconnect(uint32_t errcode, bool should_lock)
1623
1586
/* Allow any plugins to cleanup their session variables */
1624
1587
plugin_sessionvar_cleanup(this);
1626
1589
/* If necessary, log any aborted or unauthorized connections */
1627
if (getKilled() || client->wasAborted())
1590
if (killed || client->wasAborted())
1629
1592
status_var.aborted_threads++;
1632
1595
if (client->wasAborted())
1634
if (not getKilled() && variables.log_warnings > 1)
1597
if (! killed && variables.log_warnings > 1)
1636
errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
1599
SecurityContext *sctx= &security_ctx;
1601
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1638
, (_schema->empty() ? "unconnected" : _schema->c_str())
1639
, security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
1640
, security_ctx->address().c_str()
1603
, (db.empty() ? "unconnected" : db.c_str())
1604
, sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1605
, sctx->getIp().c_str()
1641
1606
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1645
setKilled(Session::KILL_CONNECTION);
1610
/* Close out our connection to the client */
1612
LOCK_thread_count.lock();
1613
killed= Session::KILL_CONNECTION;
1647
1614
if (client->isConnected())
1649
if (errcode != EE_OK)
1651
1618
/*my_error(errcode, ER(errcode));*/
1652
1619
client->sendError(errcode, ER(errcode));
1654
1621
client->close();
1624
(void) LOCK_thread_count.unlock();
1658
1627
void Session::reset_for_next_command()
1736
1705
If this is needed, use close_temporary_table()
1739
void Open_tables_state::nukeTable(Table *table)
1708
void Session::nukeTable(Table *table)
1741
1710
plugin::StorageEngine *table_type= table->getShare()->db_type();
1743
1712
table->free_io_cache();
1744
1713
table->delete_table();
1746
identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1715
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1747
1716
rm_temporary_table(table_type, identifier);
1749
boost::checked_delete(table->getMutableShare());
1718
delete table->getMutableShare();
1751
boost::checked_delete(table);
1720
/* This makes me sad, but we're allocating it via malloc */
1754
1724
/** Clear most status variables. */
1767
1737
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1769
return getVariable(std::string(name.str, name.length), create_if_not_exists);
1772
user_var_entry *Session::getVariable(const std::string &name, bool create_if_not_exists)
1777
UserVars::iterator iter= user_vars.find(name);
1778
if (iter != user_vars.end())
1779
return (*iter).second;
1781
if (not create_if_not_exists)
1784
1739
user_var_entry *entry= NULL;
1785
entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1790
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1792
if (not returnable.second)
1794
boost::checked_delete(entry);
1740
UserVarsRange ppp= user_vars.equal_range(std::string(name.str, name.length));
1742
for (UserVars::iterator iter= ppp.first;
1743
iter != ppp.second; ++iter)
1745
entry= (*iter).second;
1748
if ((entry == NULL) && create_if_not_exists)
1750
entry= new (nothrow) user_var_entry(name.str, query_id);
1755
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(std::string(name.str, name.length), entry));
1757
if (not returnable.second)
1800
void Session::setVariable(const std::string &name, const std::string &value)
1802
user_var_entry *updateable_var= getVariable(name.c_str(), true);
1805
updateable_var->update_hash(false,
1806
(void*)value.c_str(),
1807
static_cast<uint32_t>(value.length()), STRING_RESULT,
1809
DERIVATION_IMPLICIT, false);
1813
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1767
void Session::mark_temp_tables_as_free_for_reuse()
1815
1769
for (Table *table= temporary_tables ; table ; table= table->getNext())
1817
if (table->query_id == getQueryId())
1771
if (table->query_id == query_id)
1819
1773
table->query_id= 0;
1820
1774
table->cursor->ha_reset();
1878
1833
handled either before writing a query log event (inside
1879
1834
binlog_query()) or when preparing a pending event.
1836
mysql_unlock_tables(this, lock);
1885
Note that we need to hold table::Cache::singleton().mutex() while changing the
1840
Note that we need to hold LOCK_open while changing the
1886
1841
open_tables list. Another thread may work on it.
1887
(See: table::Cache::singleton().removeTable(), wait_completed_table())
1842
(See: remove_table_from_cache(), mysql_wait_completed_table())
1888
1843
Closing a MERGE child before the parent would be fatal if the
1889
1844
other thread tries to abort the MERGE lock in between.
1919
1874
if (not lock_tables(tables, counter, &need_reopen))
1922
1876
if (not need_reopen)
1925
1878
close_tables_for_reopen(&tables);
1928
if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
1880
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1881
(fill_derived_tables() &&
1882
mysql_handle_derived(lex, &mysql_derived_filling))))
1888
bool Session::openTables(TableList *tables, uint32_t flags)
1891
bool ret= fill_derived_tables();
1892
assert(ret == false);
1893
if (open_tables_from_list(&tables, &counter, flags) ||
1894
mysql_handle_derived(lex, &mysql_derived_prepare))
1937
1904
might be an issue (lame engines).
1940
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
1907
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1942
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1909
if (plugin::StorageEngine::dropTable(*this, identifier))
1944
1911
if (not best_effort)
1947
identifier.getSQLPath(path);
1948
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1949
path.c_str(), errno);
1913
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1914
identifier.getSQLPath().c_str(), errno);
1958
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
1923
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
1960
drizzled::error_t error;
1963
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
1927
if (plugin::StorageEngine::dropTable(*this, *base, identifier))
1966
identifier.getSQLPath(path);
1967
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1968
path.c_str(), error);
1929
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1930
identifier.getSQLPath().c_str(), errno);
2001
1963
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2005
1966
cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2010
table::Singular *Session::getInstanceTable()
2012
temporary_shares.push_back(new table::Singular()); // This will not go into the tableshare cache, so no key is used.
2014
table::Singular *tmp_share= temporary_shares.back();
2023
Create a reduced Table object with properly set up Field list from a
2024
list of field definitions.
2026
The created table doesn't have a table Cursor associated with
2027
it, has no keys, no group/distinct, no copy_funcs array.
2028
The sole purpose of this Table object is to use the power of Field
2029
class to read/write data to/from table->getInsertRecord(). Then one can store
2030
the record in any container (RB tree, hash, etc).
2031
The table is created in Session mem_root, so are the table's fields.
2032
Consequently, if you don't BLOB fields, you don't need to free it.
2034
@param session connection handle
2035
@param field_list list of column definitions
2038
0 if out of memory, Table object in case of success
2040
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
2042
temporary_shares.push_back(new table::Singular(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2044
table::Singular *tmp_share= temporary_shares.back();
2053
static const std::string NONE= "NONE";
2054
static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
2055
static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
2057
const std::string &type(drizzled::Session::global_read_lock_t type)
2063
case Session::GOT_GLOBAL_READ_LOCK:
2064
return GOT_GLOBAL_READ_LOCK;
2065
case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
2066
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
2070
size_t max_string_length(drizzled::Session::global_read_lock_t)
2072
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT.size();
2075
} /* namespace display */
1970
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
1972
table_message_cache.insert(make_pair(identifier.getPath(), table_message));
1977
bool Session::removeTableMessage(const TableIdentifier &identifier)
1979
TableMessageCache::iterator iter;
1981
iter= table_message_cache.find(identifier.getPath());
1983
if (iter == table_message_cache.end())
1986
table_message_cache.erase(iter);
1991
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
1993
TableMessageCache::iterator iter;
1995
iter= table_message_cache.find(identifier.getPath());
1997
if (iter == table_message_cache.end())
2000
table_message.CopyFrom(((*iter).second));
2005
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
2007
TableMessageCache::iterator iter;
2009
iter= table_message_cache.find(identifier.getPath());
2011
if (iter == table_message_cache.end())
2019
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2021
TableMessageCache::iterator iter;
2023
table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2025
iter= table_message_cache.find(to.getPath());
2027
if (iter == table_message_cache.end())
2032
(*iter).second.set_schema(to.getSchemaName());
2033
(*iter).second.set_name(to.getTableName());
2038
TableShareInstance *Session::getTemporaryShare(TableIdentifier::Type type_arg)
2040
temporary_shares.push_back(new TableShareInstance(type_arg)); // This will not go into the tableshare cache, so no key is used.
2042
TableShareInstance *tmp_share= temporary_shares.back();
2077
2049
} /* namespace drizzled */