24
24
#include "config.h"
25
#include "drizzled/session.h"
26
#include "drizzled/session/cache.h"
25
#include <drizzled/session.h>
26
#include "drizzled/session_list.h"
27
27
#include <sys/stat.h>
28
#include "drizzled/error.h"
29
#include "drizzled/gettext.h"
30
#include "drizzled/query_id.h"
31
#include "drizzled/data_home.h"
32
#include "drizzled/sql_base.h"
33
#include "drizzled/lock.h"
34
#include "drizzled/item/cache.h"
35
#include "drizzled/item/float.h"
36
#include "drizzled/item/return_int.h"
37
#include "drizzled/item/empty_string.h"
38
#include "drizzled/show.h"
39
#include "drizzled/plugin/client.h"
28
#include <drizzled/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"
43
43
#include "drizzled/plugin/transactional_storage_engine.h"
44
#include "drizzled/plugin/query_rewrite.h"
45
44
#include "drizzled/probes.h"
46
45
#include "drizzled/table_proto.h"
47
46
#include "drizzled/db.h"
49
48
#include "drizzled/transaction_services.h"
50
49
#include "drizzled/drizzled.h"
52
#include "drizzled/identifier.h"
54
#include "drizzled/table/instance.h"
51
#include "drizzled/table_share_instance.h"
56
53
#include "plugin/myisam/myisam.h"
57
54
#include "drizzled/internal/iocache.h"
58
55
#include "drizzled/internal/thread_var.h"
59
56
#include "drizzled/plugin/event_observer.h"
61
#include "drizzled/util/functors.h"
63
#include "drizzled/display.h"
66
59
#include <algorithm>
68
#include <boost/filesystem.hpp>
70
#include "drizzled/util/backtrace.h"
72
62
using namespace std;
74
namespace fs=boost::filesystem;
83
71
char empty_c_string[1]= {0}; /* used for not defined db */
85
73
const char * const Session::DEFAULT_WHERE= "field list";
74
extern pthread_key_t THR_Session;
75
extern pthread_key_t THR_Mem_root;
87
77
bool Key_part_spec::operator==(const Key_part_spec& other) const
89
79
return length == other.length &&
90
80
field_name.length == other.field_name.length &&
91
!my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
81
!strcmp(field_name.str, other.field_name.str);
94
84
Open_tables_state::Open_tables_state(uint64_t version_arg) :
164
154
Session::Session(plugin::Client *client_arg) :
165
155
Open_tables_state(refresh_version),
166
156
mem_root(&main_mem_root),
169
query(new std::string),
170
_schema(new std::string("")),
172
159
client(client_arg),
174
161
scheduler_arg(NULL),
175
162
lock_id(&main_lock_id),
177
security_ctx(identifier::User::make_shared()),
179
164
ha_data(plugin::num_trx_monitored_objects),
180
concurrent_execute_allowed(true),
181
165
arg_of_last_insert_id_function(false),
182
166
first_successful_insert_id_in_prev_stmt(0),
183
167
first_successful_insert_id_in_cur_stmt(0),
184
168
limit_found_rows(0),
185
_global_read_lock(NONE),
187
170
some_tables_deleted(false),
188
171
no_errors(false),
319
boost_unique_lock_t scopedLock(mysys_var->mutex);
304
pthread_mutex_lock(&mysys_var->mutex);
320
305
if (mysys_var->current_cond)
322
mysys_var->current_mutex->lock();
323
mysys_var->current_cond->notify_all();
324
mysys_var->current_mutex->unlock();
307
pthread_mutex_lock(mysys_var->current_mutex);
308
pthread_cond_broadcast(mysys_var->current_cond);
309
pthread_mutex_unlock(mysys_var->current_mutex);
311
pthread_mutex_unlock(&mysys_var->mutex);
328
314
void Session::pop_internal_handler()
382
366
if (client->isConnected())
384
assert(security_ctx);
385
368
if (global_system_variables.log_warnings)
387
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),
388
internal::my_progname,
390
security_ctx->username().c_str());
369
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
371
(getSecurityContext().getUser().c_str() ?
372
getSecurityContext().getUser().c_str() : ""));
393
373
disconnect(0, false);
408
388
dbug_sentry= Session_SENTRY_GONE;
410
390
main_mem_root.free_root(MYF(0));
411
currentMemRoot().release();
412
currentSession().release();
391
pthread_setspecific(THR_Session, 0);
414
393
plugin::Logging::postEndDo(this);
415
394
plugin::EventObserver::deregisterSessionEvents(*this);
417
for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
419
delete (*iter).second;
421
life_properties.clear();
424
void Session::setClient(plugin::Client *client_arg)
427
client->setSession(this);
430
void Session::awake(Session::killed_state_t state_to_set)
432
if ((state_to_set == Session::KILL_QUERY) and (command == COM_SLEEP))
396
/* Ensure that no one is using Session */
397
LOCK_delete.unlock();
400
void Session::awake(Session::killed_state state_to_set)
435
402
this->checkSentry();
437
setKilled(state_to_set);
438
scheduler->killSession(this);
403
safe_mutex_assert_owner(&LOCK_delete);
405
killed= state_to_set;
440
406
if (state_to_set != Session::KILL_QUERY)
408
scheduler->killSession(this);
442
409
DRIZZLE_CONNECTION_DONE(thread_id);
447
boost_unique_lock_t scopedLock(mysys_var->mutex);
413
pthread_mutex_lock(&mysys_var->mutex);
450
415
This broadcast could be up in the air if the victim thread
451
416
exits the cond in the time between read and broadcast, but that is
452
417
ok since all we want to do is to make the victim thread get out
578
541
current_global_counters.connections++;
579
arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
581
session::Cache::singleton().insert(arg);
583
if (unlikely(plugin::EventObserver::connectSession(*arg)))
585
// We should do something about an error...
588
if (plugin::Scheduler::getScheduler()->addSession(arg))
590
DRIZZLE_CONNECTION_START(arg->getSessionId());
542
thread_id= variables.pseudo_thread_id= global_thread_id++;
544
LOCK_thread_count.lock();
545
getSessionList().push_back(this);
546
LOCK_thread_count.unlock();
548
if (scheduler->addSession(this))
550
DRIZZLE_CONNECTION_START(thread_id);
591
551
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
593
arg->setKilled(Session::KILL_CONNECTION);
553
killed= Session::KILL_CONNECTION;
595
arg->status_var.aborted_connects++;
555
status_var.aborted_connects++;
597
557
/* Can't use my_error() since store_globals has not been called. */
598
558
/* TODO replace will better error message */
599
559
snprintf(error_message_buff, sizeof(error_message_buff),
600
560
ER(ER_CANT_CREATE_THREAD), 1);
601
arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
561
client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
611
Is this session viewable by the current user?
613
bool Session::isViewable() const
615
return plugin::Authorization::isAuthorized(current_session->user(),
621
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
569
const char* Session::enter_cond(boost::condition_variable &cond, boost::mutex &mutex, const char* msg)
623
571
const char* old_msg = get_proc_info();
624
572
safe_mutex_assert_owner(mutex);
625
mysys_var->current_mutex = &mutex;
626
mysys_var->current_cond = &cond;
573
mysys_var->current_mutex = mutex.native_handle();
574
mysys_var->current_cond = cond.native_handle();
627
575
this->set_proc_info(msg);
636
584
locked (if that would not be the case, you'll get a deadlock if someone
637
585
does a Session::awake() on you).
639
mysys_var->current_mutex->unlock();
640
boost_unique_lock_t scopedLock(mysys_var->mutex);
587
pthread_mutex_unlock(mysys_var->current_mutex);
588
pthread_mutex_lock(&mysys_var->mutex);
641
589
mysys_var->current_mutex = 0;
642
590
mysys_var->current_cond = 0;
643
591
this->set_proc_info(old_msg);
592
pthread_mutex_unlock(&mysys_var->mutex);
646
595
bool Session::authenticate()
649
598
if (client->authenticate())
657
bool Session::checkUser(const std::string &passwd_str,
658
const std::string &in_db)
606
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
608
const string passwd_str(passwd, passwd_len);
660
609
bool is_authenticated=
661
plugin::Authentication::isAuthenticated(user(), passwd_str);
610
plugin::Authentication::isAuthenticated(getSecurityContext(),
663
613
if (is_authenticated != true)
700
650
main_da.reset_diagnostics_area();
702
652
if (client->readCommand(&l_packet, &packet_length) == false)
707
if (getKilled() == KILL_CONNECTION)
655
if (killed == KILL_CONNECTION)
710
658
if (packet_length == 0)
713
l_command= static_cast<enum_server_command>(l_packet[0]);
661
l_command= (enum enum_server_command) (unsigned char) l_packet[0];
715
663
if (command >= COM_END)
716
664
command= COM_END; // Wrong command
718
666
assert(packet_length);
719
return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
667
return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
722
670
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
728
676
in_packet_length--;
730
678
const char *pos= in_packet + in_packet_length; /* Point at end null */
731
while (in_packet_length > 0 && (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
679
while (in_packet_length > 0 &&
680
(pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
734
683
in_packet_length--;
737
std::string *new_query= new std::string(in_packet, in_packet + in_packet_length);
738
// We can not be entirely sure _schema has a value
741
plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
743
query.reset(new_query);
744
_state.reset(new State(in_packet, in_packet_length));
686
query.assign(in_packet, in_packet + in_packet_length);
1044
static int create_file(Session *session,
1045
fs::path &target_path,
1046
file_exchange *exchange,
1047
internal::IO_CACHE *cache)
984
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1049
fs::path to_file(exchange->file_name);
1052
if (not to_file.has_root_directory())
987
uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
989
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
990
option|= MY_REPLACE_DIR; // Force use of db directory
993
if (!internal::dirname_length(exchange->file_name))
1054
target_path= fs::system_complete(getDataHomeCatalog());
1055
util::string::const_shared_ptr schema(session->schema());
1056
if (schema and not schema->empty())
1058
int count_elements= 0;
1059
for (fs::path::iterator iter= to_file.begin();
1060
iter != to_file.end();
1061
++iter, ++count_elements)
1064
if (count_elements == 1)
1066
target_path /= *schema;
1069
target_path /= to_file;
995
strcpy(path, data_home_real);
996
if (! session->db.empty())
997
strncat(path, session->db.c_str(), FN_REFLEN-strlen(data_home_real)-1);
998
(void) internal::fn_format(path, exchange->file_name, path, "", option);
1073
target_path = exchange->file_name;
1076
if (not secure_file_priv.string().empty())
1078
if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1080
/* Write only allowed to dir or subdir specified by secure_file_priv */
1081
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1086
if (!access(target_path.file_string().c_str(), F_OK))
1001
(void) internal::fn_format(path, exchange->file_name, data_home_real, "", option);
1003
if (opt_secure_file_priv &&
1004
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1006
/* Write only allowed to dir or subdir specified by secure_file_priv */
1007
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1011
if (!access(path, F_OK))
1088
1013
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1091
1016
/* Create the file world readable */
1092
if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1017
if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1094
1019
(void) fchmod(file, 0666); // Because of umask()
1095
if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1020
if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1097
1022
internal::my_close(file, MYF(0));
1098
internal::my_delete(target_path.file_string().c_str(), MYF(0)); // Delete file on error, it was just created
1023
internal::my_delete(path, MYF(0)); // Delete file on error, it was just created
1325
1246
for (; length > sizeof(space) ; length-=sizeof(space))
1327
1248
if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1330
1251
if (my_b_write(cache,(unsigned char*) space,length))
1334
1255
if (res && enclosed)
1336
1257
if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1337
1258
exchange->enclosed->length()))
1340
1261
if (--items_left)
1342
1263
if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1343
1264
field_term_length))
1347
1268
if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1348
1269
exchange->line_term->length()))
1457
1379
switch (val_item->result_type())
1459
1381
case REAL_RESULT:
1460
op= &select_max_min_finder_subselect::cmp_real;
1382
op= &select_max_min_finder_subselect::cmp_real;
1462
1384
case INT_RESULT:
1463
op= &select_max_min_finder_subselect::cmp_int;
1385
op= &select_max_min_finder_subselect::cmp_int;
1465
1387
case STRING_RESULT:
1466
op= &select_max_min_finder_subselect::cmp_str;
1388
op= &select_max_min_finder_subselect::cmp_str;
1468
1390
case DECIMAL_RESULT:
1469
1391
op= &select_max_min_finder_subselect::cmp_decimal;
1471
1393
case ROW_RESULT:
1472
1394
// This case should never be choosen
1477
1399
cache->store(val_item);
1560
1482
void Session::end_statement()
1562
1484
/* Cleanup SQL processing state to reuse this statement in next query. */
1564
1486
query_cache_key= ""; // reset the cache key
1565
1487
resetResultsetMessage();
1568
1490
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1571
if (_schema and _schema->empty())
1573
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1576
else if (not _schema)
1578
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1583
*p_db= strmake(_schema->c_str(), _schema->size());
1584
*p_db_length= _schema->size();
1494
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1497
*p_db= strmake(db.c_str(), db.length());
1498
*p_db_length= db.length();
1625
void Session::set_db(const std::string &new_db)
1538
bool Session::set_db(const std::string &new_db)
1627
1540
/* Do not reallocate memory if current chunk is big enough. */
1628
1541
if (new_db.length())
1630
_schema.reset(new std::string(new_db));
1634
_schema.reset(new std::string(""));
1553
Check the killed state of a user thread
1554
@param session user thread
1555
@retval 0 the user thread is active
1556
@retval 1 the user thread has been killed
1558
int session_killed(const Session *session)
1560
return(session->killed);
1564
const struct charset_info_st *session_charset(Session *session)
1566
return(session->charset());
1640
1570
Mark transaction to rollback and mark error as fatal to a sub-statement.
1657
1587
plugin_sessionvar_cleanup(this);
1659
1589
/* If necessary, log any aborted or unauthorized connections */
1660
if (getKilled() || client->wasAborted())
1590
if (killed || client->wasAborted())
1662
1592
status_var.aborted_threads++;
1665
1595
if (client->wasAborted())
1667
if (not getKilled() && variables.log_warnings > 1)
1597
if (! killed && variables.log_warnings > 1)
1599
SecurityContext *sctx= &security_ctx;
1669
1601
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1671
, (_schema->empty() ? "unconnected" : _schema->c_str())
1672
, security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
1673
, security_ctx->address().c_str()
1603
, (db.empty() ? "unconnected" : db.c_str())
1604
, sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1605
, sctx->getIp().c_str()
1674
1606
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1678
1610
/* Close out our connection to the client */
1679
1611
if (should_lock)
1680
session::Cache::singleton().mutex().lock();
1682
setKilled(Session::KILL_CONNECTION);
1612
LOCK_thread_count.lock();
1613
killed= Session::KILL_CONNECTION;
1684
1614
if (client->isConnected())
1810
1737
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1812
return getVariable(std::string(name.str, name.length), create_if_not_exists);
1815
user_var_entry *Session::getVariable(const std::string &name, bool create_if_not_exists)
1817
UserVarsRange ppp= user_vars.equal_range(name);
1739
user_var_entry *entry= NULL;
1740
UserVarsRange ppp= user_vars.equal_range(std::string(name.str, name.length));
1819
1742
for (UserVars::iterator iter= ppp.first;
1820
iter != ppp.second; ++iter)
1743
iter != ppp.second; ++iter)
1822
return (*iter).second;
1745
entry= (*iter).second;
1825
if (not create_if_not_exists)
1828
user_var_entry *entry= NULL;
1829
entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1834
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1836
if (not returnable.second)
1748
if ((entry == NULL) && create_if_not_exists)
1750
entry= new (nothrow) user_var_entry(name.str, query_id);
1755
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(std::string(name.str, name.length), entry));
1757
if (not returnable.second)
1844
void Session::setVariable(const std::string &name, const std::string &value)
1846
user_var_entry *updateable_var= getVariable(name.c_str(), true);
1848
updateable_var->update_hash(false,
1849
(void*)value.c_str(),
1850
static_cast<uint32_t>(value.length()), STRING_RESULT,
1852
DERIVATION_IMPLICIT, false);
1855
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1767
void Session::mark_temp_tables_as_free_for_reuse()
1857
1769
for (Table *table= temporary_tables ; table ; table= table->getNext())
1859
if (table->query_id == getQueryId())
1771
if (table->query_id == query_id)
1861
1773
table->query_id= 0;
1862
1774
table->cursor->ha_reset();
1920
1833
handled either before writing a query log event (inside
1921
1834
binlog_query()) or when preparing a pending event.
1836
mysql_unlock_tables(this, lock);
1927
Note that we need to hold table::Cache::singleton().mutex() while changing the
1840
Note that we need to hold LOCK_open while changing the
1928
1841
open_tables list. Another thread may work on it.
1929
(See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1842
(See: remove_table_from_cache(), mysql_wait_completed_table())
1930
1843
Closing a MERGE child before the parent would be fatal if the
1931
1844
other thread tries to abort the MERGE lock in between.
1965
1878
close_tables_for_reopen(&tables);
1967
1880
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1881
(fill_derived_tables() &&
1969
1882
mysql_handle_derived(lex, &mysql_derived_filling))))
1888
bool Session::openTables(TableList *tables, uint32_t flags)
1891
bool ret= fill_derived_tables();
1892
assert(ret == false);
1893
if (open_tables_from_list(&tables, &counter, flags) ||
1894
mysql_handle_derived(lex, &mysql_derived_prepare))
1976
1902
@note "best_effort" is used in cases were if a failure occurred on this
1977
1903
operation it would not be surprising because we are only removing because there
1978
1904
might be an issue (lame engines).
1981
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
1907
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1983
if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1909
if (plugin::StorageEngine::dropTable(*this, identifier))
1985
1911
if (not best_effort)
1988
identifier.getSQLPath(path);
1989
1913
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1990
path.c_str(), errno);
1914
identifier.getSQLPath().c_str(), errno);
1999
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
1923
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
2003
if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
1927
if (plugin::StorageEngine::dropTable(*this, *base, identifier))
2006
identifier.getSQLPath(path);
2007
1929
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2008
path.c_str(), errno);
1930
identifier.getSQLPath().c_str(), errno);
2041
1963
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2045
1966
cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2050
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
1970
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2052
1972
table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2057
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
1977
bool Session::removeTableMessage(const TableIdentifier &identifier)
2059
1979
TableMessageCache::iterator iter;
2118
table::Instance *Session::getInstanceTable()
2120
temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
2122
table::Instance *tmp_share= temporary_shares.back();
2131
Create a reduced Table object with properly set up Field list from a
2132
list of field definitions.
2134
The created table doesn't have a table Cursor associated with
2135
it, has no keys, no group/distinct, no copy_funcs array.
2136
The sole purpose of this Table object is to use the power of Field
2137
class to read/write data to/from table->getInsertRecord(). Then one can store
2138
the record in any container (RB tree, hash, etc).
2139
The table is created in Session mem_root, so are the table's fields.
2140
Consequently, if you don't BLOB fields, you don't need to free it.
2142
@param session connection handle
2143
@param field_list list of column definitions
2146
0 if out of memory, Table object in case of success
2148
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2150
temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2152
table::Instance *tmp_share= temporary_shares.back();
2161
static const std::string NONE= "NONE";
2162
static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
2163
static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
2165
const std::string &type(drizzled::Session::global_read_lock_t type)
2171
case Session::GOT_GLOBAL_READ_LOCK:
2172
return GOT_GLOBAL_READ_LOCK;
2173
case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
2174
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
2178
size_t max_string_length(drizzled::Session::global_read_lock_t)
2180
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT.size();
2183
} /* namespace display */
2038
TableShareInstance *Session::getTemporaryShare(TableIdentifier::Type type_arg)
2040
temporary_shares.push_back(new TableShareInstance(type_arg)); // This will not go into the tableshare cache, so no key is used.
2042
TableShareInstance *tmp_share= temporary_shares.back();
2185
2049
} /* namespace drizzled */