24
24
#include "config.h"
25
#include <drizzled/session.h>
25
#include "drizzled/session.h"
26
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/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"
40
40
#include "drizzled/plugin/scheduler.h"
41
41
#include "drizzled/plugin/authentication.h"
42
42
#include "drizzled/plugin/logging.h"
46
46
#include "drizzled/db.h"
47
47
#include "drizzled/pthread_globals.h"
48
48
#include "drizzled/transaction_services.h"
49
#include "drizzled/drizzled.h"
51
#include "drizzled/table/instance.h"
50
53
#include "plugin/myisam/myisam.h"
51
54
#include "drizzled/internal/iocache.h"
55
#include "drizzled/internal/thread_var.h"
56
#include "drizzled/plugin/event_observer.h"
58
#include "drizzled/util/functors.h"
54
61
#include <algorithm>
63
#include <boost/filesystem.hpp>
57
65
using namespace std;
67
namespace fs=boost::filesystem;
63
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool );
64
void free_user_var(user_var_entry *entry);
68
72
The following is used to initialise Table_ident with a internal
72
76
char empty_c_string[1]= {0}; /* used for not defined db */
74
78
const char * const Session::DEFAULT_WHERE= "field list";
75
extern pthread_key_t THR_Session;
76
extern pthread_key_t THR_Mem_root;
77
extern uint32_t max_used_connections;
78
extern atomic<uint32_t> connection_count;
81
/****************************************************************************
83
****************************************************************************/
84
unsigned char *get_var_key(user_var_entry *entry, size_t *length, bool )
86
*length= entry->name.length;
87
return (unsigned char*) entry->name.str;
90
void free_user_var(user_var_entry *entry)
95
80
bool Key_part_spec::operator==(const Key_part_spec& other) const
99
84
!strcmp(field_name.str, other.field_name.str);
102
Open_tables_state::Open_tables_state(uint64_t version_arg)
103
:version(version_arg), backups_available(false)
87
Open_tables_state::Open_tables_state(uint64_t version_arg) :
105
reset_open_tables_state();
90
open_tables= temporary_tables= derived_tables= NULL;
91
extra_lock= lock= NULL;
109
95
The following functions form part of the C plugin API
111
extern "C" int mysql_tmpfile(const char *prefix)
97
int mysql_tmpfile(const char *prefix)
113
99
char filename[FN_REFLEN];
114
int fd = internal::create_temp_file(filename, drizzle_tmpdir, prefix, MYF(MY_WME));
100
int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
116
102
unlink(filename);
156
139
return &ha_data[monitored->getId()].resource_context[index];
160
142
int64_t session_test_options(const Session *session, int64_t test_options)
162
144
return session->options & test_options;
166
147
int session_sql_command(const Session *session)
168
149
return (int) session->lex->sql_command;
172
int session_tx_isolation(const Session *session)
152
enum_tx_isolation session_tx_isolation(const Session *session)
174
return (int) session->variables.tx_isolation;
154
return (enum_tx_isolation)session->variables.tx_isolation;
177
Session::Session(plugin::Client *client_arg)
157
Session::Session(plugin::Client *client_arg) :
179
158
Open_tables_state(refresh_version),
180
159
mem_root(&main_mem_root),
183
163
client(client_arg),
185
165
scheduler_arg(NULL),
268
254
/* Initialize sub structures */
269
255
memory::init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
270
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
271
(hash_get_key) get_var_key,
272
(hash_free_key) free_user_var, 0);
274
257
substitute_null_with_insert_id = false;
275
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
258
lock_info.init(); /* safety: will be reset after start */
276
259
thr_lock_owner_init(&main_lock_id, &lock_info);
278
261
m_internal_handler= NULL;
263
plugin::EventObserver::registerSessionEvents(*this);
281
266
void Session::free_items()
310
295
return false; // 'false', as per coding style
298
void Session::setAbort(bool arg)
300
mysys_var->abort= arg;
303
void Session::lockOnSys()
309
boost_unique_lock_t scopedLock(mysys_var->mutex);
310
if (mysys_var->current_cond)
312
mysys_var->current_mutex->lock();
313
mysys_var->current_cond->notify_all();
314
mysys_var->current_mutex->unlock();
313
318
void Session::pop_internal_handler()
315
320
assert(m_internal_handler != NULL);
316
321
m_internal_handler= NULL;
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)
324
void Session::get_xid(DRIZZLE_XID *xid)
326
*xid = *(DRIZZLE_XID *) &transaction.xid_state.xid;
357
329
/* Do operations that may take a long time */
406
389
plugin::StorageEngine::closeConnection(this);
407
390
plugin_sessionvar_cleanup(this);
409
free_root(&warn_root,MYF(0));
392
warn_root.free_root(MYF(0));
410
393
mysys_var=0; // Safety (shouldn't be needed)
411
394
dbug_sentry= Session_SENTRY_GONE;
413
free_root(&main_mem_root, MYF(0));
414
pthread_setspecific(THR_Session, 0);
396
main_mem_root.free_root(MYF(0));
397
currentMemRoot().release();
398
currentSession().release();
416
400
plugin::Logging::postEndDo(this);
401
plugin::EventObserver::deregisterSessionEvents(*this);
403
for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
405
delete (*iter).second;
407
life_properties.clear();
418
409
/* 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(system_status_var *to_var, system_status_var *from_var)
438
ulong *end= (ulong*) ((unsigned char*) to_var +
439
offsetof(system_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(system_status_var *to_var, system_status_var *from_var,
460
system_status_var *dec_var)
462
ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(system_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++);
410
LOCK_delete.unlock();
471
413
void Session::awake(Session::killed_state state_to_set)
604
550
connection_count.increment();
606
if (connection_count > max_used_connections)
607
max_used_connections= connection_count;
552
if (connection_count > current_global_counters.max_used_connections)
554
current_global_counters.max_used_connections= connection_count;
557
current_global_counters.connections++;
609
558
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);
561
boost::mutex::scoped_lock scoped(LOCK_thread_count);
562
getSessionList().push_back(this);
565
if (unlikely(plugin::EventObserver::connectSession(*this)))
567
// We should do something about an error...
570
if (unlikely(plugin::EventObserver::connectSession(*this)))
572
// We should do something about an error...
615
575
if (scheduler->addSession(this))
636
const char* Session::enter_cond(pthread_cond_t *cond,
637
pthread_mutex_t* mutex,
596
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
640
598
const char* old_msg = get_proc_info();
641
599
safe_mutex_assert_owner(mutex);
642
mysys_var->current_mutex = mutex;
643
mysys_var->current_cond = cond;
600
mysys_var->current_mutex = &mutex;
601
mysys_var->current_cond = &cond;
644
602
this->set_proc_info(msg);
653
611
locked (if that would not be the case, you'll get a deadlock if someone
654
612
does a Session::awake() on you).
656
pthread_mutex_unlock(mysys_var->current_mutex);
657
pthread_mutex_lock(&mysys_var->mutex);
614
mysys_var->current_mutex->unlock();
615
boost_unique_lock_t scopedLock(mysys_var->mutex);
658
616
mysys_var->current_mutex = 0;
659
617
mysys_var->current_cond = 0;
660
618
this->set_proc_info(old_msg);
661
pthread_mutex_unlock(&mysys_var->mutex);
664
621
bool Session::authenticate()
667
624
if (client->authenticate())
670
statistic_increment(aborted_connects, &LOCK_status);
627
status_var.aborted_connects++;
674
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
632
bool Session::checkUser(const std::string &passwd_str,
633
const std::string &in_db)
676
const string passwd_str(passwd, passwd_len);
677
635
bool is_authenticated=
678
636
plugin::Authentication::isAuthenticated(getSecurityContext(),
681
639
if (is_authenticated != true)
641
status_var.access_denied++;
683
642
/* isAuthenticated has pushed the error message */
687
646
/* Change database if necessary */
688
if (in_db && in_db[0])
647
if (not in_db.empty())
690
649
SchemaIdentifier identifier(in_db);
691
650
if (mysql_change_db(this, identifier))
1040
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1008
static int create_file(Session *session,
1009
fs::path &target_path,
1010
file_exchange *exchange,
1011
internal::IO_CACHE *cache)
1013
fs::path to_file(exchange->file_name);
1043
uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1045
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
1046
option|= MY_REPLACE_DIR; // Force use of db directory
1049
if (!internal::dirname_length(exchange->file_name))
1016
if (not to_file.has_root_directory())
1051
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);
1018
target_path= fs::system_complete(getDataHomeCatalog());
1019
if (not session->db.empty())
1021
int count_elements= 0;
1022
for (fs::path::iterator iter= to_file.begin();
1023
iter != to_file.end();
1024
++iter, ++count_elements)
1027
if (count_elements == 1)
1029
target_path /= session->db;
1032
target_path /= to_file;
1057
(void) internal::fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1059
if (opt_secure_file_priv &&
1060
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1062
/* Write only allowed to dir or subdir specified by secure_file_priv */
1063
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1067
if (!access(path, F_OK))
1036
target_path = exchange->file_name;
1039
if (not secure_file_priv.string().empty())
1041
if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1043
/* Write only allowed to dir or subdir specified by secure_file_priv */
1044
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1049
if (!access(target_path.file_string().c_str(), F_OK))
1069
1051
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1072
1054
/* Create the file world readable */
1073
if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1055
if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1075
1057
(void) fchmod(file, 0666); // Because of umask()
1076
if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1058
if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1078
1060
internal::my_close(file, MYF(0));
1079
internal::my_delete(path, MYF(0)); // Delete file on error, it was just created
1061
internal::my_delete(target_path.file_string().c_str(), MYF(0)); // Delete file on error, it was just created
1302
1287
for (; length > sizeof(space) ; length-=sizeof(space))
1304
1289
if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1307
1292
if (my_b_write(cache,(unsigned char*) space,length))
1311
1296
if (res && enclosed)
1313
1298
if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1314
1299
exchange->enclosed->length()))
1317
1302
if (--items_left)
1319
1304
if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1320
1305
field_term_length))
1324
1309
if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1325
1310
exchange->line_term->length()))
1592
/****************************************************************************
1593
Handling of open and locked tables states.
1595
This is used when we want to open/lock (and then close) some tables when
1596
we already have a set of tables open and locked. We use these methods for
1597
access to mysql.proc table to find definitions of stored routines.
1598
****************************************************************************/
1600
void Session::reset_n_backup_open_tables_state(Open_tables_state *backup)
1602
backup->set_open_tables_state(this);
1603
reset_open_tables_state();
1604
backups_available= false;
1608
void Session::restore_backup_open_tables_state(Open_tables_state *backup)
1611
Before we will throw away current open tables state we want
1612
to be sure that it was properly cleaned up.
1614
assert(open_tables == 0 && temporary_tables == 0 &&
1615
derived_tables == 0 &&
1617
set_open_tables_state(backup);
1620
1578
bool Session::set_db(const std::string &new_db)
1622
1580
/* Do not reallocate memory if current chunk is big enough. */
1635
Check the killed state of a user thread
1636
@param session user thread
1637
@retval 0 the user thread is active
1638
@retval 1 the user thread has been killed
1640
extern "C" int session_killed(const Session *session)
1642
return(session->killed);
1646
Return the session id of a user session
1647
@param pointer to Session object
1648
@return session's id
1650
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)
1658
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)
1668
mark_transaction_to_rollback(session, all);
1672
1591
Mark transaction to rollback and mark error as fatal to a sub-statement.
1804
1729
void Session::nukeTable(Table *table)
1806
plugin::StorageEngine *table_type= table->s->db_type();
1731
plugin::StorageEngine *table_type= table->getShare()->db_type();
1808
1733
table->free_io_cache();
1809
table->closefrm(false);
1734
table->delete_table();
1811
TableIdentifier identifier(table->s->getSchemaName(), table->s->table_name.str, table->s->path.str);
1736
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1812
1737
rm_temporary_table(table_type, identifier);
1814
table->s->free_table_share();
1739
delete table->getMutableShare();
1816
1741
/* This makes me sad, but we're allocating it via malloc */
1820
1745
/** Clear most status variables. */
1821
1746
extern time_t flush_status_time;
1822
extern uint32_t max_used_connections;
1824
1748
void Session::refresh_status()
1826
pthread_mutex_lock(&LOCK_status);
1828
/* Add thread's status variabes to global status */
1829
add_to_status(&global_status_var, &status_var);
1831
1750
/* Reset thread's status variables */
1832
1751
memset(&status_var, 0, sizeof(status_var));
1834
/* Reset some global variables */
1835
reset_status_vars();
1837
/* Reset the counters of all key caches (default and named). */
1838
reset_key_cache_counters();
1839
1753
flush_status_time= time((time_t*) 0);
1840
max_used_connections= 1; /* We set it to one, because we know we exist */
1841
pthread_mutex_unlock(&LOCK_status);
1754
current_global_counters.max_used_connections= 1; /* We set it to one, because we know we exist */
1755
current_global_counters.connections= 0;
1844
1758
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1760
return getVariable(std::string(name.str, name.length), create_if_not_exists);
1763
user_var_entry *Session::getVariable(const std::string &name, bool create_if_not_exists)
1765
UserVarsRange ppp= user_vars.equal_range(name);
1767
for (UserVars::iterator iter= ppp.first;
1768
iter != ppp.second; ++iter)
1770
return (*iter).second;
1773
if (not create_if_not_exists)
1846
1776
user_var_entry *entry= NULL;
1848
entry= (user_var_entry*) hash_search(&user_vars, (unsigned char*) name.str, name.length);
1850
if ((entry == NULL) && create_if_not_exists)
1777
entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1782
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1784
if (not returnable.second)
1852
if (!hash_inited(&user_vars))
1854
entry= new (nothrow) user_var_entry(name.str, query_id);
1859
if (my_hash_insert(&user_vars, (unsigned char*) entry))
1862
free((char*) entry);
1792
void Session::setVariable(const std::string &name, const std::string &value)
1794
user_var_entry *updateable_var= getVariable(name.c_str(), true);
1796
updateable_var->update_hash(false,
1797
(void*)value.c_str(),
1798
static_cast<uint32_t>(value.length()), STRING_RESULT,
1800
DERIVATION_IMPLICIT, false);
1871
1803
void Session::mark_temp_tables_as_free_for_reuse()
1873
for (Table *table= temporary_tables ; table ; table= table->next)
1805
for (Table *table= temporary_tables ; table ; table= table->getNext())
1875
1807
if (table->query_id == query_id)
1904
1836
void Session::close_thread_tables()
1909
We are assuming here that session->derived_tables contains ONLY derived
1910
tables for this substatement. i.e. instead of approach which uses
1911
query_id matching for determining which of the derived tables belong
1912
to this substatement we rely on the ability of substatements to
1913
save/restore session->derived_tables during their execution.
1915
TODO: Probably even better approach is to simply associate list of
1916
derived tables with (sub-)statement instead of thread and destroy
1917
them at the end of its execution.
1919
1838
if (derived_tables)
1923
Close all derived tables generated in queries like
1924
SELECT * FROM (SELECT * FROM t1)
1926
for (table= derived_tables ; table ; table= next)
1929
table->free_tmp_table(this);
1839
derived_tables= NULL; // They should all be invalid by this point
1935
1842
Mark all temporary tables used by this statement as free for reuse.
1943
1850
does not belong to statement for which we do close_thread_tables()).
1944
1851
TODO: This should be fixed in later releases.
1946
if (backups_available == false)
1948
1854
TransactionServices &transaction_services= TransactionServices::singleton();
1949
1855
main_da.can_overwrite_status= true;
1950
transaction_services.ha_autocommit_or_rollback(this, is_error());
1856
transaction_services.autocommitOrRollback(this, is_error());
1951
1857
main_da.can_overwrite_status= false;
1952
1858
transaction.stmt.reset();
1963
1869
handled either before writing a query log event (inside
1964
1870
binlog_query()) or when preparing a pending event.
1966
mysql_unlock_tables(this, lock);
1970
1876
Note that we need to hold LOCK_open while changing the
1971
1877
open_tables list. Another thread may work on it.
1972
(See: remove_table_from_cache(), mysql_wait_completed_table())
1878
(See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1973
1879
Closing a MERGE child before the parent would be fatal if the
1974
1880
other thread tries to abort the MERGE lock in between.
2008
1914
close_tables_for_reopen(&tables);
2010
1916
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
2011
(fill_derived_tables() &&
2012
1918
mysql_handle_derived(lex, &mysql_derived_filling))))
2018
bool Session::openTables(TableList *tables, uint32_t flags)
2021
bool ret= fill_derived_tables();
2022
assert(ret == false);
2023
if (open_tables_from_list(&tables, &counter, flags) ||
2024
mysql_handle_derived(lex, &mysql_derived_prepare))
1925
@note "best_effort" is used in cases were if a failure occurred on this
1926
operation it would not be surprising because we are only removing because there
1927
might be an issue (lame engines).
2029
bool Session::rm_temporary_table(TableIdentifier &identifier)
1930
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
2031
1932
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()");
1934
if (not best_effort)
1936
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1937
identifier.getSQLPath().c_str(), errno);
2070
1972
cerr << "Begin Run: " << foo << "\n";
2071
for (table= temporary_tables; table; table= table->next)
1973
for (table= temporary_tables; table; table= table->getNext())
2073
1975
bool have_proto= false;
2075
message::Table *proto= table->s->getTableProto();
2076
if (table->s->getTableProto())
1977
message::Table *proto= table->getShare()->getTableProto();
1978
if (table->getShare()->getTableProto())
2077
1979
have_proto= true;
2079
1981
const char *answer= have_proto ? "true" : "false";
2081
1983
if (have_proto)
2083
cerr << "\tTable Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
1985
cerr << "\tTable Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2084
1986
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2087
cerr << "\tTabl;e Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
1989
cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2091
bool Session::storeTableMessage(TableIdentifier &identifier, message::Table &table_message)
1993
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2093
1995
table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2098
bool Session::removeTableMessage(TableIdentifier &identifier)
2000
bool Session::removeTableMessage(const TableIdentifier &identifier)
2100
2002
TableMessageCache::iterator iter;
2061
table::Instance *Session::getInstanceTable()
2063
temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
2065
table::Instance *tmp_share= temporary_shares.back();
2074
Create a reduced Table object with properly set up Field list from a
2075
list of field definitions.
2077
The created table doesn't have a table Cursor associated with
2078
it, has no keys, no group/distinct, no copy_funcs array.
2079
The sole purpose of this Table object is to use the power of Field
2080
class to read/write data to/from table->getInsertRecord(). Then one can store
2081
the record in any container (RB tree, hash, etc).
2082
The table is created in Session mem_root, so are the table's fields.
2083
Consequently, if you don't BLOB fields, you don't need to free it.
2085
@param session connection handle
2086
@param field_list list of column definitions
2089
0 if out of memory, Table object in case of success
2091
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2093
temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2095
table::Instance *tmp_share= temporary_shares.back();
2159
2102
} /* namespace drizzled */