39
40
#include <drizzled/plugin/client.h>
40
41
#include "drizzled/plugin/scheduler.h"
41
42
#include "drizzled/plugin/authentication.h"
42
#include "drizzled/plugin/logging.h"
43
#include "drizzled/plugin/transactional_storage_engine.h"
44
43
#include "drizzled/probes.h"
45
44
#include "drizzled/table_proto.h"
46
45
#include "drizzled/db.h"
47
46
#include "drizzled/pthread_globals.h"
48
#include "drizzled/transaction_services.h"
50
48
#include "plugin/myisam/myisam.h"
51
49
#include "drizzled/internal/iocache.h"
145
142
return session->get_proc_info();
148
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
145
void **Session::getEngineData(const plugin::StorageEngine *engine)
150
return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
147
return static_cast<void **>(&ha_data[engine->slot].ha_ptr);
153
ResourceContext *Session::getResourceContext(const plugin::MonitoredInTransaction *monitored,
150
Ha_trx_info *Session::getEngineInfo(const plugin::StorageEngine *engine,
156
return &ha_data[monitored->getId()].resource_context[index];
153
return &ha_data[engine->getSlot()].ha_info[index];
384
384
Session::~Session()
386
Session_CHECK_SENTRY(this);
387
387
add_to_status(&global_status_var, &status_var);
389
389
if (client->isConnected())
391
391
if (global_system_variables.log_warnings)
392
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
392
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),my_progname,
394
(getSecurityContext().getUser().c_str() ?
395
getSecurityContext().getUser().c_str() : ""));
394
(security_ctx.user.c_str() ?
395
security_ctx.user.c_str() : ""));
396
396
disconnect(0, false);
407
407
plugin_sessionvar_cleanup(this);
409
409
free_root(&warn_root,MYF(0));
410
free_root(&transaction.mem_root,MYF(0));
410
411
mysys_var=0; // Safety (shouldn't be needed)
411
412
dbug_sentry= Session_SENTRY_GONE;
413
414
free_root(&main_mem_root, MYF(0));
414
415
pthread_setspecific(THR_Session, 0);
416
plugin::Logging::postEndDo(this);
418
418
/* Ensure that no one is using Session */
419
419
pthread_mutex_unlock(&LOCK_delete);
433
433
If this assumption will change, then we have to explictely add
434
434
the other variables after the while loop
436
void add_to_status(system_status_var *to_var, system_status_var *from_var)
436
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
438
438
ulong *end= (ulong*) ((unsigned char*) to_var +
439
offsetof(system_status_var, last_system_status_var) +
439
offsetof(STATUS_VAR, last_system_status_var) +
441
441
ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
457
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)
459
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
462
ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(system_status_var,
462
ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(STATUS_VAR,
463
463
last_system_status_var) +
465
465
ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
674
678
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(),
680
bool is_authenticated;
682
if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
684
my_error(ER_HANDSHAKE_ERROR, MYF(0), security_ctx.ip.c_str());
688
is_authenticated= plugin::Authentication::isAuthenticated(this, passwd);
681
690
if (is_authenticated != true)
683
/* isAuthenticated has pushed the error message */
692
my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
693
security_ctx.user.c_str(),
694
security_ctx.ip.c_str(),
695
passwd_len ? ER(ER_YES) : ER(ER_NO));
700
security_ctx.skip_grants();
687
702
/* Change database if necessary */
688
703
if (in_db && in_db[0])
690
SchemaIdentifier identifier(in_db);
691
if (mysql_change_db(this, identifier))
705
const string database_name_string(in_db);
706
NonNormalisedDatabaseName database_name(database_name_string);
707
NormalisedDatabaseName normalised_database_name(database_name);
709
if (mysql_change_db(this, normalised_database_name, false))
693
711
/* mysql_change_db() has pushed the error message. */
886
917
@return NULL on failure, or pointer to the LEX_STRING object
888
919
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
889
const std::string &str,
890
bool allocate_lex_string)
892
return make_lex_string(lex_str, str.c_str(), str.length(), allocate_lex_string);
895
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
896
const char* str, uint32_t length,
897
bool allocate_lex_string)
920
const char* str, uint32_t length,
921
bool allocate_lex_string)
899
923
if (allocate_lex_string)
900
924
if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
932
/* routings to adding tables to list of changed in transaction tables */
933
inline static void list_include(CHANGED_TableList** prev,
934
CHANGED_TableList* curr,
935
CHANGED_TableList* new_table)
940
(*prev)->next = curr;
944
/* add table to list of changed in transaction tables */
946
void Session::add_changed_table(Table *table)
948
assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
949
table->cursor->has_transactions());
950
add_changed_table(table->s->table_cache_key.str,
951
(long) table->s->table_cache_key.length);
955
void Session::add_changed_table(const char *key, long key_length)
957
CHANGED_TableList **prev_changed = &transaction.changed_tables;
958
CHANGED_TableList *curr = transaction.changed_tables;
960
for (; curr; prev_changed = &(curr->next), curr = curr->next)
962
int cmp = (long)curr->key_length - (long)key_length;
965
list_include(prev_changed, curr, changed_table_dup(key, key_length));
970
cmp = memcmp(curr->key, key, curr->key_length);
973
list_include(prev_changed, curr, changed_table_dup(key, key_length));
982
*prev_changed = changed_table_dup(key, key_length);
986
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
988
CHANGED_TableList* new_table =
989
(CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
993
my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
994
ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
995
killed= KILL_CONNECTION;
999
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
1000
new_table->next = 0;
1001
new_table->key_length = key_length;
1002
::memcpy(new_table->key, key, key_length);
908
1007
int Session::send_explain_fields(select_result *result)
910
1009
List<Item> field_list;
1046
1145
option|= MY_REPLACE_DIR; // Force use of db directory
1049
if (!internal::dirname_length(exchange->file_name))
1148
if (!dirname_length(exchange->file_name))
1051
1150
strcpy(path, drizzle_real_data_home);
1052
1151
if (! session->db.empty())
1053
1152
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);
1153
(void) fn_format(path, exchange->file_name, path, "", option);
1057
(void) internal::fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1156
(void) fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1059
1158
if (opt_secure_file_priv &&
1060
1159
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1072
1171
/* Create the file world readable */
1073
if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1172
if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1075
1174
(void) fchmod(file, 0666); // Because of umask()
1076
if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1175
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
1177
my_close(file, MYF(0));
1178
my_delete(path, MYF(0)); // Delete file on error, it was just created
1697
1814
if (! killed && variables.log_warnings > 1)
1699
SecurityContext *sctx= &security_ctx;
1816
Security_context *sctx= &security_ctx;
1701
1818
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1703
1820
, (db.empty() ? "unconnected" : db.c_str())
1704
, sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1705
, sctx->getIp().c_str()
1821
, sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated"
1706
1823
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1790
1916
if (temporary_tables)
1791
1917
table->next->prev= NULL;
1919
close_temporary(table);
1797
Close and drop a temporary table
1923
Close and delete a temporary table
1800
1926
This dosn't unlink table from session->temporary
1801
1927
If this is needed, use close_temporary_table()
1804
void Session::nukeTable(Table *table)
1930
void Session::close_temporary(Table *table)
1806
1932
plugin::StorageEngine *table_type= table->s->db_type();
1808
1934
table->free_io_cache();
1809
1935
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);
1937
rm_temporary_table(table_type, table->s->path.str);
1814
1939
table->s->free_table_share();
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
2153
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 */
2159
if (plugin::StorageEngine::deleteDefinitionFromPath(identifier))
2162
if (base->doDropTable(*this, identifier.getPath()))
2165
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2166
identifier.getPath(), errno);
2171
bool Session::rm_temporary_table(plugin::StorageEngine *base, const char *path)
2177
if (delete_table_proto_file(path))
2180
if (base->doDropTable(*this, path))
2183
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),