36
35
#include <drizzled/item/return_int.h>
37
36
#include <drizzled/item/empty_string.h>
38
37
#include <drizzled/show.h>
39
#include <drizzled/plugin/client.h>
40
#include "drizzled/plugin/scheduler.h"
41
#include "drizzled/plugin/authentication.h"
42
#include "drizzled/plugin/logging.h"
43
#include "drizzled/plugin/transactional_storage_engine.h"
44
#include "drizzled/probes.h"
45
#include "drizzled/table_proto.h"
46
#include "drizzled/db.h"
47
#include "drizzled/pthread_globals.h"
48
#include "drizzled/transaction_services.h"
50
#include "plugin/myisam/myisam.h"
51
#include "drizzled/internal/iocache.h"
63
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool );
64
void free_user_var(user_var_entry *entry);
38
#include <drizzled/scheduling.h>
68
41
The following is used to initialise Table_ident with a internal
74
47
const char * const Session::DEFAULT_WHERE= "field list";
75
48
extern pthread_key_t THR_Session;
76
49
extern pthread_key_t THR_Mem_root;
77
extern uint32_t max_used_connections;
78
extern atomic<uint32_t> connection_count;
51
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
53
template class List<Key>;
54
template class List_iterator<Key>;
55
template class List<Key_part_spec>;
56
template class List_iterator<Key_part_spec>;
57
template class List<Alter_drop>;
58
template class List_iterator<Alter_drop>;
59
template class List<Alter_column>;
60
template class List_iterator<Alter_column>;
81
63
/****************************************************************************
83
65
****************************************************************************/
84
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool )
66
extern "C" unsigned char *get_var_key(user_var_entry *entry, size_t *length,
86
69
*length= entry->name.length;
87
70
return (unsigned char*) entry->name.str;
90
void free_user_var(user_var_entry *entry)
73
extern "C" void free_user_var(user_var_entry *entry)
75
char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
76
if (entry->value && entry->value != pos)
95
81
bool Key_part_spec::operator==(const Key_part_spec& other) const
266
253
memset(&status_var, 0, sizeof(status_var));
268
255
/* Initialize sub structures */
269
memory::init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
256
init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
270
257
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
271
258
(hash_get_key) get_var_key,
272
259
(hash_free_key) free_user_var, 0);
262
protocol= protocol_arg;
263
protocol->setSession(this);
265
const Query_id& local_query_id= Query_id::get_query_id();
267
protocol->setRandom(tmp + (uint64_t) &protocol,
268
tmp + (uint64_t)local_query_id.value());
274
269
substitute_null_with_insert_id = false;
275
270
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
276
271
thr_lock_owner_init(&main_lock_id, &lock_info);
384
399
Session::~Session()
401
Session_CHECK_SENTRY(this);
387
402
add_to_status(&global_status_var, &status_var);
389
if (client->isConnected())
404
if (protocol->isConnected())
391
406
if (global_system_variables.log_warnings)
392
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
407
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),my_progname,
394
(getSecurityContext().getUser().c_str() ?
395
getSecurityContext().getUser().c_str() : ""));
409
(security_ctx.user.c_str() ?
410
security_ctx.user.c_str() : ""));
396
411
disconnect(0, false);
399
414
/* Close connection */
403
418
if (cleanup_done == false)
406
plugin::StorageEngine::closeConnection(this);
421
ha_close_connection(this);
407
422
plugin_sessionvar_cleanup(this);
409
429
free_root(&warn_root,MYF(0));
430
free_root(&transaction.mem_root,MYF(0));
410
431
mysys_var=0; // Safety (shouldn't be needed)
411
432
dbug_sentry= Session_SENTRY_GONE;
413
434
free_root(&main_mem_root, MYF(0));
414
435
pthread_setspecific(THR_Session, 0);
416
plugin::Logging::postEndDo(this);
418
438
/* Ensure that no one is using Session */
419
439
pthread_mutex_unlock(&LOCK_delete);
541
560
created in another thread
543
562
thr_lock_info_init(&lock_info);
548
Init Session for query processing.
549
This has to be called once before we call mysql_parse.
550
See also comments in session.h.
553
566
void Session::prepareForQueries()
555
568
if (variables.max_join_size == HA_POS_ERROR)
556
569
options |= OPTION_BIG_SELECTS;
570
if (client_capabilities & CLIENT_COMPRESS)
572
protocol->enableCompression();
558
575
version= refresh_version;
559
576
set_proc_info(NULL);
560
577
command= COM_SLEEP;
563
reset_root_defaults(mem_root, variables.query_alloc_block_size,
564
variables.query_prealloc_size);
565
transaction.xid_state.xid.null();
566
transaction.xid_state.in_session=1;
569
582
bool Session::initGlobals()
573
586
disconnect(ER_OUT_OF_RESOURCES, true);
574
587
statistic_increment(aborted_connects, &LOCK_status);
582
if (initGlobals() || authenticate())
590
while (! client->haveError() && killed != KILL_CONNECTION)
592
if (! executeStatement())
599
bool Session::schedule()
601
scheduler= plugin::Scheduler::getScheduler();
604
connection_count.increment();
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);
618
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
620
killed= Session::KILL_CONNECTION;
622
statistic_increment(aborted_connects, &LOCK_status);
624
/* Can't use my_error() since store_globals has not been called. */
625
/* TODO replace will better error message */
626
snprintf(error_message_buff, sizeof(error_message_buff),
627
ER(ER_CANT_CREATE_THREAD), 1);
628
client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
636
const char* Session::enter_cond(pthread_cond_t *cond,
637
pthread_mutex_t* mutex,
640
const char* old_msg = get_proc_info();
641
safe_mutex_assert_owner(mutex);
642
mysys_var->current_mutex = mutex;
643
mysys_var->current_cond = cond;
644
this->set_proc_info(msg);
648
void Session::exit_cond(const char* old_msg)
651
Putting the mutex unlock in exit_cond() ensures that
652
mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
653
locked (if that would not be the case, you'll get a deadlock if someone
654
does a Session::awake() on you).
656
pthread_mutex_unlock(mysys_var->current_mutex);
657
pthread_mutex_lock(&mysys_var->mutex);
658
mysys_var->current_mutex = 0;
659
mysys_var->current_cond = 0;
660
this->set_proc_info(old_msg);
661
pthread_mutex_unlock(&mysys_var->mutex);
588
Scheduler &thread_scheduler= get_thread_scheduler();
589
thread_scheduler.end_thread(this, 0);
664
595
bool Session::authenticate()
667
if (client->authenticate())
598
if (protocol->authenticate())
670
601
statistic_increment(aborted_connects, &LOCK_status);
674
605
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
676
const string passwd_str(passwd, passwd_len);
677
bool is_authenticated=
678
plugin::Authentication::isAuthenticated(getSecurityContext(),
607
LEX_STRING db_str= { (char *) in_db, in_db ? strlen(in_db) : 0 };
608
bool is_authenticated;
611
Clear session->db as it points to something, that will be freed when
612
connection is closed. We don't want to accidentally free a wrong
613
pointer if connect failed. Also in case of 'CHANGE USER' failure,
614
current database will be switched to 'no database selected'.
618
if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
620
my_error(ER_HANDSHAKE_ERROR, MYF(0), security_ctx.ip.c_str());
624
is_authenticated= authenticate_user(this, passwd);
681
626
if (is_authenticated != true)
683
/* isAuthenticated has pushed the error message */
628
my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
629
security_ctx.user.c_str(),
630
security_ctx.ip.c_str(),
631
passwd_len ? ER(ER_YES) : ER(ER_NO));
636
security_ctx.skip_grants();
687
638
/* Change database if necessary */
688
639
if (in_db && in_db[0])
690
SchemaIdentifier identifier(in_db);
691
if (mysql_change_db(this, identifier))
641
if (mysql_change_db(this, &db_str, false))
693
643
/* mysql_change_db() has pushed the error message. */
856
/* routings to adding tables to list of changed in transaction tables */
857
inline static void list_include(CHANGED_TableList** prev,
858
CHANGED_TableList* curr,
859
CHANGED_TableList* new_table)
864
(*prev)->next = curr;
868
/* add table to list of changed in transaction tables */
870
void Session::add_changed_table(Table *table)
872
assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
873
table->file->has_transactions());
874
add_changed_table(table->s->table_cache_key.str,
875
(long) table->s->table_cache_key.length);
879
void Session::add_changed_table(const char *key, long key_length)
881
CHANGED_TableList **prev_changed = &transaction.changed_tables;
882
CHANGED_TableList *curr = transaction.changed_tables;
884
for (; curr; prev_changed = &(curr->next), curr = curr->next)
886
int cmp = (long)curr->key_length - (long)key_length;
889
list_include(prev_changed, curr, changed_table_dup(key, key_length));
894
cmp = memcmp(curr->key, key, curr->key_length);
897
list_include(prev_changed, curr, changed_table_dup(key, key_length));
906
*prev_changed = changed_table_dup(key, key_length);
910
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
912
CHANGED_TableList* new_table =
913
(CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
917
my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
918
ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
919
killed= KILL_CONNECTION;
923
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
925
new_table->key_length = key_length;
926
::memcpy(new_table->key, key, key_length);
908
931
int Session::send_explain_fields(select_result *result)
910
933
List<Item> field_list;
1040
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1056
static File create_file(Session *session, char *path, file_exchange *exchange, IO_CACHE *cache)
1043
1059
uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1045
1061
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
1046
1062
option|= MY_REPLACE_DIR; // Force use of db directory
1049
if (!internal::dirname_length(exchange->file_name))
1065
if (!dirname_length(exchange->file_name))
1051
1067
strcpy(path, drizzle_real_data_home);
1052
if (! session->db.empty())
1053
strncat(path, session->db.c_str(), FN_REFLEN-strlen(drizzle_real_data_home)-1);
1054
(void) internal::fn_format(path, exchange->file_name, path, "", option);
1069
strncat(path, session->db, FN_REFLEN-strlen(drizzle_real_data_home)-1);
1070
(void) fn_format(path, exchange->file_name, path, "", option);
1057
(void) internal::fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1073
(void) fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1059
1075
if (opt_secure_file_priv &&
1060
1076
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1072
1088
/* Create the file world readable */
1073
if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1089
if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1075
1092
(void) fchmod(file, 0666); // Because of umask()
1076
if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1094
(void) chmod(path, 0666);
1096
if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1078
internal::my_close(file, MYF(0));
1079
internal::my_delete(path, MYF(0)); // Delete file on error, it was just created
1098
my_close(file, MYF(0));
1099
my_delete(path, MYF(0)); // Delete file on error, it was just created
1171
1198
res=item->str_result(&tmp);
1172
1199
if (res && enclosed)
1174
if (my_b_write(cache,(unsigned char*) exchange->enclosed->ptr(),
1175
exchange->enclosed->length()))
1201
if (my_b_write(&cache,(unsigned char*) exchange->enclosed->ptr(),
1202
exchange->enclosed->length()))
1180
1207
if (!fixed_row_size)
1182
if (escape_char != -1) // Use \N syntax
1184
null_buff[0]=escape_char;
1186
if (my_b_write(cache,(unsigned char*) null_buff,2))
1189
else if (my_b_write(cache,(unsigned char*) "NULL",4))
1209
if (escape_char != -1) // Use \N syntax
1211
null_buff[0]=escape_char;
1213
if (my_b_write(&cache,(unsigned char*) null_buff,2))
1216
else if (my_b_write(&cache,(unsigned char*) "NULL",4))
1194
used_length=0; // Fill with space
1221
used_length=0; // Fill with space
1199
1226
if (fixed_row_size)
1200
used_length= min(res->length(),item->max_length);
1227
used_length=cmin(res->length(),item->max_length);
1202
used_length= res->length();
1229
used_length=res->length();
1204
1230
if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1207
1233
char *pos, *start, *end;
1208
1234
const CHARSET_INFO * const res_charset= res->charset();
1209
1235
const CHARSET_INFO * const character_set_client= default_charset_info;
1211
1237
bool check_second_byte= (res_charset == &my_charset_bin) &&
1212
character_set_client->
1213
escape_with_backslash_is_dangerous;
1238
character_set_client->
1239
escape_with_backslash_is_dangerous;
1214
1240
assert(character_set_client->mbmaxlen == 2 ||
1215
1241
!character_set_client->escape_with_backslash_is_dangerous);
1216
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1220
if (use_mb(res_charset))
1223
if ((l=my_ismbchar(res_charset, pos, end)))
1242
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1247
if (use_mb(res_charset))
1250
if ((l=my_ismbchar(res_charset, pos, end)))
1231
1259
Special case when dumping BINARY/VARBINARY/BLOB values
1259
1287
assert before the loop makes that sure.
1262
if ((needs_escaping(*pos, enclosed) ||
1290
if ((NEED_ESCAPING(*pos) ||
1263
1291
(check_second_byte &&
1264
1292
my_mbcharlen(character_set_client, (unsigned char) *pos) == 2 &&
1265
1293
pos + 1 < end &&
1266
needs_escaping(pos[1], enclosed))) &&
1294
NEED_ESCAPING(pos[1]))) &&
1268
Don't escape field_term_char by doubling - doubling is only
1269
valid for ENCLOSED BY characters:
1296
Don't escape field_term_char by doubling - doubling is only
1297
valid for ENCLOSED BY characters:
1271
1299
(enclosed || !is_ambiguous_field_term ||
1272
1300
(int) (unsigned char) *pos != field_term_char))
1275
1303
tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1276
1304
is_ambiguous_field_sep) ?
1277
field_sep_char : escape_char;
1278
tmp_buff[1]= *pos ? *pos : '0';
1279
if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1280
my_b_write(cache,(unsigned char*) tmp_buff,2))
1285
if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
1305
field_sep_char : escape_char;
1306
tmp_buff[1]= *pos ? *pos : '0';
1307
if (my_b_write(&cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1308
my_b_write(&cache,(unsigned char*) tmp_buff,2))
1313
if (my_b_write(&cache,(unsigned char*) start,(uint32_t) (pos-start)))
1288
else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
1316
else if (my_b_write(&cache,(unsigned char*) res->ptr(),used_length))
1291
1319
if (fixed_row_size)
1292
1320
{ // Fill with space
1293
1321
if (item->max_length > used_length)
1295
/* QQ: Fix by adding a my_b_fill() function */
1299
memset(space, ' ', sizeof(space));
1301
uint32_t length=item->max_length-used_length;
1302
for (; length > sizeof(space) ; length-=sizeof(space))
1304
if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1307
if (my_b_write(cache,(unsigned char*) space,length))
1323
/* QQ: Fix by adding a my_b_fill() function */
1327
memset(space, ' ', sizeof(space));
1329
uint32_t length=item->max_length-used_length;
1330
for (; length > sizeof(space) ; length-=sizeof(space))
1332
if (my_b_write(&cache,(unsigned char*) space,sizeof(space)))
1335
if (my_b_write(&cache,(unsigned char*) space,length))
1311
1339
if (res && enclosed)
1313
if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1341
if (my_b_write(&cache, (unsigned char*) exchange->enclosed->ptr(),
1314
1342
exchange->enclosed->length()))
1317
1345
if (--items_left)
1319
if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1347
if (my_b_write(&cache, (unsigned char*) exchange->field_term->ptr(),
1320
1348
field_term_length))
1324
if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1325
exchange->line_term->length()))
1352
if (my_b_write(&cache,(unsigned char*) exchange->line_term->ptr(),
1353
exchange->line_term->length()))
1646
Return the session id of a user session
1647
@param pointer to Session object
1648
@return session's id
1715
Return the thread id of a user thread
1716
@param session user thread
1650
1719
extern "C" unsigned long session_get_thread_id(const Session *session)
1652
return (unsigned long) session->getSessionId();
1656
const struct charset_info_st *session_charset(Session *session)
1721
return((unsigned long)session->thread_id);
1726
LEX_STRING *session_make_lex_string(Session *session, LEX_STRING *lex_str,
1727
const char *str, unsigned int size,
1728
int allocate_lex_string)
1730
return session->make_lex_string(lex_str, str, size,
1731
(bool) allocate_lex_string);
1734
extern "C" const struct charset_info_st *session_charset(Session *session)
1658
1736
return(session->charset());
1661
int session_non_transactional_update(const Session *session)
1663
return(session->transaction.all.hasModifiedNonTransData());
1666
void session_mark_transaction_to_rollback(Session *session, bool all)
1739
extern "C" char **session_query(Session *session)
1741
return(&session->query);
1744
extern "C" int session_non_transactional_update(const Session *session)
1746
return(session->transaction.all.modified_non_trans_table);
1749
extern "C" void session_mark_transaction_to_rollback(Session *session, bool all)
1668
1751
mark_transaction_to_rollback(session, all);
1689
1772
plugin_sessionvar_cleanup(this);
1691
1774
/* If necessary, log any aborted or unauthorized connections */
1692
if (killed || client->wasAborted())
1775
if (killed || protocol->wasAborted())
1693
1776
statistic_increment(aborted_threads, &LOCK_status);
1695
if (client->wasAborted())
1778
if (protocol->wasAborted())
1697
1780
if (! killed && variables.log_warnings > 1)
1699
SecurityContext *sctx= &security_ctx;
1782
Security_context *sctx= &security_ctx;
1701
1784
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1703
, (db.empty() ? "unconnected" : db.c_str())
1704
, sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1705
, sctx->getIp().c_str()
1786
, (db ? db : "unconnected")
1787
, sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated"
1706
1789
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1755
1849
Table *tmp_next;
1757
if (not temporary_tables)
1851
if (!temporary_tables)
1760
1854
for (table= temporary_tables; table; table= tmp_next)
1762
1856
tmp_next= table->next;
1857
close_temporary(table, true, true);
1765
1859
temporary_tables= NULL;
1769
unlink from session->temporary tables and close temporary table
1772
void Session::close_temporary_table(Table *table)
1776
table->prev->next= table->next;
1777
if (table->prev->next)
1778
table->next->prev= table->prev;
1782
/* removing the item from the list */
1783
assert(table == temporary_tables);
1785
slave must reset its temporary list pointer to zero to exclude
1786
passing non-zero value to end_slave via rli->save_temporary_tables
1787
when no temp tables opened, see an invariant below.
1789
temporary_tables= table->next;
1790
if (temporary_tables)
1791
table->next->prev= NULL;
1797
Close and drop a temporary table
1800
This dosn't unlink table from session->temporary
1801
If this is needed, use close_temporary_table()
1804
void Session::nukeTable(Table *table)
1806
plugin::StorageEngine *table_type= table->s->db_type();
1808
table->free_io_cache();
1809
table->closefrm(false);
1811
TableIdentifier identifier(table->s->getSchemaName(), table->s->table_name.str, table->s->path.str);
1812
rm_temporary_table(table_type, identifier);
1814
table->s->free_table_share();
1816
/* This makes me sad, but we're allocating it via malloc */
1820
1863
/** Clear most status variables. */
1821
1864
extern time_t flush_status_time;
1835
1878
reset_status_vars();
1837
1880
/* Reset the counters of all key caches (default and named). */
1838
reset_key_cache_counters();
1881
process_key_caches(reset_key_cache_counters);
1839
1882
flush_status_time= time((time_t*) 0);
1840
1883
max_used_connections= 1; /* We set it to one, because we know we exist */
1841
1884
pthread_mutex_unlock(&LOCK_status);
1887
#define extra_size sizeof(double)
1844
1889
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1846
1891
user_var_entry *entry= NULL;
1893
assert(name.length == strlen (name.str));
1848
1894
entry= (user_var_entry*) hash_search(&user_vars, (unsigned char*) name.str, name.length);
1850
1896
if ((entry == NULL) && create_if_not_exists)
1898
uint32_t size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
1852
1899
if (!hash_inited(&user_vars))
1854
entry= new (nothrow) user_var_entry(name.str, query_id);
1901
if (!(entry = (user_var_entry*) malloc(size)))
1903
entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
1905
entry->name.length=name.length;
1908
entry->update_query_id=0;
1909
entry->collation.set(NULL, DERIVATION_IMPLICIT);
1910
entry->unsigned_flag= 0;
1912
If we are here, we were called from a SET or a query which sets a
1913
variable. Imagine it is this:
1914
INSERT INTO t SELECT @a:=10, @a:=@a+1.
1915
Then when we have a Item_func_get_user_var (because of the @a+1) so we
1916
think we have to write the value of @a to the binlog. But before that,
1917
we have a Item_func_set_user_var to create @a (@a:=10), in this we mark
1918
the variable as "already logged" (line below) so that it won't be logged
1919
by Item_func_get_user_var (because that's not necessary).
1921
entry->used_query_id= query_id;
1922
entry->type=STRING_RESULT;
1923
memcpy(entry->name.str, name.str, name.length+1);
1859
1924
if (my_hash_insert(&user_vars, (unsigned char*) entry))
1991
2055
close_thread_tables();
1994
bool Session::openTablesLock(TableList *tables)
2058
int Session::open_and_lock_tables(TableList *tables)
1996
2060
uint32_t counter;
1997
2061
bool need_reopen;
2001
if (open_tables_from_list(&tables, &counter))
2065
if (open_tables_from_list(&tables, &counter, 0))
2004
if (not lock_tables(tables, counter, &need_reopen))
2068
if (!lock_tables(this, tables, counter, &need_reopen))
2006
if (not need_reopen)
2008
2072
close_tables_for_reopen(&tables);
2010
2074
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
2011
2075
(fill_derived_tables() &&
2012
2076
mysql_handle_derived(lex, &mysql_derived_filling))))
2077
return 1; /* purecov: inspected */
2018
bool Session::openTables(TableList *tables, uint32_t flags)
2082
bool Session::open_normal_and_derived_tables(TableList *tables, uint32_t flags)
2020
2084
uint32_t counter;
2021
bool ret= fill_derived_tables();
2022
assert(ret == false);
2085
assert(!(fill_derived_tables()));
2023
2086
if (open_tables_from_list(&tables, &counter, flags) ||
2024
2087
mysql_handle_derived(lex, &mysql_derived_prepare))
2029
bool Session::rm_temporary_table(TableIdentifier &identifier)
2031
if (plugin::StorageEngine::dropTable(*this, identifier))
2033
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2034
identifier.getSQLPath().c_str(), errno);
2035
dumpTemporaryTableNames("rm_temporary_table()");
2043
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
2047
if (plugin::StorageEngine::dropTable(*this, *base, identifier))
2049
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2050
identifier.getSQLPath().c_str(), errno);
2051
dumpTemporaryTableNames("rm_temporary_table()");
2060
@note this will be removed, I am looking through Hudson to see if it is finding
2061
any tables that are missed during cleanup.
2063
void Session::dumpTemporaryTableNames(const char *foo)
2067
if (not temporary_tables)
2070
cerr << "Begin Run: " << foo << "\n";
2071
for (table= temporary_tables; table; table= table->next)
2073
bool have_proto= false;
2075
message::Table *proto= table->s->getTableProto();
2076
if (table->s->getTableProto())
2079
const char *answer= have_proto ? "true" : "false";
2083
cerr << "\tTable Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
2084
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2087
cerr << "\tTabl;e Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
2091
bool Session::storeTableMessage(TableIdentifier &identifier, message::Table &table_message)
2093
table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2098
bool Session::removeTableMessage(TableIdentifier &identifier)
2100
TableMessageCache::iterator iter;
2102
iter= table_message_cache.find(identifier.getPath());
2104
if (iter == table_message_cache.end())
2107
table_message_cache.erase(iter);
2112
bool Session::getTableMessage(TableIdentifier &identifier, message::Table &table_message)
2114
TableMessageCache::iterator iter;
2116
iter= table_message_cache.find(identifier.getPath());
2118
if (iter == table_message_cache.end())
2121
table_message.CopyFrom(((*iter).second));
2126
bool Session::doesTableMessageExist(TableIdentifier &identifier)
2128
TableMessageCache::iterator iter;
2130
iter= table_message_cache.find(identifier.getPath());
2132
if (iter == table_message_cache.end())
2140
bool Session::renameTableMessage(TableIdentifier &from, TableIdentifier &to)
2142
TableMessageCache::iterator iter;
2144
table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2146
iter= table_message_cache.find(to.getPath());
2148
if (iter == table_message_cache.end())
2153
(*iter).second.set_schema(to.getSchemaName());
2154
(*iter).second.set_name(to.getTableName());
2159
} /* namespace drizzled */
2088
return true; /* purecov: inspected */