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"
48
48
#include "drizzled/transaction_services.h"
49
49
#include "drizzled/drizzled.h"
51
#include "drizzled/table_share_instance.h"
51
#include "drizzled/table/instance.h"
53
53
#include "plugin/myisam/myisam.h"
54
54
#include "drizzled/internal/iocache.h"
55
55
#include "drizzled/internal/thread_var.h"
56
56
#include "drizzled/plugin/event_observer.h"
58
#include "drizzled/util/functors.h"
59
61
#include <algorithm>
61
#include "boost/filesystem.hpp"
63
#include <boost/filesystem.hpp>
63
65
using namespace std;
405
410
LOCK_delete.unlock();
408
void Session::awake(Session::killed_state state_to_set)
413
void Session::awake(Session::killed_state_t state_to_set)
410
415
this->checkSentry();
411
416
safe_mutex_assert_owner(&LOCK_delete);
413
killed= state_to_set;
418
setKilled(state_to_set);
414
419
if (state_to_set != Session::KILL_QUERY)
416
421
scheduler->killSession(this);
552
557
current_global_counters.connections++;
553
558
thread_id= variables.pseudo_thread_id= global_thread_id++;
555
LOCK_thread_count.lock();
556
getSessionList().push_back(this);
557
LOCK_thread_count.unlock();
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...
559
575
if (scheduler->addSession(this))
561
577
DRIZZLE_CONNECTION_START(thread_id);
562
578
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
564
killed= Session::KILL_CONNECTION;
580
setKilled(Session::KILL_CONNECTION);
566
582
status_var.aborted_connects++;
580
const char* Session::enter_cond(boost::condition_variable &cond, boost::mutex &mutex, const char* msg)
596
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
582
598
const char* old_msg = get_proc_info();
583
599
safe_mutex_assert_owner(mutex);
596
612
does a Session::awake() on you).
598
614
mysys_var->current_mutex->unlock();
599
boost::mutex::scoped_lock scopedLock(mysys_var->mutex);
615
boost_unique_lock_t scopedLock(mysys_var->mutex);
600
616
mysys_var->current_mutex = 0;
601
617
mysys_var->current_cond = 0;
602
618
this->set_proc_info(old_msg);
616
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)
618
const string passwd_str(passwd, passwd_len);
619
635
bool is_authenticated=
620
636
plugin::Authentication::isAuthenticated(getSecurityContext(),
750
766
if (result == false)
751
768
my_error(killed_errno(), MYF(0));
752
770
else if ((result == true) && do_release)
753
killed= Session::KILL_CONNECTION;
772
setKilled(Session::KILL_CONNECTION);
821
841
where= Session::DEFAULT_WHERE;
823
843
/* Reset the temporary shares we built */
824
for (std::vector<TableShareInstance *>::iterator iter= temporary_shares.begin();
825
iter != temporary_shares.end(); iter++)
844
for_each(temporary_shares.begin(),
845
temporary_shares.end(),
829
847
temporary_shares.clear();
911
929
my_message(errcode, err, MYF(0));
914
(void) end_io_cache(cache);
932
(void) cache->end_io_cache();
915
933
(void) internal::my_close(file, MYF(0));
916
(void) internal::my_delete(path, MYF(0)); // Delete file on error
934
(void) internal::my_delete(path.file_string().c_str(), MYF(0)); // Delete file on error
922
940
bool select_to_file::send_eof()
924
int error= test(end_io_cache(cache));
942
int error= test(cache->end_io_cache());
925
943
if (internal::my_close(file, MYF(MY_WME)))
943
961
/* In case of error send_eof() may be not called: close the file here. */
946
(void) end_io_cache(cache);
964
(void) cache->end_io_cache();
947
965
(void) internal::my_close(file, MYF(0));
994
static int create_file(Session *session, char *path, file_exchange *exchange, internal::IO_CACHE *cache)
1012
static int create_file(Session *session,
1013
fs::path &target_path,
1014
file_exchange *exchange,
1015
internal::IO_CACHE *cache)
1017
fs::path to_file(exchange->file_name);
997
uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
999
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
1000
option|= MY_REPLACE_DIR; // Force use of db directory
1003
if (!internal::dirname_length(exchange->file_name))
1020
if (not to_file.has_root_directory())
1005
strcpy(path, getDataHomeCatalog().c_str());
1006
strncat(path, "/", 1);
1007
if (! session->db.empty())
1008
strncat(path, session->db.c_str(), FN_REFLEN-getDataHomeCatalog().size());
1009
(void) internal::fn_format(path, exchange->file_name, path, "", option);
1022
target_path= fs::system_complete(getDataHomeCatalog());
1023
if (not session->db.empty())
1025
int count_elements= 0;
1026
for (fs::path::iterator iter= to_file.begin();
1027
iter != to_file.end();
1028
++iter, ++count_elements)
1031
if (count_elements == 1)
1033
target_path /= session->db;
1036
target_path /= to_file;
1012
(void) internal::fn_format(path, exchange->file_name, getDataHomeCatalog().c_str(), "", option);
1040
target_path = exchange->file_name;
1014
if (opt_secure_file_priv)
1043
if (not secure_file_priv.string().empty())
1016
fs::path secure_file_path(fs::system_complete(fs::path(opt_secure_file_priv)));
1017
fs::path target_path(fs::system_complete(fs::path(path)));
1018
if (target_path.file_string().substr(0, secure_file_path.file_string().size()) != secure_file_path.file_string())
1045
if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1020
1047
/* Write only allowed to dir or subdir specified by secure_file_priv */
1021
1048
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1026
if (!access(path, F_OK))
1053
if (!access(target_path.file_string().c_str(), F_OK))
1028
1055
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1031
1058
/* Create the file world readable */
1032
if ((file= internal::my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1059
if ((file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1034
1061
(void) fchmod(file, 0666); // Because of umask()
1035
if (init_io_cache(cache, file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1062
if (cache->init_io_cache(file, 0L, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1037
1064
internal::my_close(file, MYF(0));
1038
internal::my_delete(path, MYF(0)); // Delete file on error, it was just created
1065
internal::my_delete(target_path.file_string().c_str(), MYF(0)); // Delete file on error, it was just created
1049
1076
bool string_results= false, non_string_results= false;
1051
1078
if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1052
strncpy(path,exchange->file_name,FN_REFLEN-1);
1080
path= exchange->file_name;
1054
1083
/* Check if there is any blobs in data */
1143
1173
null_buff[0]=escape_char;
1144
1174
null_buff[1]='N';
1145
1175
if (my_b_write(cache,(unsigned char*) null_buff,2))
1148
1178
else if (my_b_write(cache,(unsigned char*) "NULL",4))
1237
1267
tmp_buff[1]= *pos ? *pos : '0';
1238
1268
if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1239
1269
my_b_write(cache,(unsigned char*) tmp_buff,2))
1244
1274
if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
1247
1277
else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
1250
1280
if (fixed_row_size)
1251
1281
{ // Fill with space
1261
1291
for (; length > sizeof(space) ; length-=sizeof(space))
1263
1293
if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1266
1296
if (my_b_write(cache,(unsigned char*) space,length))
1270
1300
if (res && enclosed)
1272
1302
if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1273
1303
exchange->enclosed->length()))
1276
1306
if (--items_left)
1278
1308
if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1279
1309
field_term_length))
1283
1313
if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1284
1314
exchange->line_term->length()))
1326
1357
if (!res) // If NULL
1328
1359
if (my_b_write(cache,(unsigned char*) "",1))
1331
1362
else if (my_b_write(cache,(unsigned char*) res->ptr(),res->length()))
1333
my_error(ER_ERROR_ON_WRITE, MYF(0), path, errno);
1364
my_error(ER_ERROR_ON_WRITE, MYF(0), path.file_string().c_str(), errno);
1394
1423
switch (val_item->result_type())
1396
1425
case REAL_RESULT:
1397
op= &select_max_min_finder_subselect::cmp_real;
1426
op= &select_max_min_finder_subselect::cmp_real;
1399
1428
case INT_RESULT:
1400
op= &select_max_min_finder_subselect::cmp_int;
1429
op= &select_max_min_finder_subselect::cmp_int;
1402
1431
case STRING_RESULT:
1403
op= &select_max_min_finder_subselect::cmp_str;
1432
op= &select_max_min_finder_subselect::cmp_str;
1405
1434
case DECIMAL_RESULT:
1406
1435
op= &select_max_min_finder_subselect::cmp_decimal;
1408
1437
case ROW_RESULT:
1409
1438
// This case should never be choosen
1414
1443
cache->store(val_item);
1568
Check the killed state of a user thread
1569
@param session user thread
1570
@retval 0 the user thread is active
1571
@retval 1 the user thread has been killed
1573
int session_killed(const Session *session)
1575
return(session->killed);
1579
const struct charset_info_st *session_charset(Session *session)
1581
return(session->charset());
1585
1595
Mark transaction to rollback and mark error as fatal to a sub-statement.
1602
1612
plugin_sessionvar_cleanup(this);
1604
1614
/* If necessary, log any aborted or unauthorized connections */
1605
if (killed || client->wasAborted())
1615
if (getKilled() || client->wasAborted())
1607
1617
status_var.aborted_threads++;
1610
1620
if (client->wasAborted())
1612
if (! killed && variables.log_warnings > 1)
1622
if (not getKilled() && variables.log_warnings > 1)
1614
1624
SecurityContext *sctx= &security_ctx;
1625
1635
/* Close out our connection to the client */
1626
1636
if (should_lock)
1627
1637
LOCK_thread_count.lock();
1628
killed= Session::KILL_CONNECTION;
1639
setKilled(Session::KILL_CONNECTION);
1629
1641
if (client->isConnected())
1752
1767
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1769
return getVariable(std::string(name.str, name.length), create_if_not_exists);
1772
user_var_entry *Session::getVariable(const std::string &name, bool create_if_not_exists)
1774
UserVarsRange ppp= user_vars.equal_range(name);
1776
for (UserVars::iterator iter= ppp.first;
1777
iter != ppp.second; ++iter)
1779
return (*iter).second;
1782
if (not create_if_not_exists)
1754
1785
user_var_entry *entry= NULL;
1755
UserVarsRange ppp= user_vars.equal_range(std::string(name.str, name.length));
1757
for (UserVars::iterator iter= ppp.first;
1758
iter != ppp.second; ++iter)
1760
entry= (*iter).second;
1763
if ((entry == NULL) && create_if_not_exists)
1765
entry= new (nothrow) user_var_entry(name.str, query_id);
1770
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(std::string(name.str, name.length), entry));
1772
if (not returnable.second)
1786
entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1791
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1793
if (not returnable.second)
1801
void Session::setVariable(const std::string &name, const std::string &value)
1803
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);
1782
1812
void Session::mark_temp_tables_as_free_for_reuse()
1784
1814
for (Table *table= temporary_tables ; table ; table= table->getNext())
1848
1878
handled either before writing a query log event (inside
1849
1879
binlog_query()) or when preparing a pending event.
1851
mysql_unlock_tables(this, lock);
1855
1885
Note that we need to hold LOCK_open while changing the
1856
1886
open_tables list. Another thread may work on it.
1857
(See: remove_table_from_cache(), mysql_wait_completed_table())
1887
(See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1858
1888
Closing a MERGE child before the parent would be fatal if the
1859
1889
other thread tries to abort the MERGE lock in between.
1893
1923
close_tables_for_reopen(&tables);
1895
1925
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1896
(fill_derived_tables() &&
1897
1927
mysql_handle_derived(lex, &mysql_derived_filling))))
1903
bool Session::openTables(TableList *tables, uint32_t flags)
1906
bool ret= fill_derived_tables();
1907
assert(ret == false);
1908
if (open_tables_from_list(&tables, &counter, flags) ||
1909
mysql_handle_derived(lex, &mysql_derived_prepare))
1917
1934
@note "best_effort" is used in cases were if a failure occurred on this
1918
1935
operation it would not be surprising because we are only removing because there
2053
TableShareInstance *Session::getTemporaryShare(TableIdentifier::Type type_arg)
2055
temporary_shares.push_back(new TableShareInstance(type_arg)); // This will not go into the tableshare cache, so no key is used.
2057
TableShareInstance *tmp_share= temporary_shares.back();
2070
table::Instance *Session::getInstanceTable()
2072
temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
2074
table::Instance *tmp_share= temporary_shares.back();
2083
Create a reduced Table object with properly set up Field list from a
2084
list of field definitions.
2086
The created table doesn't have a table Cursor associated with
2087
it, has no keys, no group/distinct, no copy_funcs array.
2088
The sole purpose of this Table object is to use the power of Field
2089
class to read/write data to/from table->getInsertRecord(). Then one can store
2090
the record in any container (RB tree, hash, etc).
2091
The table is created in Session mem_root, so are the table's fields.
2092
Consequently, if you don't BLOB fields, you don't need to free it.
2094
@param session connection handle
2095
@param field_list list of column definitions
2098
0 if out of memory, Table object in case of success
2100
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2102
temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2104
table::Instance *tmp_share= temporary_shares.back();
2059
2106
assert(tmp_share);