1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
4
* Copyright (C) 2008 Sun Microsystems
6
6
* This program is free software; you can redistribute it and/or modify
7
7
* it under the terms of the GNU General Public License as published by
24
24
#include "config.h"
26
#include <drizzled/copy_field.h>
27
#include "drizzled/session.h"
28
#include "drizzled/session/cache.h"
29
#include "drizzled/error.h"
30
#include "drizzled/gettext.h"
31
#include "drizzled/query_id.h"
32
#include "drizzled/data_home.h"
33
#include "drizzled/sql_base.h"
34
#include "drizzled/lock.h"
35
#include "drizzled/item/cache.h"
36
#include "drizzled/item/float.h"
37
#include "drizzled/item/return_int.h"
38
#include "drizzled/item/empty_string.h"
39
#include "drizzled/show.h"
40
#include "drizzled/plugin/client.h"
25
#include <drizzled/session.h>
26
#include "drizzled/session_list.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>
41
40
#include "drizzled/plugin/scheduler.h"
42
41
#include "drizzled/plugin/authentication.h"
43
42
#include "drizzled/plugin/logging.h"
44
43
#include "drizzled/plugin/transactional_storage_engine.h"
45
#include "drizzled/plugin/query_rewrite.h"
46
44
#include "drizzled/probes.h"
47
45
#include "drizzled/table_proto.h"
48
46
#include "drizzled/db.h"
50
48
#include "drizzled/transaction_services.h"
51
49
#include "drizzled/drizzled.h"
53
#include "drizzled/identifier.h"
55
#include <drizzled/refresh_version.h>
57
#include "drizzled/table/singular.h"
51
#include "drizzled/table/instance.h"
59
53
#include "plugin/myisam/myisam.h"
60
54
#include "drizzled/internal/iocache.h"
64
58
#include "drizzled/util/functors.h"
66
#include "drizzled/display.h"
68
61
#include <algorithm>
73
#include <boost/filesystem.hpp>
74
#include <boost/checked_delete.hpp>
76
#include "drizzled/util/backtrace.h"
63
#include "boost/filesystem.hpp"
78
65
using namespace std;
95
82
return length == other.length &&
96
83
field_name.length == other.field_name.length &&
97
!my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
84
!strcmp(field_name.str, other.field_name.str);
100
87
Open_tables_state::Open_tables_state(uint64_t version_arg) :
108
95
The following functions form part of the C plugin API
110
int tmpfile(const char *prefix)
97
int mysql_tmpfile(const char *prefix)
112
99
char filename[FN_REFLEN];
113
100
int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
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 */
234
247
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
235
248
warn_list.empty();
236
249
memset(warn_count, 0, sizeof(warn_count));
237
251
memset(&status_var, 0, sizeof(status_var));
239
253
/* Initialize sub structures */
269
283
m_internal_handler= handler;
272
bool Session::handle_error(drizzled::error_t sql_errno, const char *message,
273
DRIZZLE_ERROR::enum_warning_level level)
286
bool Session::handle_error(uint32_t sql_errno, const char *message,
287
DRIZZLE_ERROR::enum_warning_level level)
275
289
if (m_internal_handler)
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);
586
Is this session viewable by the current user?
588
bool Session::isViewable(identifier::User::const_reference user_arg) const
590
return plugin::Authorization::isAuthorized(user_arg, this, false);
594
593
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
596
595
const char* old_msg = get_proc_info();
642
643
/* Change database if necessary */
643
644
if (not in_db.empty())
645
identifier::Schema identifier(in_db);
646
if (change_db(this, identifier))
646
SchemaIdentifier identifier(in_db);
647
if (mysql_change_db(this, identifier))
648
/* change_db() has pushed the error message. */
649
/* mysql_change_db() has pushed the error message. */
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);
738
731
* (Which of course should never happen...)
740
733
server_status&= ~SERVER_STATUS_IN_TRANS;
741
if (transaction_services.commitTransaction(*this, true))
734
if (transaction_services.commitTransaction(this, true))
743
736
options&= ~(OPTION_BEGIN);
755
748
case ROLLBACK_AND_CHAIN:
757
750
server_status&= ~SERVER_STATUS_IN_TRANS;
758
if (transaction_services.rollbackTransaction(*this, true))
751
if (transaction_services.rollbackTransaction(this, true))
760
753
options&= ~(OPTION_BEGIN);
761
754
if (result == true && (completion == ROLLBACK_AND_CHAIN))
770
763
if (result == false)
772
my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
764
my_error(killed_errno(), MYF(0));
774
765
else if ((result == true) && do_release)
776
setKilled(Session::KILL_CONNECTION);
766
killed= Session::KILL_CONNECTION;
792
781
if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
794
783
server_status&= ~SERVER_STATUS_IN_TRANS;
795
if (transaction_services.commitTransaction(*this, true))
784
if (transaction_services.commitTransaction(this, true))
798
787
options&= ~(OPTION_BEGIN);
804
793
bool result= true;
806
assert(! inTransaction());
808
options|= OPTION_BEGIN;
809
server_status|= SERVER_STATUS_IN_TRANS;
811
if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
795
if (! endActiveTransaction())
801
options|= OPTION_BEGIN;
802
server_status|= SERVER_STATUS_IN_TRANS;
804
if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
833
827
first_successful_insert_id_in_cur_stmt= 0;
834
828
substitute_null_with_insert_id= true;
837
830
arg_of_last_insert_id_function= false;
839
831
/* Free Items that were created during this execution */
843
_where= Session::DEFAULT_WHERE;
834
where= Session::DEFAULT_WHERE;
845
836
/* Reset the temporary shares we built */
846
837
for_each(temporary_shares.begin(),
917
908
return (result->send_fields(field_list));
920
void select_result::send_error(drizzled::error_t errcode, const char *err)
911
void select_result::send_error(uint32_t errcode, const char *err)
922
913
my_message(errcode, err, MYF(0));
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
1022
1013
if (not to_file.has_root_directory())
1024
1015
target_path= fs::system_complete(getDataHomeCatalog());
1025
util::string::const_shared_ptr schema(session->schema());
1026
if (schema and not schema->empty())
1016
if (not session->db.empty())
1028
1018
int count_elements= 0;
1029
1019
for (fs::path::iterator iter= to_file.begin();
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();
1574
1554
/* Fix for Intel compiler */
1575
1555
if (copy_field)
1577
boost::checked_array_delete(copy_field);
1578
save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
1557
delete [] copy_field;
1558
save_copy_field= copy_field= 0;
1582
1562
void Session::send_kill_message() const
1584
drizzled::error_t err= static_cast<drizzled::error_t>(killed_errno());
1564
int err= killed_errno();
1586
1566
my_message(err, ER(err), MYF(0));
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. */
1772
1779
user_var_entry *Session::getVariable(const std::string &name, bool create_if_not_exists)
1781
UserVarsRange ppp= user_vars.equal_range(name);
1777
UserVars::iterator iter= user_vars.find(name);
1778
if (iter != user_vars.end())
1783
for (UserVars::iterator iter= ppp.first;
1784
iter != ppp.second; ++iter)
1779
1786
return (*iter).second;
1781
1789
if (not create_if_not_exists)
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();
1863
1870
TransactionServices &transaction_services= TransactionServices::singleton();
1864
1871
main_da.can_overwrite_status= true;
1865
transaction_services.autocommitOrRollback(*this, is_error());
1872
transaction_services.autocommitOrRollback(this, is_error());
1866
1873
main_da.can_overwrite_status= false;
1867
1874
transaction.stmt.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.
1919
1926
if (not lock_tables(tables, counter, &need_reopen))
1922
1928
if (not need_reopen)
1925
1930
close_tables_for_reopen(&tables);
1928
if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
1932
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1934
mysql_handle_derived(lex, &mysql_derived_filling))))
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();
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();
2016
2083
assert(tmp_share);
2038
2105
0 if out of memory, Table object in case of success
2040
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
2107
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.
2109
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();
2111
table::Instance *tmp_share= temporary_shares.back();
2046
2113
assert(tmp_share);
2048
2115
return tmp_share;
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 */
2077
2118
} /* namespace drizzled */