21
21
* @file Implementation of the Session class and API
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"
41
#include "drizzled/plugin/scheduler.h"
42
#include "drizzled/plugin/authentication.h"
43
#include "drizzled/plugin/logging.h"
44
#include "drizzled/plugin/transactional_storage_engine.h"
45
#include "drizzled/plugin/query_rewrite.h"
46
#include "drizzled/probes.h"
47
#include "drizzled/table_proto.h"
48
#include "drizzled/db.h"
49
#include "drizzled/pthread_globals.h"
50
#include "drizzled/transaction_services.h"
51
#include "drizzled/drizzled.h"
53
#include "drizzled/identifier.h"
55
#include <drizzled/refresh_version.h>
57
#include "drizzled/table/singular.h"
59
#include "plugin/myisam/myisam.h"
60
#include "drizzled/internal/iocache.h"
61
#include "drizzled/internal/thread_var.h"
62
#include "drizzled/plugin/event_observer.h"
64
#include "drizzled/util/functors.h"
66
#include "drizzled/display.h"
24
#include <drizzled/server_includes.h>
25
#include <drizzled/session.h>
27
#include <mysys/mysys_err.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/scheduling.h>
68
41
#include <algorithm>
73
#include <boost/filesystem.hpp>
74
#include <boost/checked_delete.hpp>
76
#include "drizzled/util/backtrace.h"
78
43
using namespace std;
44
using namespace drizzled;
80
namespace fs=boost::filesystem;
48
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool );
49
void free_user_var(user_var_entry *entry);
85
53
The following is used to initialise Table_ident with a internal
89
57
char empty_c_string[1]= {0}; /* used for not defined db */
91
59
const char * const Session::DEFAULT_WHERE= "field list";
60
extern pthread_key_t THR_Session;
61
extern pthread_key_t THR_Mem_root;
62
extern uint32_t max_used_connections;
63
extern drizzled::atomic<uint32_t> connection_count;
65
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
67
template class List<Key>;
68
template class List_iterator<Key>;
69
template class List<Key_part_spec>;
70
template class List_iterator<Key_part_spec>;
71
template class List<Alter_drop>;
72
template class List_iterator<Alter_drop>;
73
template class List<Alter_column>;
74
template class List_iterator<Alter_column>;
77
/****************************************************************************
79
****************************************************************************/
80
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool )
82
*length= entry->name.length;
83
return (unsigned char*) entry->name.str;
86
void free_user_var(user_var_entry *entry)
93
91
bool Key_part_spec::operator==(const Key_part_spec& other) const
95
93
return length == other.length &&
96
94
field_name.length == other.field_name.length &&
97
!my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
95
!strcmp(field_name.str, other.field_name.str);
100
Open_tables_state::Open_tables_state(uint64_t version_arg) :
98
Open_tables_state::Open_tables_state(ulong version_arg)
99
:version(version_arg), backups_available(false)
103
open_tables= temporary_tables= derived_tables= NULL;
104
extra_lock= lock= NULL;
101
reset_open_tables_state();
108
105
The following functions form part of the C plugin API
110
int tmpfile(const char *prefix)
107
extern "C" int mysql_tmpfile(const char *prefix)
112
109
char filename[FN_REFLEN];
113
int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
110
File fd = create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
115
112
unlink(filename);
121
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
123
return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
126
ResourceContext *Session::getResourceContext(const plugin::MonitoredInTransaction *monitored,
129
return &ha_data[monitored->getId()].resource_context[index];
119
int session_tablespace_op(const Session *session)
121
return test(session->tablespace_op);
125
Set the process info field of the Session structure.
127
This function is used by plug-ins. Internally, the
128
Session::set_proc_info() function should be used.
130
@see Session::set_proc_info
133
set_session_proc_info(Session *session, const char *info)
135
session->set_proc_info(info);
139
const char *get_session_proc_info(Session *session)
141
return session->get_proc_info();
145
void **session_ha_data(const Session *session, const struct StorageEngine *engine)
147
return (void **) &session->ha_data[engine->slot].ha_ptr;
132
151
int64_t session_test_options(const Session *session, int64_t test_options)
134
153
return session->options & test_options;
137
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
157
int session_sql_command(const Session *session)
159
return (int) session->lex->sql_command;
163
int session_tx_isolation(const Session *session)
165
return (int) session->variables.tx_isolation;
169
void session_inc_row_count(Session *session)
171
session->row_count++;
174
Session::Session(plugin::Protocol *protocol_arg)
138
176
Open_tables_state(refresh_version),
139
177
mem_root(&main_mem_root),
142
query(new std::string),
143
_schema(new std::string("")),
146
181
scheduler_arg(NULL),
147
182
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
ha_data(plugin::num_trx_monitored_objects),
161
concurrent_execute_allowed(true),
162
184
arg_of_last_insert_id_function(false),
163
185
first_successful_insert_id_in_prev_stmt(0),
164
186
first_successful_insert_id_in_cur_stmt(0),
165
187
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
189
some_tables_deleted(false),
181
190
no_errors(false),
183
192
is_fatal_error(false),
184
193
transaction_rollback_request(false),
185
194
is_fatal_sub_stmt_error(0),
195
derived_tables_processing(false),
186
196
tablespace_op(false),
187
derived_tables_processing(false),
190
transaction_message(NULL),
191
statement_message(NULL),
192
session_event_observers(NULL),
193
_catalog(catalog_arg),
196
client->setSession(this);
200
memset(process_list_info, 0, PROCESS_LIST_WIDTH);
199
203
Pass nominal parameters to init_alloc_root only to ensure that
200
204
the destructor works OK in case of an error. The main_mem_root
201
205
will be re-initialized in init_for_queries().
203
memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
207
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
209
count_cuted_fields= CHECK_FIELD_IGNORE;
204
214
cuted_fields= sent_row_count= row_count= 0L;
216
statement_id_counter= 0UL;
205
217
// Must be reset to handle error with Session's created for init of mysqld
206
218
lex->current_select= 0;
219
start_time=(time_t) 0;
221
utime_after_lock= 0L;
207
222
memset(&variables, 0, sizeof(variables));
208
scoreboard_index= -1;
209
cleanup_done= abort_on_warning= no_warnings_for_error= false;
211
/* query_cache init */
227
memset(ha_data, 0, sizeof(ha_data));
230
dbug_sentry=Session_SENTRY_MAGIC;
231
cleanup_done= abort_on_warning= no_warnings_for_error= false;
232
peer_port= 0; // For SHOW PROCESSLIST
234
pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
215
236
/* Variables with default values */
216
237
proc_info="login";
238
where= Session::DEFAULT_WHERE;
239
command= COM_CONNECT;
218
241
plugin_sessionvar_init(this);
224
247
variables.pseudo_thread_id= thread_id;
225
248
server_status= SERVER_STATUS_AUTOCOMMIT;
249
options= session_startup_options;
227
251
if (variables.max_join_size == HA_POS_ERROR)
228
252
options |= OPTION_BIG_SELECTS;
230
254
options &= ~OPTION_BIG_SELECTS;
256
transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= false;
232
257
open_options=ha_open_options;
233
258
update_lock_default= TL_WRITE;
234
259
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
235
260
warn_list.empty();
236
261
memset(warn_count, 0, sizeof(warn_count));
237
263
memset(&status_var, 0, sizeof(status_var));
239
265
/* Initialize sub structures */
240
memory::init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
266
init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
267
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
268
(hash_get_key) get_var_key,
269
(hash_free_key) free_user_var, 0);
271
protocol= protocol_arg;
272
protocol->setSession(this);
242
274
substitute_null_with_insert_id = false;
243
lock_info.init(); /* safety: will be reset after start */
275
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
244
276
thr_lock_owner_init(&main_lock_id, &lock_info);
246
278
m_internal_handler= NULL;
248
plugin::EventObserver::registerSessionEvents(*this);
251
281
void Session::free_items()
254
/* This works because items are allocated with memory::sql_alloc() */
284
/* This works because items are allocated with sql_alloc() */
255
285
for (; free_list; free_list= next)
257
287
next= free_list->next;
280
310
return false; // 'false', as per coding style
283
void Session::setAbort(bool arg)
285
mysys_var->abort= arg;
288
void Session::lockOnSys()
294
boost_unique_lock_t scopedLock(mysys_var->mutex);
295
if (mysys_var->current_cond)
297
mysys_var->current_mutex->lock();
298
mysys_var->current_cond->notify_all();
299
mysys_var->current_mutex->unlock();
303
313
void Session::pop_internal_handler()
305
315
assert(m_internal_handler != NULL);
306
316
m_internal_handler= NULL;
309
void Session::get_xid(DRIZZLE_XID *xid)
311
*xid = *(DRIZZLE_XID *) &transaction.xid_state.xid;
319
#if defined(__cplusplus)
323
void *session_alloc(Session *session, unsigned int size)
325
return session->alloc(size);
328
void *session_calloc(Session *session, unsigned int size)
330
return session->calloc(size);
333
char *session_strdup(Session *session, const char *str)
335
return session->strdup(str);
338
char *session_strmake(Session *session, const char *str, unsigned int size)
340
return session->strmake(str, size);
343
void *session_memdup(Session *session, const void* str, unsigned int size)
345
return session->memdup(str, size);
348
void session_get_xid(const Session *session, DRIZZLE_XID *xid)
350
*xid = *(DRIZZLE_XID *) &session->transaction.xid_state.xid;
353
#if defined(__cplusplus)
314
357
/* Do operations that may take a long time */
328
TransactionServices &transaction_services= TransactionServices::singleton();
329
transaction_services.rollbackTransaction(*this, true);
330
372
xid_cache_delete(&transaction.xid_state);
333
for (UserVars::iterator iter= user_vars.begin();
334
iter != user_vars.end();
337
user_var_entry *entry= (*iter).second;
338
boost::checked_delete(entry);
374
hash_free(&user_vars);
343
375
close_temporary_tables();
345
377
if (global_read_lock)
347
unlockGlobalReadLock();
378
unlock_global_read_lock(this);
350
380
cleanup_done= true;
353
383
Session::~Session()
385
Session_CHECK_SENTRY(this);
386
add_to_status(&global_status_var, &status_var);
357
if (client and client->isConnected())
388
if (protocol->isConnected())
359
assert(security_ctx);
360
390
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());
391
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),my_progname,
393
(security_ctx.user.c_str() ?
394
security_ctx.user.c_str() : ""));
395
disconnect(0, false);
371
398
/* Close connection */
375
boost::checked_delete(client);
379
402
if (cleanup_done == false)
382
plugin::StorageEngine::closeConnection(this);
405
ha_close_connection(this);
383
406
plugin_sessionvar_cleanup(this);
385
warn_root.free_root(MYF(0));
413
free_root(&warn_root,MYF(0));
414
free_root(&transaction.mem_root,MYF(0));
386
415
mysys_var=0; // Safety (shouldn't be needed)
387
416
dbug_sentry= Session_SENTRY_GONE;
389
main_mem_root.free_root(MYF(0));
390
currentMemRoot().release();
391
currentSession().release();
393
plugin::Logging::postEndDo(this);
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))
410
setKilled(state_to_set);
411
scheduler->killSession(this);
418
free_root(&main_mem_root, MYF(0));
419
pthread_setspecific(THR_Session, 0);
422
/* Ensure that no one is using Session */
423
pthread_mutex_unlock(&LOCK_delete);
424
pthread_mutex_destroy(&LOCK_delete);
428
Add all status variables to another status variable array
432
to_var add to this array
433
from_var from this array
436
This function assumes that all variables are long/ulong.
437
If this assumption will change, then we have to explictely add
438
the other variables after the while loop
440
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
442
ulong *end= (ulong*) ((unsigned char*) to_var +
443
offsetof(STATUS_VAR, last_system_status_var) +
445
ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
452
Add the difference between two status variable arrays to another one.
456
to_var add to this array
457
from_var from this array
458
dec_var minus this array
461
This function assumes that all variables are long/ulong.
463
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
466
ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(STATUS_VAR,
467
last_system_status_var) +
469
ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
472
*(to++)+= *(from++) - *(dec++);
475
void Session::awake(Session::killed_state state_to_set)
477
Session_CHECK_SENTRY(this);
478
safe_mutex_assert_owner(&LOCK_delete);
480
killed= state_to_set;
413
481
if (state_to_set != Session::KILL_QUERY)
415
DRIZZLE_CONNECTION_DONE(thread_id);
483
scheduler->killSession(this);
420
boost_unique_lock_t scopedLock(mysys_var->mutex);
487
pthread_mutex_lock(&mysys_var->mutex);
423
489
This broadcast could be up in the air if the victim thread
424
490
exits the cond in the time between read and broadcast, but that is
425
491
ok since all we want to do is to make the victim thread get out
497
562
set_proc_info(NULL);
498
563
command= COM_SLEEP;
565
ha_enable_transaction(this,true);
501
mem_root->reset_root_defaults(variables.query_alloc_block_size,
502
variables.query_prealloc_size);
567
reset_root_defaults(mem_root, variables.query_alloc_block_size,
568
variables.query_prealloc_size);
569
reset_root_defaults(&transaction.mem_root,
570
variables.trans_alloc_block_size,
571
variables.trans_prealloc_size);
503
572
transaction.xid_state.xid.null();
504
573
transaction.xid_state.in_session=1;
509
576
bool Session::initGlobals()
511
578
if (storeGlobals())
513
disconnect(ER_OUT_OF_RESOURCES);
514
status_var.aborted_connects++;
580
disconnect(ER_OUT_OF_RESOURCES, true);
581
statistic_increment(aborted_connects, &LOCK_status);
522
589
if (initGlobals() || authenticate())
528
595
prepareForQueries();
530
while (not client->haveError() && getKilled() != KILL_CONNECTION)
597
while (! protocol->haveError() && killed != KILL_CONNECTION)
532
if (not executeStatement())
599
if (! executeStatement())
539
bool Session::schedule(Session::shared_ptr &arg)
606
bool Session::schedule()
541
arg->scheduler= plugin::Scheduler::getScheduler();
542
assert(arg->scheduler);
608
scheduler= get_thread_scheduler();
544
610
++connection_count;
546
long current_connections= connection_count;
548
if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
550
current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
553
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());
612
if (connection_count > max_used_connections)
613
max_used_connections= connection_count;
615
thread_id= variables.pseudo_thread_id= global_thread_id++;
617
pthread_mutex_lock(&LOCK_thread_count);
618
session_list.push_back(this);
619
pthread_mutex_unlock(&LOCK_thread_count);
621
if (scheduler->addSession(this))
566
623
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
568
arg->setKilled(Session::KILL_CONNECTION);
625
killed= Session::KILL_CONNECTION;
570
arg->status_var.aborted_connects++;
627
statistic_increment(aborted_connects, &LOCK_status);
572
629
/* Can't use my_error() since store_globals has not been called. */
573
630
/* TODO replace will better error message */
574
631
snprintf(error_message_buff, sizeof(error_message_buff),
575
632
ER(ER_CANT_CREATE_THREAD), 1);
576
arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
633
protocol->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)
596
const char* old_msg = get_proc_info();
597
safe_mutex_assert_owner(mutex);
598
mysys_var->current_mutex = &mutex;
599
mysys_var->current_cond = &cond;
600
this->set_proc_info(msg);
604
void Session::exit_cond(const char* old_msg)
607
Putting the mutex unlock in exit_cond() ensures that
608
mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
609
locked (if that would not be the case, you'll get a deadlock if someone
610
does a Session::awake() on you).
612
mysys_var->current_mutex->unlock();
613
boost_unique_lock_t scopedLock(mysys_var->mutex);
614
mysys_var->current_mutex = 0;
615
mysys_var->current_cond = 0;
616
this->set_proc_info(old_msg);
619
640
bool Session::authenticate()
621
if (client->authenticate())
643
if (protocol->authenticate())
624
status_var.aborted_connects++;
646
statistic_increment(aborted_connects, &LOCK_status);
629
bool Session::checkUser(const std::string &passwd_str,
630
const std::string &in_db)
650
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
632
bool is_authenticated=
633
plugin::Authentication::isAuthenticated(user(), passwd_str);
652
LEX_STRING db_str= { (char *) in_db, in_db ? strlen(in_db) : 0 };
653
bool is_authenticated;
656
Clear session->db as it points to something, that will be freed when
657
connection is closed. We don't want to accidentally free a wrong
658
pointer if connect failed. Also in case of 'CHANGE USER' failure,
659
current database will be switched to 'no database selected'.
663
if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
665
my_error(ER_HANDSHAKE_ERROR, MYF(0), security_ctx.ip.c_str());
669
is_authenticated= authenticate_user(this, passwd);
635
671
if (is_authenticated != true)
637
status_var.access_denied++;
638
/* isAuthenticated has pushed the error message */
673
my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
674
security_ctx.user.c_str(),
675
security_ctx.ip.c_str(),
676
passwd_len ? ER(ER_YES) : ER(ER_NO));
681
security_ctx.skip_grants();
642
683
/* Change database if necessary */
643
if (not in_db.empty())
684
if (in_db && in_db[0])
645
identifier::Schema identifier(in_db);
646
if (change_db(this, identifier))
686
if (mysql_change_db(this, &db_str, false))
648
/* change_db() has pushed the error message. */
688
/* mysql_change_db() has pushed the error message. */
653
password= not passwd_str.empty();
693
password= test(passwd_len); // remember for error messages
655
695
/* Ready to handle queries */
700
733
in_packet_length--;
702
735
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])))
736
while (in_packet_length > 0 &&
737
(pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
706
740
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));
743
/* We must allocate some extra memory for the cached query string */
744
query_length= 0; /* Extra safety: Avoid races */
745
query= (char*) memdup_w_gap((unsigned char*) in_packet, in_packet_length, db_length + 1);
749
query[in_packet_length]=0;
750
query_length= in_packet_length;
752
/* Reclaim some memory */
753
packet.shrink(variables.net_buffer_length);
754
convert_buffer.shrink(variables.net_buffer_length);
860
886
@return NULL on failure, or pointer to the LEX_STRING object
862
888
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
863
const std::string &str,
864
bool allocate_lex_string)
866
return make_lex_string(lex_str, str.c_str(), str.length(), allocate_lex_string);
869
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
870
const char* str, uint32_t length,
871
bool allocate_lex_string)
889
const char* str, uint32_t length,
890
bool allocate_lex_string)
873
892
if (allocate_lex_string)
874
if (!(lex_str= (LEX_STRING *)getMemRoot()->allocate(sizeof(LEX_STRING))))
893
if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
876
if (!(lex_str->str= mem_root->strmake_root(str, length)))
895
if (!(lex_str->str= strmake_root(mem_root, str, length)))
878
897
lex_str->length= length;
901
/* routings to adding tables to list of changed in transaction tables */
902
inline static void list_include(CHANGED_TableList** prev,
903
CHANGED_TableList* curr,
904
CHANGED_TableList* new_table)
909
(*prev)->next = curr;
913
/* add table to list of changed in transaction tables */
915
void Session::add_changed_table(Table *table)
917
assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
918
table->file->has_transactions());
919
add_changed_table(table->s->table_cache_key.str,
920
(long) table->s->table_cache_key.length);
924
void Session::add_changed_table(const char *key, long key_length)
926
CHANGED_TableList **prev_changed = &transaction.changed_tables;
927
CHANGED_TableList *curr = transaction.changed_tables;
929
for (; curr; prev_changed = &(curr->next), curr = curr->next)
931
int cmp = (long)curr->key_length - (long)key_length;
934
list_include(prev_changed, curr, changed_table_dup(key, key_length));
939
cmp = memcmp(curr->key, key, curr->key_length);
942
list_include(prev_changed, curr, changed_table_dup(key, key_length));
951
*prev_changed = changed_table_dup(key, key_length);
955
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
957
CHANGED_TableList* new_table =
958
(CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
962
my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
963
ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
964
killed= KILL_CONNECTION;
968
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
970
new_table->key_length = key_length;
971
::memcpy(new_table->key, key, key_length);
882
976
int Session::send_explain_fields(select_result *result)
884
978
List<Item> field_list;
917
1011
return (result->send_fields(field_list));
920
void select_result::send_error(drizzled::error_t errcode, const char *err)
922
my_message(errcode, err, MYF(0));
925
1014
/************************************************************************
926
1015
Handling writing to file
927
1016
************************************************************************/
929
void select_to_file::send_error(drizzled::error_t errcode,const char *err)
1018
void select_to_file::send_error(uint32_t errcode,const char *err)
931
1020
my_message(errcode, err, MYF(0));
934
(void) cache->end_io_cache();
935
(void) internal::my_close(file, MYF(0));
936
(void) internal::my_delete(path.file_string().c_str(), MYF(0)); // Delete file on error
1023
(void) end_io_cache(&cache);
1024
(void) my_close(file,MYF(0));
1025
(void) 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)
1100
static File create_file(Session *session, char *path, file_exchange *exchange, IO_CACHE *cache)
1019
fs::path to_file(exchange->file_name);
1022
if (not to_file.has_root_directory())
1103
uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1105
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
1106
option|= MY_REPLACE_DIR; // Force use of db directory
1109
if (!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;
1111
strcpy(path, drizzle_real_data_home);
1113
strncat(path, session->db, FN_REFLEN-strlen(drizzle_real_data_home)-1);
1114
(void) 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))
1117
(void) fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1119
if (opt_secure_file_priv &&
1120
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1122
/* Write only allowed to dir or subdir specified by secure_file_priv */
1123
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1127
if (!access(path, F_OK))
1058
1129
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1061
1132
/* 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)
1133
if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1064
1136
(void) fchmod(file, 0666); // Because of umask()
1065
if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1138
(void) chmod(path, 0666);
1140
if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1067
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
1142
my_close(file, MYF(0));
1143
my_delete(path, MYF(0)); // Delete file on error, it was just created
1164
1242
res=item->str_result(&tmp);
1165
1243
if (res && enclosed)
1167
if (my_b_write(cache,(unsigned char*) exchange->enclosed->ptr(),
1168
exchange->enclosed->length()))
1245
if (my_b_write(&cache,(unsigned char*) exchange->enclosed->ptr(),
1246
exchange->enclosed->length()))
1173
1251
if (!fixed_row_size)
1175
if (escape_char != -1) // Use \N syntax
1177
null_buff[0]=escape_char;
1179
if (my_b_write(cache,(unsigned char*) null_buff,2))
1182
else if (my_b_write(cache,(unsigned char*) "NULL",4))
1253
if (escape_char != -1) // Use \N syntax
1255
null_buff[0]=escape_char;
1257
if (my_b_write(&cache,(unsigned char*) null_buff,2))
1260
else if (my_b_write(&cache,(unsigned char*) "NULL",4))
1187
used_length=0; // Fill with space
1265
used_length=0; // Fill with space
1192
1270
if (fixed_row_size)
1193
used_length= min(res->length(), static_cast<size_t>(item->max_length));
1271
used_length= min(res->length(),item->max_length);
1195
1273
used_length= res->length();
1197
1275
if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1200
1278
char *pos, *start, *end;
1201
1279
const CHARSET_INFO * const res_charset= res->charset();
1202
1280
const CHARSET_INFO * const character_set_client= default_charset_info;
1204
1282
bool check_second_byte= (res_charset == &my_charset_bin) &&
1205
character_set_client->
1206
escape_with_backslash_is_dangerous;
1283
character_set_client->
1284
escape_with_backslash_is_dangerous;
1207
1285
assert(character_set_client->mbmaxlen == 2 ||
1208
1286
!character_set_client->escape_with_backslash_is_dangerous);
1209
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1213
if (use_mb(res_charset))
1216
if ((l=my_ismbchar(res_charset, pos, end)))
1287
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1291
if (use_mb(res_charset))
1294
if ((l=my_ismbchar(res_charset, pos, end)))
1224
1302
Special case when dumping BINARY/VARBINARY/BLOB values
1252
1330
assert before the loop makes that sure.
1255
if ((needs_escaping(*pos, enclosed) ||
1333
if ((NEED_ESCAPING(*pos) ||
1256
1334
(check_second_byte &&
1257
1335
my_mbcharlen(character_set_client, (unsigned char) *pos) == 2 &&
1258
1336
pos + 1 < end &&
1259
needs_escaping(pos[1], enclosed))) &&
1337
NEED_ESCAPING(pos[1]))) &&
1261
Don't escape field_term_char by doubling - doubling is only
1262
valid for ENCLOSED BY characters:
1339
Don't escape field_term_char by doubling - doubling is only
1340
valid for ENCLOSED BY characters:
1264
1342
(enclosed || !is_ambiguous_field_term ||
1265
1343
(int) (unsigned char) *pos != field_term_char))
1268
1346
tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1269
1347
is_ambiguous_field_sep) ?
1270
field_sep_char : escape_char;
1271
tmp_buff[1]= *pos ? *pos : '0';
1272
if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1273
my_b_write(cache,(unsigned char*) tmp_buff,2))
1278
if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
1348
field_sep_char : escape_char;
1349
tmp_buff[1]= *pos ? *pos : '0';
1350
if (my_b_write(&cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1351
my_b_write(&cache,(unsigned char*) tmp_buff,2))
1356
if (my_b_write(&cache,(unsigned char*) start,(uint32_t) (pos-start)))
1281
else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
1359
else if (my_b_write(&cache,(unsigned char*) res->ptr(),used_length))
1284
1362
if (fixed_row_size)
1285
1363
{ // Fill with space
1286
1364
if (item->max_length > used_length)
1288
/* QQ: Fix by adding a my_b_fill() function */
1292
memset(space, ' ', sizeof(space));
1294
uint32_t length=item->max_length-used_length;
1295
for (; length > sizeof(space) ; length-=sizeof(space))
1297
if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1300
if (my_b_write(cache,(unsigned char*) space,length))
1366
/* QQ: Fix by adding a my_b_fill() function */
1370
memset(space, ' ', sizeof(space));
1372
uint32_t length=item->max_length-used_length;
1373
for (; length > sizeof(space) ; length-=sizeof(space))
1375
if (my_b_write(&cache,(unsigned char*) space,sizeof(space)))
1378
if (my_b_write(&cache,(unsigned char*) space,length))
1304
1382
if (res && enclosed)
1306
if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1384
if (my_b_write(&cache, (unsigned char*) exchange->enclosed->ptr(),
1307
1385
exchange->enclosed->length()))
1310
1388
if (--items_left)
1312
if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1390
if (my_b_write(&cache, (unsigned char*) exchange->field_term->ptr(),
1313
1391
field_term_length))
1317
if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1318
exchange->line_term->length()))
1395
if (my_b_write(&cache,(unsigned char*) exchange->line_term->ptr(),
1396
exchange->line_term->length()))
1480
1559
bool select_max_min_finder_subselect::cmp_decimal()
1482
1561
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);
1562
my_decimal cval, *cvalue= cache->val_decimal(&cval);
1563
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1486
1565
return (cache->null_value && !maxmin->null_value) ||
1487
1566
(!cache->null_value && !maxmin->null_value &&
1488
class_decimal_cmp(cvalue, mvalue) > 0) ;
1567
my_decimal_cmp(cvalue, mvalue) > 0) ;
1489
1568
return (maxmin->null_value && !cache->null_value) ||
1490
1569
(!cache->null_value && !maxmin->null_value &&
1491
class_decimal_cmp(cvalue,mvalue) < 0);
1570
my_decimal_cmp(cvalue,mvalue) < 0);
1494
1573
bool select_max_min_finder_subselect::cmp_str()
1591
1660
memset(&status_var, 0, sizeof(status_var));
1595
void Session::set_db(const std::string &new_db)
1663
void Security_context::skip_grants()
1665
/* privileges for the user are unknown everything is allowed */
1669
/****************************************************************************
1670
Handling of open and locked tables states.
1672
This is used when we want to open/lock (and then close) some tables when
1673
we already have a set of tables open and locked. We use these methods for
1674
access to mysql.proc table to find definitions of stored routines.
1675
****************************************************************************/
1677
void Session::reset_n_backup_open_tables_state(Open_tables_state *backup)
1679
backup->set_open_tables_state(this);
1680
reset_open_tables_state();
1681
backups_available= false;
1685
void Session::restore_backup_open_tables_state(Open_tables_state *backup)
1688
Before we will throw away current open tables state we want
1689
to be sure that it was properly cleaned up.
1691
assert(open_tables == 0 && temporary_tables == 0 &&
1692
derived_tables == 0 &&
1694
set_open_tables_state(backup);
1698
bool Session::set_db(const char *new_db, size_t new_db_len)
1597
1700
/* Do not reallocate memory if current chunk is big enough. */
1598
if (new_db.length())
1600
_schema.reset(new std::string(new_db));
1701
if (db && new_db && db_length >= new_db_len)
1702
memcpy(db, new_db, new_db_len+1);
1604
_schema.reset(new std::string(""));
1709
db= (char *)malloc(new_db_len + 1);
1712
memcpy(db, new_db, new_db_len);
1719
db_length= db ? new_db_len : 0;
1720
return new_db && !db;
1725
Check the killed state of a user thread
1726
@param session user thread
1727
@retval 0 the user thread is active
1728
@retval 1 the user thread has been killed
1730
extern "C" int session_killed(const Session *session)
1732
return(session->killed);
1736
Return the thread id of a user thread
1737
@param session user thread
1740
extern "C" unsigned long session_get_thread_id(const Session *session)
1742
return((unsigned long)session->thread_id);
1747
LEX_STRING *session_make_lex_string(Session *session, LEX_STRING *lex_str,
1748
const char *str, unsigned int size,
1749
int allocate_lex_string)
1751
return session->make_lex_string(lex_str, str, size,
1752
(bool) allocate_lex_string);
1755
const struct charset_info_st *session_charset(Session *session)
1757
return(session->charset());
1760
char **session_query(Session *session)
1762
return(&session->query);
1765
int session_non_transactional_update(const Session *session)
1767
return(session->transaction.all.modified_non_trans_table);
1770
void session_mark_transaction_to_rollback(Session *session, bool all)
1772
mark_transaction_to_rollback(session, all);
1610
1776
Mark transaction to rollback and mark error as fatal to a sub-statement.
1612
1778
@param session Thread handle
1613
1779
@param all true <=> rollback main transaction.
1615
void Session::markTransactionForRollback(bool all)
1781
void mark_transaction_to_rollback(Session *session, bool all)
1617
is_fatal_sub_stmt_error= true;
1618
transaction_rollback_request= all;
1785
session->is_fatal_sub_stmt_error= true;
1786
session->transaction_rollback_request= all;
1621
void Session::disconnect(enum error_t errcode)
1790
void Session::disconnect(uint32_t errcode, bool should_lock)
1623
1792
/* Allow any plugins to cleanup their session variables */
1624
1793
plugin_sessionvar_cleanup(this);
1626
1795
/* If necessary, log any aborted or unauthorized connections */
1627
if (getKilled() || client->wasAborted())
1629
status_var.aborted_threads++;
1796
if (killed || protocol->wasAborted())
1797
statistic_increment(aborted_threads, &LOCK_status);
1632
if (client->wasAborted())
1799
if (protocol->wasAborted())
1634
if (not getKilled() && variables.log_warnings > 1)
1801
if (! killed && variables.log_warnings > 1)
1636
errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
1803
Security_context *sctx= &security_ctx;
1805
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()
1807
, (db ? db : "unconnected")
1808
, sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated"
1641
1810
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1645
setKilled(Session::KILL_CONNECTION);
1647
if (client->isConnected())
1814
/* Close out our connection to the client */
1816
(void) pthread_mutex_lock(&LOCK_thread_count);
1817
killed= Session::KILL_CONNECTION;
1818
if (protocol->isConnected())
1649
if (errcode != EE_OK)
1651
1822
/*my_error(errcode, ER(errcode));*/
1652
client->sendError(errcode, ER(errcode));
1823
protocol->sendError(errcode, ER(errcode)); /* purecov: inspected */
1828
(void) pthread_mutex_unlock(&LOCK_thread_count);
1658
1831
void Session::reset_for_next_command()
1719
1902
passing non-zero value to end_slave via rli->save_temporary_tables
1720
1903
when no temp tables opened, see an invariant below.
1722
temporary_tables= table->getNext();
1905
temporary_tables= table->next;
1723
1906
if (temporary_tables)
1725
table->getNext()->setPrev(NULL);
1907
table->next->prev= NULL;
1909
close_temporary(table, free_share, delete_table);
1732
Close and drop a temporary table
1913
Close and delete a temporary table
1735
1916
This dosn't unlink table from session->temporary
1736
1917
If this is needed, use close_temporary_table()
1739
void Open_tables_state::nukeTable(Table *table)
1920
void Session::close_temporary(Table *table, bool free_share, bool delete_table)
1741
plugin::StorageEngine *table_type= table->getShare()->db_type();
1922
StorageEngine *table_type= table->s->db_type();
1743
1924
table->free_io_cache();
1744
table->delete_table();
1746
identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1747
rm_temporary_table(table_type, identifier);
1749
boost::checked_delete(table->getMutableShare());
1751
boost::checked_delete(table);
1925
table->closefrm(false);
1928
rm_temporary_table(table_type, table->s->path.str);
1932
table->s->free_table_share();
1933
/* This makes me sad, but we're allocating it via malloc */
1754
1938
/** Clear most status variables. */
1755
1939
extern time_t flush_status_time;
1940
extern uint32_t max_used_connections;
1757
1942
void Session::refresh_status()
1944
pthread_mutex_lock(&LOCK_status);
1946
/* Add thread's status variabes to global status */
1947
add_to_status(&global_status_var, &status_var);
1759
1949
/* Reset thread's status variables */
1760
1950
memset(&status_var, 0, sizeof(status_var));
1952
/* Reset some global variables */
1953
reset_status_vars();
1955
/* Reset the counters of all key caches (default and named). */
1956
reset_key_cache_counters();
1762
1957
flush_status_time= time((time_t*) 0);
1763
current_global_counters.max_used_connections= 1; /* We set it to one, because we know we exist */
1764
current_global_counters.connections= 0;
1958
max_used_connections= 1; /* We set it to one, because we know we exist */
1959
pthread_mutex_unlock(&LOCK_status);
1962
#define extra_size sizeof(double)
1767
1964
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
1966
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)
1968
entry= (user_var_entry*) hash_search(&user_vars, (unsigned char*) name.str, name.length);
1970
if ((entry == NULL) && create_if_not_exists)
1794
boost::checked_delete(entry);
1972
if (!hash_inited(&user_vars))
1974
entry= new (nothrow) user_var_entry(name.str, query_id);
1979
if (my_hash_insert(&user_vars, (unsigned char*) entry))
1982
free((char*) entry);
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()
1815
for (Table *table= temporary_tables ; table ; table= table->getNext())
1817
if (table->query_id == getQueryId())
1991
void Session::mark_temp_tables_as_free_for_reuse()
1993
for (Table *table= temporary_tables ; table ; table= table->next)
1995
if (table->query_id == query_id)
1819
1997
table->query_id= 0;
1820
table->cursor->ha_reset();
1998
table->file->ha_reset();
1825
2003
void Session::mark_used_tables_as_free_for_reuse(Table *table)
1827
for (; table ; table= table->getNext())
2005
for (; table ; table= table->next)
1829
if (table->query_id == getQueryId())
2007
if (table->query_id == query_id)
1831
2009
table->query_id= 0;
1832
table->cursor->ha_reset();
2010
table->file->ha_reset();
1916
2120
if (open_tables_from_list(&tables, &counter))
1919
if (not lock_tables(tables, counter, &need_reopen))
2123
if (!lock_tables(tables, counter, &need_reopen))
1922
if (not need_reopen)
1925
2127
close_tables_for_reopen(&tables);
1928
if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
1935
@note "best_effort" is used in cases were if a failure occurred on this
1936
operation it would not be surprising because we are only removing because there
1937
might be an issue (lame engines).
1940
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
1942
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1944
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);
1958
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
1960
drizzled::error_t error;
2129
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
2130
(fill_derived_tables() &&
2131
mysql_handle_derived(lex, &mysql_derived_filling))))
2132
return true; /* purecov: inspected */
2137
bool Session::openTables(TableList *tables, uint32_t flags)
2140
bool ret= fill_derived_tables();
2141
assert(ret == false);
2142
if (open_tables_from_list(&tables, &counter, flags) ||
2143
mysql_handle_derived(lex, &mysql_derived_prepare))
2144
return true; /* purecov: inspected */
2148
bool Session::rm_temporary_table(StorageEngine *base, char *path)
1963
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
1966
identifier.getSQLPath(path);
1967
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1968
path.c_str(), error);
1977
@note this will be removed, I am looking through Hudson to see if it is finding
1978
any tables that are missed during cleanup.
1980
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
1984
if (not temporary_tables)
1987
cerr << "Begin Run: " << foo << "\n";
1988
for (table= temporary_tables; table; table= table->getNext())
1990
bool have_proto= false;
1992
message::Table *proto= table->getShare()->getTableMessage();
1993
if (table->getShare()->getTableMessage())
1996
const char *answer= have_proto ? "true" : "false";
2000
cerr << "\tTable Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2001
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2005
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 */
2077
} /* namespace drizzled */
2154
if (delete_table_proto_file(path))
2155
error=1; /* purecov: inspected */
2157
if (base->deleteTable(this, path))
2160
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),