24
24
#include "config.h"
26
#include <drizzled/copy_field.h>
27
25
#include "drizzled/session.h"
28
26
#include "drizzled/session/cache.h"
29
28
#include "drizzled/error.h"
30
29
#include "drizzled/gettext.h"
31
30
#include "drizzled/query_id.h"
53
52
#include "drizzled/identifier.h"
55
#include <drizzled/refresh_version.h>
57
#include "drizzled/table/singular.h"
54
#include "drizzled/table/instance.h"
59
56
#include "plugin/myisam/myisam.h"
60
57
#include "drizzled/internal/iocache.h"
108
102
The following functions form part of the C plugin API
110
int tmpfile(const char *prefix)
104
int mysql_tmpfile(const char *prefix)
112
106
char filename[FN_REFLEN];
113
107
int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
115
int session_tablespace_op(const Session *session)
117
return test(session->tablespace_op);
121
Set the process info field of the Session structure.
123
This function is used by plug-ins. Internally, the
124
Session::set_proc_info() function should be used.
126
@see Session::set_proc_info
128
void set_session_proc_info(Session *session, const char *info)
130
session->set_proc_info(info);
133
const char *get_session_proc_info(Session *session)
135
return session->get_proc_info();
121
138
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
123
140
return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
134
151
return session->options & test_options;
137
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
154
int session_sql_command(const Session *session)
156
return (int) session->lex->sql_command;
159
enum_tx_isolation session_tx_isolation(const Session *session)
161
return (enum_tx_isolation)session->variables.tx_isolation;
164
Session::Session(plugin::Client *client_arg) :
138
165
Open_tables_state(refresh_version),
139
166
mem_root(&main_mem_root),
142
169
query(new std::string),
143
170
_schema(new std::string("")),
144
172
client(client_arg),
146
174
scheduler_arg(NULL),
147
175
lock_id(&main_lock_id),
148
176
thread_stack(NULL),
149
177
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
179
ha_data(plugin::num_trx_monitored_objects),
161
180
concurrent_execute_allowed(true),
162
181
arg_of_last_insert_id_function(false),
163
182
first_successful_insert_id_in_prev_stmt(0),
164
183
first_successful_insert_id_in_cur_stmt(0),
165
184
limit_found_rows(0),
166
options(session_startup_options),
169
examined_row_count(0),
173
statement_id_counter(0),
177
185
_global_read_lock(NONE),
178
count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
179
186
_killed(NOT_KILLED),
180
187
some_tables_deleted(false),
181
188
no_errors(false),
183
190
is_fatal_error(false),
184
191
transaction_rollback_request(false),
185
192
is_fatal_sub_stmt_error(0),
193
derived_tables_processing(false),
186
194
tablespace_op(false),
187
derived_tables_processing(false),
190
197
transaction_message(NULL),
191
198
statement_message(NULL),
192
199
session_event_observers(NULL),
193
_catalog(catalog_arg),
196
202
client->setSession(this);
201
207
will be re-initialized in init_for_queries().
203
209
memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
210
count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
204
214
cuted_fields= sent_row_count= row_count= 0L;
216
statement_id_counter= 0UL;
205
217
// Must be reset to handle error with Session's created for init of mysqld
206
218
lex->current_select= 0;
219
start_time=(time_t) 0;
221
utime_after_lock= 0L;
207
222
memset(&variables, 0, sizeof(variables));
208
228
scoreboard_index= -1;
229
dbug_sentry=Session_SENTRY_MAGIC;
209
230
cleanup_done= abort_on_warning= no_warnings_for_error= false;
211
232
/* query_cache init */
224
247
variables.pseudo_thread_id= thread_id;
225
248
server_status= SERVER_STATUS_AUTOCOMMIT;
249
options= session_startup_options;
227
251
if (variables.max_join_size == HA_POS_ERROR)
228
252
options |= OPTION_BIG_SELECTS;
234
258
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
235
259
warn_list.empty();
236
260
memset(warn_count, 0, sizeof(warn_count));
237
262
memset(&status_var, 0, sizeof(status_var));
239
264
/* Initialize sub structures */
269
294
m_internal_handler= handler;
272
bool Session::handle_error(drizzled::error_t sql_errno, const char *message,
273
DRIZZLE_ERROR::enum_warning_level level)
297
bool Session::handle_error(uint32_t sql_errno, const char *message,
298
DRIZZLE_ERROR::enum_warning_level level)
275
300
if (m_internal_handler)
328
353
TransactionServices &transaction_services= TransactionServices::singleton();
329
transaction_services.rollbackTransaction(*this, true);
354
transaction_services.rollbackTransaction(this, true);
330
355
xid_cache_delete(&transaction.xid_state);
355
380
this->checkSentry();
357
if (client and client->isConnected())
382
if (client->isConnected())
359
384
assert(security_ctx);
360
385
if (global_system_variables.log_warnings)
362
errmsg_printf(error::WARN, ER(ER_FORCING_CLOSE),
387
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),
363
388
internal::my_progname,
365
390
security_ctx->username().c_str());
393
disconnect(0, false);
371
396
/* Close connection */
375
boost::checked_delete(client);
379
400
if (cleanup_done == false)
393
414
plugin::Logging::postEndDo(this);
394
415
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();
397
424
void Session::setClient(plugin::Client *client_arg)
541
568
arg->scheduler= plugin::Scheduler::getScheduler();
542
569
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)
571
connection_count.increment();
573
if (connection_count > current_global_counters.max_used_connections)
550
current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
575
current_global_counters.max_used_connections= connection_count;
553
578
current_global_counters.connections++;
586
611
Is this session viewable by the current user?
588
bool Session::isViewable(identifier::User::const_reference user_arg) const
613
bool Session::isViewable() const
590
return plugin::Authorization::isAuthorized(user_arg, this, false);
615
return plugin::Authorization::isAuthorized(current_session->user(),
642
670
/* Change database if necessary */
643
671
if (not in_db.empty())
645
identifier::Schema identifier(in_db);
646
if (change_db(this, identifier))
673
SchemaIdentifier identifier(in_db);
674
if (mysql_change_db(this, identifier))
648
/* change_db() has pushed the error message. */
676
/* mysql_change_db() has pushed the error message. */
713
741
plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
715
743
query.reset(new_query);
716
_state.reset(new session::State(in_packet, in_packet_length));
744
_state.reset(new State(in_packet, in_packet_length));
738
766
* (Which of course should never happen...)
740
768
server_status&= ~SERVER_STATUS_IN_TRANS;
741
if (transaction_services.commitTransaction(*this, true))
769
if (transaction_services.commitTransaction(this, true))
743
771
options&= ~(OPTION_BEGIN);
755
783
case ROLLBACK_AND_CHAIN:
757
785
server_status&= ~SERVER_STATUS_IN_TRANS;
758
if (transaction_services.rollbackTransaction(*this, true))
786
if (transaction_services.rollbackTransaction(this, true))
760
788
options&= ~(OPTION_BEGIN);
761
789
if (result == true && (completion == ROLLBACK_AND_CHAIN))
792
820
if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
794
822
server_status&= ~SERVER_STATUS_IN_TRANS;
795
if (transaction_services.commitTransaction(*this, true))
823
if (transaction_services.commitTransaction(this, true))
798
826
options&= ~(OPTION_BEGIN);
804
832
bool result= true;
806
assert(! inTransaction());
808
options|= OPTION_BEGIN;
809
server_status|= SERVER_STATUS_IN_TRANS;
811
if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
834
if (! endActiveTransaction())
840
options|= OPTION_BEGIN;
841
server_status|= SERVER_STATUS_IN_TRANS;
843
if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
833
866
first_successful_insert_id_in_cur_stmt= 0;
834
867
substitute_null_with_insert_id= true;
837
869
arg_of_last_insert_id_function= false;
839
870
/* Free Items that were created during this execution */
843
_where= Session::DEFAULT_WHERE;
873
where= Session::DEFAULT_WHERE;
845
875
/* Reset the temporary shares we built */
846
876
for_each(temporary_shares.begin(),
871
901
bool allocate_lex_string)
873
903
if (allocate_lex_string)
874
if (!(lex_str= (LEX_STRING *)getMemRoot()->allocate(sizeof(LEX_STRING))))
904
if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
876
906
if (!(lex_str->str= mem_root->strmake_root(str, length)))
917
947
return (result->send_fields(field_list));
920
void select_result::send_error(drizzled::error_t errcode, const char *err)
950
void select_result::send_error(uint32_t errcode, const char *err)
922
952
my_message(errcode, err, MYF(0));
926
956
Handling writing to file
927
957
************************************************************************/
929
void select_to_file::send_error(drizzled::error_t errcode,const char *err)
959
void select_to_file::send_error(uint32_t errcode,const char *err)
931
961
my_message(errcode, err, MYF(0));
1480
1510
bool select_max_min_finder_subselect::cmp_decimal()
1482
1512
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);
1513
my_decimal cval, *cvalue= cache->val_decimal(&cval);
1514
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1486
1516
return (cache->null_value && !maxmin->null_value) ||
1487
1517
(!cache->null_value && !maxmin->null_value &&
1488
class_decimal_cmp(cvalue, mvalue) > 0) ;
1518
my_decimal_cmp(cvalue, mvalue) > 0) ;
1489
1519
return (maxmin->null_value && !cache->null_value) ||
1490
1520
(!cache->null_value && !maxmin->null_value &&
1491
class_decimal_cmp(cvalue,mvalue) < 0);
1521
my_decimal_cmp(cvalue,mvalue) < 0);
1494
1524
bool select_max_min_finder_subselect::cmp_str()
1574
1604
/* Fix for Intel compiler */
1575
1605
if (copy_field)
1577
boost::checked_array_delete(copy_field);
1578
save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
1607
delete [] copy_field;
1608
save_copy_field= copy_field= 0;
1582
1612
void Session::send_kill_message() const
1584
drizzled::error_t err= static_cast<drizzled::error_t>(killed_errno());
1614
int err= killed_errno();
1586
1616
my_message(err, ER(err), MYF(0));
1612
1642
@param session Thread handle
1613
1643
@param all true <=> rollback main transaction.
1615
void Session::markTransactionForRollback(bool all)
1645
void mark_transaction_to_rollback(Session *session, bool all)
1617
is_fatal_sub_stmt_error= true;
1618
transaction_rollback_request= all;
1649
session->is_fatal_sub_stmt_error= true;
1650
session->transaction_rollback_request= all;
1621
void Session::disconnect(enum error_t errcode)
1654
void Session::disconnect(uint32_t errcode, bool should_lock)
1623
1656
/* Allow any plugins to cleanup their session variables */
1624
1657
plugin_sessionvar_cleanup(this);
1634
1667
if (not getKilled() && variables.log_warnings > 1)
1636
errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
1669
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1638
1671
, (_schema->empty() ? "unconnected" : _schema->c_str())
1639
1672
, security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
1678
/* Close out our connection to the client */
1680
session::Cache::singleton().mutex().lock();
1645
1682
setKilled(Session::KILL_CONNECTION);
1647
1684
if (client->isConnected())
1649
if (errcode != EE_OK)
1651
1688
/*my_error(errcode, ER(errcode));*/
1652
1689
client->sendError(errcode, ER(errcode));
1654
1691
client->close();
1696
session::Cache::singleton().mutex().unlock();
1658
1700
void Session::reset_for_next_command()
1743
1785
table->free_io_cache();
1744
1786
table->delete_table();
1746
identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1788
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1747
1789
rm_temporary_table(table_type, identifier);
1749
boost::checked_delete(table->getMutableShare());
1791
delete table->getMutableShare();
1751
boost::checked_delete(table);
1793
/* This makes me sad, but we're allocating it via malloc */
1754
1797
/** Clear most status variables. */
1772
1815
user_var_entry *Session::getVariable(const std::string &name, bool create_if_not_exists)
1817
UserVarsRange ppp= user_vars.equal_range(name);
1777
UserVars::iterator iter= user_vars.find(name);
1778
if (iter != user_vars.end())
1819
for (UserVars::iterator iter= ppp.first;
1820
iter != ppp.second; ++iter)
1779
1822
return (*iter).second;
1781
1825
if (not create_if_not_exists)
1800
1844
void Session::setVariable(const std::string &name, const std::string &value)
1802
1846
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);
1848
updateable_var->update_hash(false,
1849
(void*)value.c_str(),
1850
static_cast<uint32_t>(value.length()), STRING_RESULT,
1852
DERIVATION_IMPLICIT, false);
1813
1855
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1863
1905
TransactionServices &transaction_services= TransactionServices::singleton();
1864
1906
main_da.can_overwrite_status= true;
1865
transaction_services.autocommitOrRollback(*this, is_error());
1907
transaction_services.autocommitOrRollback(this, is_error());
1866
1908
main_da.can_overwrite_status= false;
1867
1909
transaction.stmt.reset();
1885
1927
Note that we need to hold table::Cache::singleton().mutex() while changing the
1886
1928
open_tables list. Another thread may work on it.
1887
(See: table::Cache::singleton().removeTable(), wait_completed_table())
1929
(See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1888
1930
Closing a MERGE child before the parent would be fatal if the
1889
1931
other thread tries to abort the MERGE lock in between.
1919
1961
if (not lock_tables(tables, counter, &need_reopen))
1922
1963
if (not need_reopen)
1925
1965
close_tables_for_reopen(&tables);
1928
if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
1967
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1969
mysql_handle_derived(lex, &mysql_derived_filling))))
1937
1978
might be an issue (lame engines).
1940
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
1981
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
1942
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1983
if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1944
1985
if (not best_effort)
1946
1987
std::string path;
1947
1988
identifier.getSQLPath(path);
1948
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1989
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1949
1990
path.c_str(), errno);
1958
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
1999
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
1960
drizzled::error_t error;
1963
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
2003
if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
1965
2005
std::string path;
1966
2006
identifier.getSQLPath(path);
1967
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1968
path.c_str(), error);
2007
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2008
path.c_str(), errno);
1990
2030
bool have_proto= false;
1992
message::Table *proto= table->getShare()->getTableMessage();
1993
if (table->getShare()->getTableMessage())
2032
message::Table *proto= table->getShare()->getTableProto();
2033
if (table->getShare()->getTableProto())
1994
2034
have_proto= true;
1996
2036
const char *answer= have_proto ? "true" : "false";
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();
2050
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2052
table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2057
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
2059
TableMessageCache::iterator iter;
2061
iter= table_message_cache.find(identifier.getPath());
2063
if (iter == table_message_cache.end())
2066
table_message_cache.erase(iter);
2071
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
2073
TableMessageCache::iterator iter;
2075
iter= table_message_cache.find(identifier.getPath());
2077
if (iter == table_message_cache.end())
2080
table_message.CopyFrom(((*iter).second));
2085
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
2087
TableMessageCache::iterator iter;
2089
iter= table_message_cache.find(identifier.getPath());
2091
if (iter == table_message_cache.end())
2099
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
2101
TableMessageCache::iterator iter;
2103
table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2105
iter= table_message_cache.find(to.getPath());
2107
if (iter == table_message_cache.end())
2112
(*iter).second.set_schema(to.getSchemaName());
2113
(*iter).second.set_name(to.getTableName());
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();
2016
2124
assert(tmp_share);
2038
2146
0 if out of memory, Table object in case of success
2040
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
2148
table::Instance *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.
2150
temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2044
table::Singular *tmp_share= temporary_shares.back();
2152
table::Instance *tmp_share= temporary_shares.back();
2046
2154
assert(tmp_share);