24
24
#include "config.h"
25
#include "drizzled/session.h"
26
#include "drizzled/session/cache.h"
25
#include <drizzled/session.h>
26
#include "drizzled/session_list.h"
27
27
#include <sys/stat.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"
28
#include "drizzled/my_error.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>
40
41
#include "drizzled/plugin/scheduler.h"
41
42
#include "drizzled/plugin/authentication.h"
42
#include "drizzled/plugin/logging.h"
43
#include "drizzled/plugin/transactional_storage_engine.h"
44
#include "drizzled/plugin/query_rewrite.h"
45
43
#include "drizzled/probes.h"
46
44
#include "drizzled/table_proto.h"
47
45
#include "drizzled/db.h"
48
46
#include "drizzled/pthread_globals.h"
49
47
#include "drizzled/transaction_services.h"
50
#include "drizzled/drizzled.h"
52
#include "drizzled/table/instance.h"
54
49
#include "plugin/myisam/myisam.h"
55
50
#include "drizzled/internal/iocache.h"
56
#include "drizzled/internal/thread_var.h"
57
#include "drizzled/plugin/event_observer.h"
59
#include "drizzled/util/functors.h"
61
#include "drizzled/display.h"
64
53
#include <algorithm>
66
#include <boost/filesystem.hpp>
68
#include "drizzled/util/backtrace.h"
70
56
using namespace std;
72
namespace fs=boost::filesystem;
62
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool );
63
void free_user_var(user_var_entry *entry);
77
67
The following is used to initialise Table_ident with a internal
81
71
char empty_c_string[1]= {0}; /* used for not defined db */
83
73
const char * const Session::DEFAULT_WHERE= "field list";
74
extern pthread_key_t THR_Session;
75
extern pthread_key_t THR_Mem_root;
76
extern uint32_t max_used_connections;
77
extern atomic<uint32_t> connection_count;
80
/****************************************************************************
82
****************************************************************************/
83
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool )
85
*length= entry->name.length;
86
return (unsigned char*) entry->name.str;
89
void free_user_var(user_var_entry *entry)
85
94
bool Key_part_spec::operator==(const Key_part_spec& other) const
87
96
return length == other.length &&
88
97
field_name.length == other.field_name.length &&
89
!my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
98
!strcmp(field_name.str, other.field_name.str);
92
Open_tables_state::Open_tables_state(uint64_t version_arg) :
101
Open_tables_state::Open_tables_state(uint64_t version_arg)
102
:version(version_arg), backups_available(false)
95
open_tables= temporary_tables= derived_tables= NULL;
96
extra_lock= lock= NULL;
104
reset_open_tables_state();
100
108
The following functions form part of the C plugin API
102
int mysql_tmpfile(const char *prefix)
110
extern "C" int mysql_tmpfile(const char *prefix)
104
112
char filename[FN_REFLEN];
105
int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
113
int fd = internal::create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
107
115
unlink(filename);
124
133
@see Session::set_proc_info
126
void set_session_proc_info(Session *session, const char *info)
136
set_session_proc_info(Session *session, const char *info)
128
138
session->set_proc_info(info);
131
142
const char *get_session_proc_info(Session *session)
133
144
return session->get_proc_info();
136
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
138
return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
141
ResourceContext *Session::getResourceContext(const plugin::MonitoredInTransaction *monitored,
144
return &ha_data[monitored->getId()].resource_context[index];
147
void **Session::getEngineData(const plugin::StorageEngine *engine)
149
return static_cast<void **>(&ha_data[engine->slot].ha_ptr);
152
Ha_trx_info *Session::getEngineInfo(const plugin::StorageEngine *engine,
155
return &ha_data[engine->getSlot()].ha_info[index];
147
159
int64_t session_test_options(const Session *session, int64_t test_options)
149
161
return session->options & test_options;
152
165
int session_sql_command(const Session *session)
154
167
return (int) session->lex->sql_command;
157
enum_tx_isolation session_tx_isolation(const Session *session)
171
int session_tx_isolation(const Session *session)
159
return (enum_tx_isolation)session->variables.tx_isolation;
173
return (int) session->variables.tx_isolation;
162
Session::Session(plugin::Client *client_arg) :
176
Session::Session(plugin::Client *client_arg)
163
178
Open_tables_state(refresh_version),
164
179
mem_root(&main_mem_root),
167
query(new std::string),
168
_schema(new std::string("")),
170
181
client(client_arg),
172
183
scheduler_arg(NULL),
173
184
lock_id(&main_lock_id),
175
ha_data(plugin::num_trx_monitored_objects),
176
concurrent_execute_allowed(true),
177
186
arg_of_last_insert_id_function(false),
178
187
first_successful_insert_id_in_prev_stmt(0),
179
188
first_successful_insert_id_in_cur_stmt(0),
180
189
limit_found_rows(0),
181
_global_read_lock(NONE),
183
191
some_tables_deleted(false),
184
192
no_errors(false),
302
311
return false; // 'false', as per coding style
305
void Session::setAbort(bool arg)
307
mysys_var->abort= arg;
310
void Session::lockOnSys()
316
boost_unique_lock_t scopedLock(mysys_var->mutex);
317
if (mysys_var->current_cond)
319
mysys_var->current_mutex->lock();
320
mysys_var->current_cond->notify_all();
321
mysys_var->current_mutex->unlock();
325
314
void Session::pop_internal_handler()
327
316
assert(m_internal_handler != NULL);
328
317
m_internal_handler= NULL;
331
void Session::get_xid(DRIZZLE_XID *xid)
333
*xid = *(DRIZZLE_XID *) &transaction.xid_state.xid;
320
#if defined(__cplusplus)
324
void *session_alloc(Session *session, unsigned int size)
326
return session->alloc(size);
329
void *session_calloc(Session *session, unsigned int size)
331
return session->calloc(size);
334
char *session_strdup(Session *session, const char *str)
336
return session->strdup(str);
339
char *session_strmake(Session *session, const char *str, unsigned int size)
341
return session->strmake(str, size);
344
void *session_memdup(Session *session, const void* str, unsigned int size)
346
return session->memdup(str, size);
349
void session_get_xid(const Session *session, DRIZZLE_XID *xid)
351
*xid = *(DRIZZLE_XID *) &session->transaction.xid_state.xid;
354
#if defined(__cplusplus)
336
358
/* Do operations that may take a long time */
396
407
plugin::StorageEngine::closeConnection(this);
397
408
plugin_sessionvar_cleanup(this);
399
warn_root.free_root(MYF(0));
410
free_root(&warn_root,MYF(0));
400
411
mysys_var=0; // Safety (shouldn't be needed)
401
412
dbug_sentry= Session_SENTRY_GONE;
403
main_mem_root.free_root(MYF(0));
404
currentMemRoot().release();
405
currentSession().release();
407
plugin::Logging::postEndDo(this);
408
plugin::EventObserver::deregisterSessionEvents(*this);
410
for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
412
delete (*iter).second;
414
life_properties.clear();
417
void Session::setClient(plugin::Client *client_arg)
420
client->setSession(this);
423
void Session::awake(Session::killed_state_t state_to_set)
425
if ((state_to_set == Session::KILL_QUERY) and (command == COM_SLEEP))
430
setKilled(state_to_set);
431
scheduler->killSession(this);
414
free_root(&main_mem_root, MYF(0));
415
pthread_setspecific(THR_Session, 0);
418
/* Ensure that no one is using Session */
419
pthread_mutex_unlock(&LOCK_delete);
420
pthread_mutex_destroy(&LOCK_delete);
424
Add all status variables to another status variable array
428
to_var add to this array
429
from_var from this array
432
This function assumes that all variables are long/ulong.
433
If this assumption will change, then we have to explictely add
434
the other variables after the while loop
436
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
438
ulong *end= (ulong*) ((unsigned char*) to_var +
439
offsetof(STATUS_VAR, last_system_status_var) +
441
ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
448
Add the difference between two status variable arrays to another one.
452
to_var add to this array
453
from_var from this array
454
dec_var minus this array
457
This function assumes that all variables are long/ulong.
459
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
462
ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(STATUS_VAR,
463
last_system_status_var) +
465
ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
468
*(to++)+= *(from++) - *(dec++);
471
void Session::awake(Session::killed_state state_to_set)
473
Session_CHECK_SENTRY(this);
474
safe_mutex_assert_owner(&LOCK_delete);
476
killed= state_to_set;
433
477
if (state_to_set != Session::KILL_QUERY)
479
scheduler->killSession(this);
435
480
DRIZZLE_CONNECTION_DONE(thread_id);
440
boost_unique_lock_t scopedLock(mysys_var->mutex);
484
pthread_mutex_lock(&mysys_var->mutex);
443
486
This broadcast could be up in the air if the victim thread
444
487
exits the cond in the time between read and broadcast, but that is
445
488
ok since all we want to do is to make the victim thread get out
548
588
prepareForQueries();
550
while (not client->haveError() && getKilled() != KILL_CONNECTION)
590
while (! client->haveError() && killed != KILL_CONNECTION)
552
if (not executeStatement())
592
if (! executeStatement())
556
596
disconnect(0, true);
559
bool Session::schedule(Session::shared_ptr &arg)
599
bool Session::schedule()
561
arg->scheduler= plugin::Scheduler::getScheduler();
562
assert(arg->scheduler);
601
scheduler= plugin::Scheduler::getScheduler();
564
604
connection_count.increment();
566
if (connection_count > current_global_counters.max_used_connections)
568
current_global_counters.max_used_connections= connection_count;
571
current_global_counters.connections++;
572
arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
574
session::Cache::singleton().insert(arg);
576
if (unlikely(plugin::EventObserver::connectSession(*arg)))
578
// We should do something about an error...
581
if (plugin::Scheduler::getScheduler()->addSession(arg))
583
DRIZZLE_CONNECTION_START(arg->getSessionId());
606
if (connection_count > max_used_connections)
607
max_used_connections= connection_count;
609
thread_id= variables.pseudo_thread_id= global_thread_id++;
611
pthread_mutex_lock(&LOCK_thread_count);
612
getSessionList().push_back(this);
613
pthread_mutex_unlock(&LOCK_thread_count);
615
if (scheduler->addSession(this))
617
DRIZZLE_CONNECTION_START(thread_id);
584
618
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
586
arg->setKilled(Session::KILL_CONNECTION);
620
killed= Session::KILL_CONNECTION;
588
arg->status_var.aborted_connects++;
622
statistic_increment(aborted_connects, &LOCK_status);
590
624
/* Can't use my_error() since store_globals has not been called. */
591
625
/* TODO replace will better error message */
592
626
snprintf(error_message_buff, sizeof(error_message_buff),
593
627
ER(ER_CANT_CREATE_THREAD), 1);
594
arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
628
client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
629
653
locked (if that would not be the case, you'll get a deadlock if someone
630
654
does a Session::awake() on you).
632
mysys_var->current_mutex->unlock();
633
boost_unique_lock_t scopedLock(mysys_var->mutex);
656
pthread_mutex_unlock(mysys_var->current_mutex);
657
pthread_mutex_lock(&mysys_var->mutex);
634
658
mysys_var->current_mutex = 0;
635
659
mysys_var->current_cond = 0;
636
660
this->set_proc_info(old_msg);
661
pthread_mutex_unlock(&mysys_var->mutex);
639
664
bool Session::authenticate()
642
667
if (client->authenticate())
645
status_var.aborted_connects++;
670
statistic_increment(aborted_connects, &LOCK_status);
650
bool Session::checkUser(const std::string &passwd_str,
651
const std::string &in_db)
674
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
653
bool is_authenticated=
654
plugin::Authentication::isAuthenticated(getSecurityContext(),
676
LEX_STRING db_str= { (char *) in_db, in_db ? strlen(in_db) : 0 };
677
bool is_authenticated;
679
if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
681
my_error(ER_HANDSHAKE_ERROR, MYF(0), security_ctx.ip.c_str());
685
is_authenticated= plugin::Authentication::isAuthenticated(this, passwd);
657
687
if (is_authenticated != true)
659
status_var.access_denied++;
660
/* isAuthenticated has pushed the error message */
689
my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
690
security_ctx.user.c_str(),
691
security_ctx.ip.c_str(),
692
passwd_len ? ER(ER_YES) : ER(ER_NO));
697
security_ctx.skip_grants();
664
699
/* Change database if necessary */
665
if (not in_db.empty())
700
if (in_db && in_db[0])
667
SchemaIdentifier identifier(in_db);
668
if (mysql_change_db(this, identifier))
702
if (mysql_change_db(this, &db_str, false))
670
704
/* mysql_change_db() has pushed the error message. */
675
password= not passwd_str.empty();
709
password= test(passwd_len); // remember for error messages
677
711
/* Ready to handle queries */
1038
static int create_file(Session *session,
1039
fs::path &target_path,
1040
file_exchange *exchange,
1041
internal::IO_CACHE *cache)
1059
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1043
fs::path to_file(exchange->file_name);
1046
if (not to_file.has_root_directory())
1062
uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1064
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
1065
option|= MY_REPLACE_DIR; // Force use of db directory
1068
if (!internal::dirname_length(exchange->file_name))
1048
target_path= fs::system_complete(getDataHomeCatalog());
1049
util::string::const_shared_ptr schema(session->schema());
1050
if (schema and not schema->empty())
1052
int count_elements= 0;
1053
for (fs::path::iterator iter= to_file.begin();
1054
iter != to_file.end();
1055
++iter, ++count_elements)
1058
if (count_elements == 1)
1060
target_path /= *schema;
1063
target_path /= to_file;
1070
strcpy(path, drizzle_real_data_home);
1071
if (! session->db.empty())
1072
strncat(path, session->db.c_str(), FN_REFLEN-strlen(drizzle_real_data_home)-1);
1073
(void) internal::fn_format(path, exchange->file_name, path, "", option);
1067
target_path = exchange->file_name;
1070
if (not secure_file_priv.string().empty())
1072
if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1074
/* Write only allowed to dir or subdir specified by secure_file_priv */
1075
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1080
if (!access(target_path.file_string().c_str(), F_OK))
1076
(void) internal::fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1078
if (opt_secure_file_priv &&
1079
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1081
/* Write only allowed to dir or subdir specified by secure_file_priv */
1082
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1086
if (!access(path, F_OK))
1082
1088
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1085
1091
/* Create the file world readable */
1086
if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1092
if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1088
1094
(void) fchmod(file, 0666); // Because of umask()
1089
if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1095
if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1091
1097
internal::my_close(file, MYF(0));
1092
internal::my_delete(target_path.file_string().c_str(), MYF(0)); // Delete file on error, it was just created
1098
internal::my_delete(path, MYF(0)); // Delete file on error, it was just created
1615
1615
memset(&status_var, 0, sizeof(status_var));
1619
void Session::set_db(const std::string &new_db)
1618
void Security_context::skip_grants()
1620
/* privileges for the user are unknown everything is allowed */
1624
/****************************************************************************
1625
Handling of open and locked tables states.
1627
This is used when we want to open/lock (and then close) some tables when
1628
we already have a set of tables open and locked. We use these methods for
1629
access to mysql.proc table to find definitions of stored routines.
1630
****************************************************************************/
1632
void Session::reset_n_backup_open_tables_state(Open_tables_state *backup)
1634
backup->set_open_tables_state(this);
1635
reset_open_tables_state();
1636
backups_available= false;
1640
void Session::restore_backup_open_tables_state(Open_tables_state *backup)
1643
Before we will throw away current open tables state we want
1644
to be sure that it was properly cleaned up.
1646
assert(open_tables == 0 && temporary_tables == 0 &&
1647
derived_tables == 0 &&
1649
set_open_tables_state(backup);
1652
bool Session::set_db(const char *new_db, size_t length)
1621
1654
/* Do not reallocate memory if current chunk is big enough. */
1622
if (new_db.length())
1624
_schema.reset(new std::string(new_db));
1628
_schema.reset(new std::string(""));
1667
Check the killed state of a user thread
1668
@param session user thread
1669
@retval 0 the user thread is active
1670
@retval 1 the user thread has been killed
1672
extern "C" int session_killed(const Session *session)
1674
return(session->killed);
1678
Return the session id of a user session
1679
@param pointer to Session object
1680
@return session's id
1682
extern "C" unsigned long session_get_thread_id(const Session *session)
1684
return (unsigned long) session->getSessionId();
1688
const struct charset_info_st *session_charset(Session *session)
1690
return(session->charset());
1693
char **session_query(Session *session)
1695
return(&session->query);
1698
int session_non_transactional_update(const Session *session)
1700
return(session->transaction.all.modified_non_trans_table);
1703
void session_mark_transaction_to_rollback(Session *session, bool all)
1705
mark_transaction_to_rollback(session, all);
1634
1709
Mark transaction to rollback and mark error as fatal to a sub-statement.
1651
1726
plugin_sessionvar_cleanup(this);
1653
1728
/* If necessary, log any aborted or unauthorized connections */
1654
if (getKilled() || client->wasAborted())
1656
status_var.aborted_threads++;
1729
if (killed || client->wasAborted())
1730
statistic_increment(aborted_threads, &LOCK_status);
1659
1732
if (client->wasAborted())
1661
if (not getKilled() && variables.log_warnings > 1)
1734
if (! killed && variables.log_warnings > 1)
1663
SecurityContext *sctx= &security_ctx;
1736
Security_context *sctx= &security_ctx;
1665
1738
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1667
, (_schema->empty() ? "unconnected" : _schema->c_str())
1668
, sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1669
, sctx->getIp().c_str()
1740
, (db.empty() ? "unconnected" : db.c_str())
1741
, sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated"
1670
1743
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1674
1747
/* Close out our connection to the client */
1675
1748
if (should_lock)
1676
session::Cache::singleton().mutex().lock();
1678
setKilled(Session::KILL_CONNECTION);
1749
(void) pthread_mutex_lock(&LOCK_thread_count);
1750
killed= Session::KILL_CONNECTION;
1680
1751
if (client->isConnected())
1757
1832
passing non-zero value to end_slave via rli->save_temporary_tables
1758
1833
when no temp tables opened, see an invariant below.
1760
temporary_tables= table->getNext();
1835
temporary_tables= table->next;
1761
1836
if (temporary_tables)
1763
table->getNext()->setPrev(NULL);
1837
table->next->prev= NULL;
1839
close_temporary(table);
1770
Close and drop a temporary table
1843
Close and delete a temporary table
1773
1846
This dosn't unlink table from session->temporary
1774
1847
If this is needed, use close_temporary_table()
1777
void Open_tables_state::nukeTable(Table *table)
1850
void Session::close_temporary(Table *table)
1779
plugin::StorageEngine *table_type= table->getShare()->db_type();
1852
plugin::StorageEngine *table_type= table->s->db_type();
1781
1854
table->free_io_cache();
1782
table->delete_table();
1784
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1785
rm_temporary_table(table_type, identifier);
1787
delete table->getMutableShare();
1855
table->closefrm(false);
1857
rm_temporary_table(table_type, table->s->path.str);
1859
table->s->free_table_share();
1789
1861
/* This makes me sad, but we're allocating it via malloc */
1793
1865
/** Clear most status variables. */
1794
1866
extern time_t flush_status_time;
1867
extern uint32_t max_used_connections;
1796
1869
void Session::refresh_status()
1871
pthread_mutex_lock(&LOCK_status);
1873
/* Add thread's status variabes to global status */
1874
add_to_status(&global_status_var, &status_var);
1798
1876
/* Reset thread's status variables */
1799
1877
memset(&status_var, 0, sizeof(status_var));
1879
/* Reset some global variables */
1880
reset_status_vars();
1882
/* Reset the counters of all key caches (default and named). */
1883
reset_key_cache_counters();
1801
1884
flush_status_time= time((time_t*) 0);
1802
current_global_counters.max_used_connections= 1; /* We set it to one, because we know we exist */
1803
current_global_counters.connections= 0;
1885
max_used_connections= 1; /* We set it to one, because we know we exist */
1886
pthread_mutex_unlock(&LOCK_status);
1806
1889
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1808
return getVariable(std::string(name.str, name.length), create_if_not_exists);
1811
user_var_entry *Session::getVariable(const std::string &name, bool create_if_not_exists)
1813
UserVarsRange ppp= user_vars.equal_range(name);
1815
for (UserVars::iterator iter= ppp.first;
1816
iter != ppp.second; ++iter)
1818
return (*iter).second;
1821
if (not create_if_not_exists)
1824
1891
user_var_entry *entry= NULL;
1825
entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1830
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1832
if (not returnable.second)
1893
entry= (user_var_entry*) hash_search(&user_vars, (unsigned char*) name.str, name.length);
1895
if ((entry == NULL) && create_if_not_exists)
1897
if (!hash_inited(&user_vars))
1899
entry= new (nothrow) user_var_entry(name.str, query_id);
1904
if (my_hash_insert(&user_vars, (unsigned char*) entry))
1907
free((char*) entry);
1840
void Session::setVariable(const std::string &name, const std::string &value)
1842
user_var_entry *updateable_var= getVariable(name.c_str(), true);
1844
updateable_var->update_hash(false,
1845
(void*)value.c_str(),
1846
static_cast<uint32_t>(value.length()), STRING_RESULT,
1848
DERIVATION_IMPLICIT, false);
1851
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1853
for (Table *table= temporary_tables ; table ; table= table->getNext())
1916
void Session::mark_temp_tables_as_free_for_reuse()
1918
for (Table *table= temporary_tables ; table ; table= table->next)
1855
if (table->query_id == getQueryId())
1920
if (table->query_id == query_id)
1857
1922
table->query_id= 0;
1858
1923
table->cursor->ha_reset();
1954
2046
if (open_tables_from_list(&tables, &counter))
1957
if (not lock_tables(tables, counter, &need_reopen))
2049
if (!lock_tables(tables, counter, &need_reopen))
1959
if (not need_reopen)
1961
2053
close_tables_for_reopen(&tables);
1963
2055
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
2056
(fill_derived_tables() &&
1965
2057
mysql_handle_derived(lex, &mysql_derived_filling))))
1972
@note "best_effort" is used in cases were if a failure occurred on this
1973
operation it would not be surprising because we are only removing because there
1974
might be an issue (lame engines).
1977
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
1979
if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1981
if (not best_effort)
1984
identifier.getSQLPath(path);
1985
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1986
path.c_str(), errno);
1995
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
1999
if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
2002
identifier.getSQLPath(path);
2003
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2004
path.c_str(), errno);
2013
@note this will be removed, I am looking through Hudson to see if it is finding
2014
any tables that are missed during cleanup.
2016
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
2020
if (not temporary_tables)
2023
cerr << "Begin Run: " << foo << "\n";
2024
for (table= temporary_tables; table; table= table->getNext())
2026
bool have_proto= false;
2028
message::Table *proto= table->getShare()->getTableProto();
2029
if (table->getShare()->getTableProto())
2032
const char *answer= have_proto ? "true" : "false";
2036
cerr << "\tTable Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2037
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2041
cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2046
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2048
table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2053
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
2055
TableMessageCache::iterator iter;
2057
iter= table_message_cache.find(identifier.getPath());
2059
if (iter == table_message_cache.end())
2062
table_message_cache.erase(iter);
2067
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2069
TableMessageCache::iterator iter;
2071
iter= table_message_cache.find(identifier.getPath());
2073
if (iter == table_message_cache.end())
2076
table_message.CopyFrom(((*iter).second));
2081
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
2083
TableMessageCache::iterator iter;
2085
iter= table_message_cache.find(identifier.getPath());
2087
if (iter == table_message_cache.end())
2095
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2097
TableMessageCache::iterator iter;
2099
table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2101
iter= table_message_cache.find(to.getPath());
2103
if (iter == table_message_cache.end())
2108
(*iter).second.set_schema(to.getSchemaName());
2109
(*iter).second.set_name(to.getTableName());
2114
table::Instance *Session::getInstanceTable()
2116
temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
2118
table::Instance *tmp_share= temporary_shares.back();
2127
Create a reduced Table object with properly set up Field list from a
2128
list of field definitions.
2130
The created table doesn't have a table Cursor associated with
2131
it, has no keys, no group/distinct, no copy_funcs array.
2132
The sole purpose of this Table object is to use the power of Field
2133
class to read/write data to/from table->getInsertRecord(). Then one can store
2134
the record in any container (RB tree, hash, etc).
2135
The table is created in Session mem_root, so are the table's fields.
2136
Consequently, if you don't BLOB fields, you don't need to free it.
2138
@param session connection handle
2139
@param field_list list of column definitions
2142
0 if out of memory, Table object in case of success
2144
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2146
temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2148
table::Instance *tmp_share= temporary_shares.back();
2157
static const std::string NONE= "NONE";
2158
static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
2159
static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
2161
const std::string &type(drizzled::Session::global_read_lock_t type)
2167
case Session::GOT_GLOBAL_READ_LOCK:
2168
return GOT_GLOBAL_READ_LOCK;
2169
case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
2170
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
2174
size_t max_string_length(drizzled::Session::global_read_lock_t)
2176
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT.size();
2179
} /* namespace display */
2063
bool Session::openTables(TableList *tables, uint32_t flags)
2066
bool ret= fill_derived_tables();
2067
assert(ret == false);
2068
if (open_tables_from_list(&tables, &counter, flags) ||
2069
mysql_handle_derived(lex, &mysql_derived_prepare))
2074
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
2080
if (plugin::StorageEngine::deleteDefinitionFromPath(identifier))
2083
if (base->doDropTable(*this, identifier.getPath()))
2086
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2087
identifier.getPath(), errno);
2092
bool Session::rm_temporary_table(plugin::StorageEngine *base, const char *path)
2098
if (delete_table_proto_file(path))
2101
if (base->doDropTable(*this, path))
2104
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2181
2110
} /* namespace drizzled */