108
int session_tablespace_op(const Session *session)
110
return test(session->tablespace_op);
114
Set the process info field of the Session structure.
116
This function is used by plug-ins. Internally, the
117
Session::set_proc_info() function should be used.
119
@see Session::set_proc_info
121
void set_session_proc_info(Session *session, const char *info)
123
session->set_proc_info(info);
126
const char *get_session_proc_info(Session *session)
128
return session->get_proc_info();
121
131
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
123
133
return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
134
144
return session->options & test_options;
137
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
147
int session_sql_command(const Session *session)
149
return (int) session->lex->sql_command;
152
enum_tx_isolation session_tx_isolation(const Session *session)
154
return (enum_tx_isolation)session->variables.tx_isolation;
157
Session::Session(plugin::Client *client_arg) :
138
158
Open_tables_state(refresh_version),
139
159
mem_root(&main_mem_root),
142
query(new std::string),
143
_schema(new std::string("")),
144
162
client(client_arg),
146
164
scheduler_arg(NULL),
147
165
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
167
ha_data(plugin::num_trx_monitored_objects),
161
concurrent_execute_allowed(true),
162
168
arg_of_last_insert_id_function(false),
163
169
first_successful_insert_id_in_prev_stmt(0),
164
170
first_successful_insert_id_in_cur_stmt(0),
165
171
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
173
some_tables_deleted(false),
181
174
no_errors(false),
183
176
is_fatal_error(false),
184
177
transaction_rollback_request(false),
185
178
is_fatal_sub_stmt_error(0),
179
derived_tables_processing(false),
186
180
tablespace_op(false),
187
derived_tables_processing(false),
190
183
transaction_message(NULL),
191
184
statement_message(NULL),
192
185
session_event_observers(NULL),
193
_catalog(catalog_arg),
188
memset(process_list_info, 0, PROCESS_LIST_WIDTH);
196
189
client->setSession(this);
201
194
will be re-initialized in init_for_queries().
203
196
memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
198
count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
204
203
cuted_fields= sent_row_count= row_count= 0L;
205
statement_id_counter= 0UL;
205
206
// Must be reset to handle error with Session's created for init of mysqld
206
207
lex->current_select= 0;
208
start_time=(time_t) 0;
210
utime_after_lock= 0L;
207
211
memset(&variables, 0, sizeof(variables));
208
217
scoreboard_index= -1;
218
dbug_sentry=Session_SENTRY_MAGIC;
209
219
cleanup_done= abort_on_warning= no_warnings_for_error= false;
211
221
/* query_cache init */
355
367
this->checkSentry();
357
if (client and client->isConnected())
369
if (client->isConnected())
359
assert(security_ctx);
360
371
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());
372
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
374
(getSecurityContext().getUser().c_str() ?
375
getSecurityContext().getUser().c_str() : ""));
376
disconnect(0, false);
371
379
/* Close connection */
375
boost::checked_delete(client);
379
383
if (cleanup_done == false)
393
397
plugin::Logging::postEndDo(this);
394
398
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))
400
for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
402
delete (*iter).second;
404
life_properties.clear();
406
/* Ensure that no one is using Session */
407
LOCK_delete.unlock();
410
void Session::awake(Session::killed_state state_to_set)
408
412
this->checkSentry();
410
setKilled(state_to_set);
411
scheduler->killSession(this);
413
safe_mutex_assert_owner(&LOCK_delete);
415
killed= state_to_set;
413
416
if (state_to_set != Session::KILL_QUERY)
418
scheduler->killSession(this);
415
419
DRIZZLE_CONNECTION_DONE(thread_id);
420
423
boost_unique_lock_t scopedLock(mysys_var->mutex);
522
525
if (initGlobals() || authenticate())
528
531
prepareForQueries();
530
while (not client->haveError() && getKilled() != KILL_CONNECTION)
533
while (! client->haveError() && killed != KILL_CONNECTION)
532
if (not executeStatement())
535
if (! executeStatement())
539
bool Session::schedule(Session::shared_ptr &arg)
542
bool Session::schedule()
541
arg->scheduler= plugin::Scheduler::getScheduler();
542
assert(arg->scheduler);
546
long current_connections= connection_count;
548
if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
544
scheduler= plugin::Scheduler::getScheduler();
547
connection_count.increment();
549
if (connection_count > current_global_counters.max_used_connections)
550
current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
551
current_global_counters.max_used_connections= connection_count;
553
554
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());
555
thread_id= variables.pseudo_thread_id= global_thread_id++;
558
boost::mutex::scoped_lock scoped(LOCK_thread_count);
559
getSessionList().push_back(this);
562
if (unlikely(plugin::EventObserver::connectSession(*this)))
564
// We should do something about an error...
567
if (unlikely(plugin::EventObserver::connectSession(*this)))
569
// We should do something about an error...
572
if (scheduler->addSession(this))
574
DRIZZLE_CONNECTION_START(thread_id);
566
575
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
568
arg->setKilled(Session::KILL_CONNECTION);
577
killed= Session::KILL_CONNECTION;
570
arg->status_var.aborted_connects++;
579
status_var.aborted_connects++;
572
581
/* Can't use my_error() since store_globals has not been called. */
573
582
/* TODO replace will better error message */
574
583
snprintf(error_message_buff, sizeof(error_message_buff),
575
584
ER(ER_CANT_CREATE_THREAD), 1);
576
arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
585
client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
672
673
main_da.reset_diagnostics_area();
674
675
if (client->readCommand(&l_packet, &packet_length) == false)
679
if (getKilled() == KILL_CONNECTION)
678
if (killed == KILL_CONNECTION)
682
681
if (packet_length == 0)
685
l_command= static_cast<enum_server_command>(l_packet[0]);
684
l_command= (enum enum_server_command) (unsigned char) l_packet[0];
687
686
if (command >= COM_END)
688
687
command= COM_END; // Wrong command
690
689
assert(packet_length);
691
return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
690
return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
694
693
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
700
699
in_packet_length--;
702
701
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])))
702
while (in_packet_length > 0 &&
703
(pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
706
706
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));
709
query.assign(in_packet, in_packet + in_packet_length);
926
917
Handling writing to file
927
918
************************************************************************/
929
void select_to_file::send_error(drizzled::error_t errcode,const char *err)
920
void select_to_file::send_error(uint32_t errcode,const char *err)
931
922
my_message(errcode, err, MYF(0));
934
(void) cache->end_io_cache();
925
(void) end_io_cache(cache);
935
926
(void) internal::my_close(file, MYF(0));
936
927
(void) internal::my_delete(path.file_string().c_str(), MYF(0)); // Delete file on error
1062
1052
if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1064
1054
(void) fchmod(file, 0666); // Because of umask()
1065
if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1055
if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1067
1057
internal::my_close(file, MYF(0));
1068
1058
internal::my_delete(target_path.file_string().c_str(), MYF(0)); // Delete file on error, it was just created
1480
1469
bool select_max_min_finder_subselect::cmp_decimal()
1482
1471
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);
1472
my_decimal cval, *cvalue= cache->val_decimal(&cval);
1473
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1486
1475
return (cache->null_value && !maxmin->null_value) ||
1487
1476
(!cache->null_value && !maxmin->null_value &&
1488
class_decimal_cmp(cvalue, mvalue) > 0) ;
1477
my_decimal_cmp(cvalue, mvalue) > 0) ;
1489
1478
return (maxmin->null_value && !cache->null_value) ||
1490
1479
(!cache->null_value && !maxmin->null_value &&
1491
class_decimal_cmp(cvalue,mvalue) < 0);
1480
my_decimal_cmp(cvalue,mvalue) < 0);
1494
1483
bool select_max_min_finder_subselect::cmp_str()
1530
1519
void Session::end_statement()
1532
1521
/* Cleanup SQL processing state to reuse this statement in next query. */
1534
1523
query_cache_key= ""; // reset the cache key
1535
1524
resetResultsetMessage();
1538
1527
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1541
if (_schema and _schema->empty())
1543
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1546
else if (not _schema)
1548
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1553
*p_db= strmake(_schema->c_str(), _schema->size());
1554
*p_db_length= _schema->size();
1531
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1534
*p_db= strmake(db.c_str(), db.length());
1535
*p_db_length= db.length();
1595
void Session::set_db(const std::string &new_db)
1575
bool Session::set_db(const std::string &new_db)
1597
1577
/* Do not reallocate memory if current chunk is big enough. */
1598
1578
if (new_db.length())
1600
_schema.reset(new std::string(new_db));
1604
_schema.reset(new std::string(""));
1590
Check the killed state of a user thread
1591
@param session user thread
1592
@retval 0 the user thread is active
1593
@retval 1 the user thread has been killed
1595
int session_killed(const Session *session)
1597
return(session->killed);
1601
const struct charset_info_st *session_charset(Session *session)
1603
return(session->charset());
1610
1607
Mark transaction to rollback and mark error as fatal to a sub-statement.
1612
1609
@param session Thread handle
1613
1610
@param all true <=> rollback main transaction.
1615
void Session::markTransactionForRollback(bool all)
1612
void mark_transaction_to_rollback(Session *session, bool all)
1617
is_fatal_sub_stmt_error= true;
1618
transaction_rollback_request= all;
1616
session->is_fatal_sub_stmt_error= true;
1617
session->transaction_rollback_request= all;
1621
void Session::disconnect(enum error_t errcode)
1621
void Session::disconnect(uint32_t errcode, bool should_lock)
1623
1623
/* Allow any plugins to cleanup their session variables */
1624
1624
plugin_sessionvar_cleanup(this);
1626
1626
/* If necessary, log any aborted or unauthorized connections */
1627
if (getKilled() || client->wasAborted())
1627
if (killed || client->wasAborted())
1629
1629
status_var.aborted_threads++;
1632
1632
if (client->wasAborted())
1634
if (not getKilled() && variables.log_warnings > 1)
1634
if (! killed && variables.log_warnings > 1)
1636
errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
1636
SecurityContext *sctx= &security_ctx;
1638
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()
1640
, (db.empty() ? "unconnected" : db.c_str())
1641
, sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1642
, sctx->getIp().c_str()
1641
1643
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1645
setKilled(Session::KILL_CONNECTION);
1647
/* Close out our connection to the client */
1649
LOCK_thread_count.lock();
1650
killed= Session::KILL_CONNECTION;
1647
1651
if (client->isConnected())
1649
if (errcode != EE_OK)
1651
1655
/*my_error(errcode, ER(errcode));*/
1652
1656
client->sendError(errcode, ER(errcode));
1654
1658
client->close();
1661
(void) LOCK_thread_count.unlock();
1658
1664
void Session::reset_for_next_command()
1736
1742
If this is needed, use close_temporary_table()
1739
void Open_tables_state::nukeTable(Table *table)
1745
void Session::nukeTable(Table *table)
1741
1747
plugin::StorageEngine *table_type= table->getShare()->db_type();
1743
1749
table->free_io_cache();
1744
1750
table->delete_table();
1746
identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1752
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1747
1753
rm_temporary_table(table_type, identifier);
1749
boost::checked_delete(table->getMutableShare());
1755
delete table->getMutableShare();
1751
boost::checked_delete(table);
1757
/* This makes me sad, but we're allocating it via malloc */
1754
1761
/** Clear most status variables. */
1800
1808
void Session::setVariable(const std::string &name, const std::string &value)
1802
1810
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);
1812
updateable_var->update_hash(false,
1813
(void*)value.c_str(),
1814
static_cast<uint32_t>(value.length()), STRING_RESULT,
1816
DERIVATION_IMPLICIT, false);
1813
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1819
void Session::mark_temp_tables_as_free_for_reuse()
1815
1821
for (Table *table= temporary_tables ; table ; table= table->getNext())
1817
if (table->query_id == getQueryId())
1823
if (table->query_id == query_id)
1819
1825
table->query_id= 0;
1820
1826
table->cursor->ha_reset();
1878
1885
handled either before writing a query log event (inside
1879
1886
binlog_query()) or when preparing a pending event.
1888
mysql_unlock_tables(this, lock);
1885
Note that we need to hold table::Cache::singleton().mutex() while changing the
1892
Note that we need to hold LOCK_open while changing the
1886
1893
open_tables list. Another thread may work on it.
1887
(See: table::Cache::singleton().removeTable(), wait_completed_table())
1894
(See: remove_table_from_cache(), mysql_wait_completed_table())
1888
1895
Closing a MERGE child before the parent would be fatal if the
1889
1896
other thread tries to abort the MERGE lock in between.
1937
1943
might be an issue (lame engines).
1940
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
1946
bool Session::rm_temporary_table(TableIdentifier &identifier, bool best_effort)
1942
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1948
if (plugin::StorageEngine::dropTable(*this, identifier))
1944
1950
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);
1952
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1953
identifier.getSQLPath().c_str(), errno);
1958
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
1962
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
1960
drizzled::error_t error;
1963
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
1966
if (plugin::StorageEngine::dropTable(*this, *base, identifier))
1966
identifier.getSQLPath(path);
1967
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1968
path.c_str(), error);
1968
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1969
identifier.getSQLPath().c_str(), errno);
2001
2002
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2005
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 */
2009
bool Session::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2011
table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2016
bool Session::removeTableMessage(const TableIdentifier &identifier)
2018
TableMessageCache::iterator iter;
2020
iter= table_message_cache.find(identifier.getPath());
2022
if (iter == table_message_cache.end())
2025
table_message_cache.erase(iter);
2030
bool Session::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2032
TableMessageCache::iterator iter;
2034
iter= table_message_cache.find(identifier.getPath());
2036
if (iter == table_message_cache.end())
2039
table_message.CopyFrom(((*iter).second));
2044
bool Session::doesTableMessageExist(const TableIdentifier &identifier)
2046
TableMessageCache::iterator iter;
2048
iter= table_message_cache.find(identifier.getPath());
2050
if (iter == table_message_cache.end())
2058
bool Session::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2060
TableMessageCache::iterator iter;
2062
table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2064
iter= table_message_cache.find(to.getPath());
2066
if (iter == table_message_cache.end())
2071
(*iter).second.set_schema(to.getSchemaName());
2072
(*iter).second.set_name(to.getTableName());
2077
table::Instance *Session::getInstanceTable()
2079
temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
2081
table::Instance *tmp_share= temporary_shares.back();
2077
2088
} /* namespace drizzled */