26 #include <boost/checked_delete.hpp>
27 #include <boost/filesystem.hpp>
28 #include <boost/ptr_container/ptr_container.hpp>
29 #include <drizzled/copy_field.h>
30 #include <drizzled/catalog/local.h>
31 #include <drizzled/diagnostics_area.h>
32 #include <drizzled/display.h>
33 #include <drizzled/drizzled.h>
34 #include <drizzled/error.h>
35 #include <drizzled/gettext.h>
36 #include <drizzled/ha_data.h>
37 #include <drizzled/identifier.h>
38 #include <drizzled/internal/iocache.h>
39 #include <drizzled/internal/thread_var.h>
40 #include <drizzled/item/cache.h>
41 #include <drizzled/item/empty_string.h>
42 #include <drizzled/item/float.h>
43 #include <drizzled/item/return_int.h>
44 #include <drizzled/item/subselect.h>
45 #include <drizzled/lock.h>
46 #include <drizzled/open_tables_state.h>
47 #include <drizzled/plugin/authentication.h>
48 #include <drizzled/plugin/authorization.h>
49 #include <drizzled/plugin/client.h>
50 #include <drizzled/plugin/event_observer.h>
51 #include <drizzled/plugin/logging.h>
52 #include <drizzled/plugin/query_rewrite.h>
53 #include <drizzled/plugin/scheduler.h>
54 #include <drizzled/plugin/transactional_storage_engine.h>
55 #include <drizzled/probes.h>
56 #include <drizzled/pthread_globals.h>
57 #include <drizzled/schema.h>
58 #include <drizzled/select_dump.h>
59 #include <drizzled/select_exists_subselect.h>
60 #include <drizzled/select_export.h>
61 #include <drizzled/select_max_min_finder_subselect.h>
62 #include <drizzled/select_singlerow_subselect.h>
63 #include <drizzled/select_subselect.h>
64 #include <drizzled/select_to_file.h>
65 #include <drizzled/session.h>
66 #include <drizzled/session/cache.h>
67 #include <drizzled/session/state.h>
68 #include <drizzled/session/table_messages.h>
69 #include <drizzled/session/times.h>
70 #include <drizzled/session/transactions.h>
72 #include <drizzled/sql_base.h>
73 #include <drizzled/sql_lex.h>
74 #include <drizzled/system_variables.h>
75 #include <drizzled/statement.h>
76 #include <drizzled/statistics_variables.h>
77 #include <drizzled/table/singular.h>
78 #include <drizzled/table_proto.h>
79 #include <drizzled/tmp_table_param.h>
80 #include <drizzled/transaction_services.h>
81 #include <drizzled/user_var_entry.h>
82 #include <drizzled/util/backtrace.h>
83 #include <drizzled/util/find_ptr.h>
84 #include <drizzled/util/functors.h>
85 #include <drizzled/util/storable.h>
86 #include <plugin/myisam/myisam.h>
95 namespace fs= boost::filesystem;
99 const char*
const Session::DEFAULT_WHERE=
"field list";
101 uint64_t g_refresh_version = 1;
103 bool Key_part_spec::operator==(
const Key_part_spec& other)
const
105 return length == other.length
106 && field_name.size() == other.field_name.size()
107 && not system_charset_info->strcasecmp(field_name.data(), other.field_name.data());
110 Open_tables_state::Open_tables_state(Session& session, uint64_t version_arg) :
111 version(version_arg),
114 open_tables_= temporary_tables= derived_tables= NULL;
115 extra_lock= lock= NULL;
123 char filename[FN_REFLEN];
124 int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
130 void **Session::getEngineData(
const plugin::MonitoredInTransaction *monitored)
132 return static_cast<void **
>(&ha_data[monitored->getId()].ha_ptr);
135 ResourceContext& Session::getResourceContext(
const plugin::MonitoredInTransaction& monitored,
size_t index)
137 return ha_data[monitored.getId()].resource_context[index];
140 int64_t session_test_options(
const Session *session, int64_t test_options)
142 return session->options & test_options;
148 typedef boost::unordered_map<std::string, util::Storable*, util::insensitive_hash, util::insensitive_equal_to> properties_t;
149 typedef std::map<std::string, plugin::EventObserverList*> schema_event_observers_t;
152 open_tables(session, g_refresh_version),
153 schema(boost::make_shared<std::string>())
159 BOOST_FOREACH(properties_t::reference it, properties)
174 properties_t properties;
175 schema_event_observers_t schema_event_observers;
178 util::string::mptr schema;
179 boost::shared_ptr<session::State> state;
180 boost::ptr_vector<table::Singular> temporary_shares;
186 Session::Session(
plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
188 mem(impl_->mem_root),
189 mem_root(&impl_->mem_root),
190 query(new std::string),
192 variables(impl_->variables),
193 status_var(impl_->status_var),
194 lock_id(&main_lock_id),
196 _where(
Session::DEFAULT_WHERE),
198 command(COM_CONNECT),
199 ha_data(plugin::num_trx_monitored_objects),
202 transaction(impl_->transaction),
203 open_tables(impl_->open_tables),
205 first_successful_insert_id_in_prev_stmt(0),
206 first_successful_insert_id_in_cur_stmt(0),
208 options(session_startup_options),
211 examined_row_count(0),
217 _global_read_lock(NONE),
218 count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
221 is_fatal_error(false),
222 transaction_rollback_request(false),
223 is_fatal_sub_stmt_error(0),
224 derived_tables_processing(false),
226 arg_of_last_insert_id_function(false),
227 _catalog(catalog_arg),
228 transaction_message(NULL),
229 statement_message(NULL),
230 session_event_observers(NULL),
232 concurrent_execute_allowed(true),
233 tablespace_op(false),
235 security_ctx(identifier::User::make_shared()),
236 originating_server_uuid_set(false),
239 client->setSession(
this);
246 mem.init(memory::ROOT_MIN_BLOCK_SIZE);
249 lex().current_select= 0;
250 memset(&variables, 0,
sizeof(variables));
251 scoreboard_index= -1;
252 originating_server_uuid=
"";
253 originating_commit_id= 0;
261 plugin_sessionvar_init(
this);
267 variables.pseudo_thread_id= thread_id;
268 server_status= SERVER_STATUS_AUTOCOMMIT;
270 if (variables.max_join_size == HA_POS_ERROR)
273 options &= ~OPTION_BIG_SELECTS;
275 open_options=ha_open_options;
276 update_lock_default= TL_WRITE;
277 session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
279 memset(&status_var, 0,
sizeof(status_var));
288 plugin::EventObserver::registerSessionEvents(*
this);
293 return impl_->diagnostics;
296 const LEX& Session::lex()
const
306 enum_sql_command Session::getSqlCommand()
const
308 return lex().sql_command;
311 session::TableMessages& Session::getMessageCache()
313 return impl_->table_message_cache;
316 void statement::Statement::set_command(enum_sql_command v)
318 session().lex().sql_command= v;
321 LEX& statement::Statement::lex()
323 return session().lex();
326 session::Transactions& statement::Statement::transaction()
328 return session().transaction;
331 void Session::add_item_to_list(Item *item)
333 lex().current_select->add_item_to_list(
this, item);
336 void Session::add_value_to_list(Item *value)
338 lex().value_list.push_back(value);
341 void Session::add_order_to_list(Item *item,
bool asc)
343 lex().current_select->add_order_to_list(
this, item, asc);
346 void Session::add_group_to_list(Item *item,
bool asc)
348 lex().current_select->add_group_to_list(
this, item, asc);
361 void Session::setAbort(
bool arg)
363 mysys_var->abort= arg;
366 void Session::lockOnSys()
372 boost::mutex::scoped_lock scopedLock(mysys_var->mutex);
373 if (mysys_var->current_cond)
375 mysys_var->current_mutex->lock();
376 mysys_var->current_cond->notify_all();
377 mysys_var->current_mutex->unlock();
381 void Session::get_xid(DrizzleXid *xid)
const
383 *xid = *(DrizzleXid *) &transaction.xid_state.xid;
388 void Session::cleanup()
390 assert(not cleanup_done);
392 setKilled(KILL_CONNECTION);
397 TransactionServices::rollbackTransaction(*
this,
true);
399 BOOST_FOREACH(UserVars::reference iter,
user_vars)
400 boost::checked_delete(iter.second);
403 open_tables.close_temporary_tables();
405 if (global_read_lock)
406 unlockGlobalReadLock();
415 assert(security_ctx);
416 if (global_system_variables.log_warnings)
418 errmsg_printf(error::WARN, ER(ER_FORCING_CLOSE), internal::my_progname, thread_id, security_ctx->username().c_str());
428 boost::checked_delete(client);
432 if (not cleanup_done)
436 plugin_sessionvar_cleanup(
this);
441 impl_->mem_root.free_root(MYF(0));
442 setCurrentMemRoot(NULL);
443 setCurrentSession(NULL);
445 plugin::Logging::postEndDo(
this);
446 plugin::EventObserver::deregisterSessionEvents(session_event_observers);
448 BOOST_FOREACH(impl_c::schema_event_observers_t::reference it, impl_->schema_event_observers)
449 plugin::EventObserver::deregisterSchemaEvents(it.second);
452 void Session::setClient(plugin::Client *client_arg)
458 void Session::awake(Session::killed_state_t state_to_set)
460 if (state_to_set == Session::KILL_QUERY &&
command == COM_SLEEP)
463 setKilled(state_to_set);
466 if (state_to_set != Session::KILL_QUERY)
468 DRIZZLE_CONNECTION_DONE(thread_id);
473 boost::mutex::scoped_lock scopedLock(mysys_var->mutex);
494 if (mysys_var->current_cond && mysys_var->current_mutex)
496 mysys_var->current_mutex->lock();
497 mysys_var->current_cond->notify_all();
498 mysys_var->current_mutex->unlock();
507 void Session::storeGlobals()
514 setCurrentSession(
this);
515 setCurrentMemRoot(&mem);
517 mysys_var= internal::my_thread_var2().get();
523 mysys_var->id= thread_id;
540 if (
variables.max_join_size == HA_POS_ERROR)
543 open_tables.version= g_refresh_version;
549 transaction.xid_state.xid.set_null();
550 transaction.xid_state.in_session=1;
564 while (not client->haveError() && getKilled() != KILL_CONNECTION)
572 bool Session::schedule(
const shared_ptr& arg)
574 arg->scheduler= plugin::Scheduler::getScheduler();
575 assert(arg->scheduler);
579 long current_connections= connection_count;
581 if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
583 current_global_counters.max_used_connections=
static_cast<uint64_t
>(connection_count);
586 current_global_counters.connections++;
587 arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
589 session::Cache::insert(arg);
591 if (unlikely(plugin::EventObserver::connectSession(*arg)))
596 if (plugin::Scheduler::getScheduler()->addSession(arg))
598 DRIZZLE_CONNECTION_START(arg->getSessionId());
599 char error_message_buff[DRIZZLE_ERRMSG_SIZE];
601 arg->setKilled(Session::KILL_CONNECTION);
603 arg->status_var.aborted_connects++;
607 snprintf(error_message_buff,
sizeof(error_message_buff), ER(ER_CANT_CREATE_THREAD), 1);
608 arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
624 const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex,
const char* msg)
626 const char* old_msg = get_proc_info();
627 safe_mutex_assert_owner(mutex);
628 mysys_var->current_mutex = &mutex;
629 mysys_var->current_cond = &cond;
634 void Session::exit_cond(
const char* old_msg)
642 mysys_var->current_mutex->unlock();
643 boost::mutex::scoped_lock scopedLock(mysys_var->mutex);
644 mysys_var->current_mutex = 0;
645 mysys_var->current_cond = 0;
654 status_var.aborted_connects++;
661 if (not plugin::Authentication::isAuthenticated(*user(), passwd_str))
663 status_var.access_denied++;
683 lex().current_select= 0;
687 uint32_t packet_length;
688 if (not client->
readCommand(&l_packet, packet_length))
691 if (getKilled() == KILL_CONNECTION)
694 if (packet_length == 0)
697 enum_server_command l_command=
static_cast<enum_server_command
>(l_packet[0]);
702 assert(packet_length);
703 return not
dispatch_command(l_command,
this, l_packet+1, (uint32_t) (packet_length-1));
709 while (in_packet_length > 0 && charset()->isspace(in_packet[0]))
714 const char *pos= in_packet + in_packet_length;
715 while (in_packet_length > 0 && (pos[-1] ==
';' || charset()->isspace(pos[-1])))
721 util::string::mptr new_query= boost::make_shared<std::string>(in_packet, in_packet_length);
724 impl_->state= boost::make_shared<session::State>(in_packet, in_packet_length);
732 if (transaction.xid_state.xa_state != XA_NOTR)
734 my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
745 server_status&= ~SERVER_STATUS_IN_TRANS;
752 case COMMIT_AND_CHAIN:
753 result= endActiveTransaction();
754 if (result ==
true && completion == COMMIT_AND_CHAIN)
755 result= startTransaction();
757 case ROLLBACK_RELEASE:
760 case ROLLBACK_AND_CHAIN:
762 server_status&= ~SERVER_STATUS_IN_TRANS;
763 if (TransactionServices::rollbackTransaction(*
this,
true))
766 if (result ==
true && (completion == ROLLBACK_AND_CHAIN))
767 result= startTransaction();
771 my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
777 my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
779 else if (result && do_release)
781 setKilled(Session::KILL_CONNECTION);
787 bool Session::endActiveTransaction()
791 if (transaction.xid_state.xa_state != XA_NOTR)
793 my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
796 if (
options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
798 server_status&= ~SERVER_STATUS_IN_TRANS;
806 bool Session::startTransaction(start_transaction_option_t opt)
811 server_status|= SERVER_STATUS_IN_TRANS;
832 arg_of_last_insert_id_function=
false;
841 impl_->temporary_shares.clear();
867 field_list.push_back(
new Item_return_int(
"id",3, DRIZZLE_TYPE_LONGLONG));
873 field_list.push_back(item=
new Item_empty_string(
"possible_keys", NAME_CHAR_LEN*MAX_KEY, cs));
877 field_list.push_back(item=
new Item_empty_string(
"key_len", MAX_KEY * (MAX_KEY_LENGTH_DECIMAL_WIDTH + 1 ), cs));
879 field_list.push_back(item=
new Item_empty_string(
"ref", NAME_CHAR_LEN*MAX_REF_PARTS, cs));
881 field_list.push_back(item=
new Item_return_int(
"rows", 10, DRIZZLE_TYPE_LONGLONG));
882 if (lex().describe & DESCRIBE_EXTENDED)
884 field_list.push_back(item=
new Item_float(
"filtered", 0.1234, 2, 4));
888 field_list.push_back(
new Item_empty_string(
"Extra", 255, cs));
889 result->send_fields(field_list);
892 void select_result::send_error(drizzled::error_t errcode,
const char *err)
894 my_message(errcode, err, MYF(0));
901 void select_to_file::send_error(drizzled::error_t errcode,
const char *err)
903 my_message(errcode, err, MYF(0));
906 (void) cache->end_io_cache();
907 (void) internal::my_close(file, MYF(0));
908 (void) internal::my_delete(path.file_string().c_str(), MYF(0));
914 bool select_to_file::send_eof()
916 int error= test(cache->end_io_cache());
917 if (internal::my_close(file, MYF(MY_WME)))
933 void select_to_file::cleanup()
938 (void) cache->end_io_cache();
939 (void) internal::my_close(file, MYF(0));
946 select_to_file::select_to_file(file_exchange *ex)
949 cache(static_cast<internal::io_cache_st *>(memory::sql_calloc(sizeof(internal::io_cache_st)))),
955 select_to_file::~select_to_file()
964 select_export::~select_export()
986 static int create_file(Session& session,
987 fs::path &target_path,
988 file_exchange *exchange,
989 internal::io_cache_st *cache)
991 fs::path to_file(exchange->file_name);
993 if (not to_file.has_root_directory())
995 target_path= fs::system_complete(catalog::local_identifier().getPath());
996 util::string::ptr schema(session.schema());
997 if (not schema->empty())
999 int count_elements= 0;
1000 for (fs::path::iterator it= to_file.begin(); it != to_file.end(); it++)
1002 if (count_elements == 1)
1003 target_path /= *schema;
1005 target_path /= to_file;
1009 target_path = exchange->file_name;
1012 if (not secure_file_priv.string().empty())
1014 if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1017 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"--secure-file-priv");
1022 if (!access(target_path.file_string().c_str(), F_OK))
1024 my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1028 int file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME));
1031 (void) fchmod(file, 0666);
1032 if (cache->init_io_cache(file, 0, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1034 internal::my_close(file, MYF(0));
1035 internal::my_delete(target_path.file_string().c_str(), MYF(0));
1043 select_export::prepare(List<Item> &list, Select_Lex_Unit *u)
1046 bool string_results=
false, non_string_results=
false;
1048 if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1050 path= exchange->file_name;
1055 List<Item>::iterator li(list.begin());
1056 while (Item* item= li++)
1058 if (item->max_length >= MAX_BLOB_WIDTH)
1064 if (item->result_type() == STRING_RESULT)
1065 string_results=
true;
1067 non_string_results=
true;
1070 field_term_length=exchange->field_term->length();
1071 field_term_char= field_term_length ?
1072 (int) (
unsigned char) (*exchange->field_term)[0] : INT_MAX;
1073 if (!exchange->line_term->length())
1074 exchange->line_term=exchange->field_term;
1075 field_sep_char= exchange->enclosed->length() ? (int) (
unsigned char) (*exchange->enclosed)[0] : field_term_char;
1076 escape_char= exchange->escaped->length() ? (int) (
unsigned char) (*exchange->escaped)[0] : -1;
1077 is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
1078 is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
1079 line_sep_char= exchange->line_term->length() ? (int) (
unsigned char) (*exchange->line_term)[0] : INT_MAX;
1080 if (!field_term_length)
1081 exchange->opt_enclosed=0;
1082 if (!exchange->enclosed->length())
1083 exchange->opt_enclosed=1;
1084 fixed_row_size= (!field_term_length && !exchange->enclosed->length() &&
1086 if ((is_ambiguous_field_sep && exchange->enclosed->empty() && (string_results || is_unsafe_field_sep)) ||
1087 (exchange->opt_enclosed && non_string_results && field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
1089 my_error(ER_AMBIGUOUS_FIELD_TERM, MYF(0));
1093 if ((file= create_file(*session, path, exchange, cache)) < 0)
1099 bool select_export::send_data(List<Item> &items)
1101 char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
1102 bool space_inited=0;
1103 String tmp(buff,
sizeof(buff),&my_charset_bin),*res;
1106 if (unit->offset_limit_cnt)
1108 unit->offset_limit_cnt--;
1112 uint32_t used_length=0,items_left=items.size();
1113 List<Item>::iterator li(items.begin());
1115 if (cache->write(exchange->line_start->ptr(), exchange->line_start->length()))
1118 while (Item* item=li++)
1120 Item_result result_type=item->result_type();
1121 bool enclosed = (exchange->enclosed->length() &&
1122 (!exchange->opt_enclosed || result_type == STRING_RESULT));
1123 res=item->str_result(&tmp);
1124 if (res && enclosed)
1126 if (cache->write(exchange->enclosed->ptr(), exchange->enclosed->length()))
1131 if (!fixed_row_size)
1133 if (escape_char != -1)
1135 null_buff[0]=escape_char;
1137 if (cache->write(null_buff, 2))
1140 else if (cache->write(
"NULL", 4))
1151 used_length= min(res->length(),
static_cast<size_t>(item->max_length));
1153 used_length= res->length();
1155 if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1158 char *pos, *start, *end;
1159 const charset_info_st*
const res_charset= res->charset();
1161 for (start= pos= (
char*) res->ptr(),end=pos+used_length; pos != end; pos++)
1163 if (use_mb(res_charset))
1165 if (
int l= my_ismbchar(res_charset, pos, end))
1204 if (needs_escaping(*pos, enclosed) &&
1209 (enclosed || !is_ambiguous_field_term ||
1210 (int) (
unsigned char) *pos != field_term_char))
1213 tmp_buff[0]= ((int) (
unsigned char) *pos == field_sep_char &&
1214 is_ambiguous_field_sep) ? field_sep_char : escape_char;
1215 tmp_buff[1]= *pos ? *pos :
'0';
1216 if (cache->write(start, pos - start) || cache->write(tmp_buff, 2))
1221 if (cache->write(start, pos - start))
1224 else if (cache->write(res->ptr(), used_length))
1229 if (item->max_length > used_length)
1235 memset(space,
' ',
sizeof(space));
1237 uint32_t length=item->max_length-used_length;
1238 for (; length >
sizeof(space) ; length-=
sizeof(space))
1240 if (cache->write(space,
sizeof(space)))
1243 if (cache->write(space, length))
1247 if (res && enclosed)
1249 if (cache->write(exchange->enclosed->ptr(), exchange->enclosed->length()))
1254 if (cache->write(exchange->field_term->ptr(), field_term_length))
1258 if (cache->write(exchange->line_term->ptr(), exchange->line_term->length()))
1273 select_dump::prepare(List<Item> &, Select_Lex_Unit *u)
1276 return (file= create_file(*session, path, exchange, cache)) < 0;
1280 bool select_dump::send_data(List<Item> &items)
1282 List<Item>::iterator li(items.begin());
1283 char buff[MAX_FIELD_WIDTH];
1284 String tmp(buff,
sizeof(buff),&my_charset_bin),*res;
1287 if (unit->offset_limit_cnt)
1289 unit->offset_limit_cnt--;
1292 if (row_count++ > 1)
1294 my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
1297 while (Item* item=li++)
1299 res=item->str_result(&tmp);
1302 if (cache->write(
"", 1))
1305 else if (cache->write(res->ptr(), res->length()))
1307 my_error(ER_ERROR_ON_WRITE, MYF(0), path.file_string().c_str(), errno);
1315 select_subselect::select_subselect(Item_subselect *item_arg)
1321 bool select_singlerow_subselect::send_data(List<Item> &items)
1323 Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
1326 my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
1329 if (unit->offset_limit_cnt)
1331 unit->offset_limit_cnt--;
1334 List<Item>::iterator li(items.begin());
1336 for (uint32_t i= 0; (val_item= li++); i++)
1337 it->store(i, val_item);
1343 void select_max_min_finder_subselect::cleanup()
1349 bool select_max_min_finder_subselect::send_data(List<Item> &items)
1351 Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
1352 List<Item>::iterator li(items.begin());
1353 Item *val_item= li++;
1354 it->register_value();
1357 cache->store(val_item);
1359 it->store(0, cache);
1365 cache= Item_cache::get_cache(val_item);
1366 switch (val_item->result_type())
1369 op= &select_max_min_finder_subselect::cmp_real;
1372 op= &select_max_min_finder_subselect::cmp_int;
1375 op= &select_max_min_finder_subselect::cmp_str;
1377 case DECIMAL_RESULT:
1378 op= &select_max_min_finder_subselect::cmp_decimal;
1386 cache->store(val_item);
1387 it->store(0, cache);
1393 bool select_max_min_finder_subselect::cmp_real()
1395 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1396 double val1= cache->val_real(), val2= maxmin->val_real();
1398 return (cache->null_value && !maxmin->null_value) ||
1399 (!cache->null_value && !maxmin->null_value &&
1401 return (maxmin->null_value && !cache->null_value) ||
1402 (!cache->null_value && !maxmin->null_value &&
1406 bool select_max_min_finder_subselect::cmp_int()
1408 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1409 int64_t val1= cache->val_int(), val2= maxmin->val_int();
1411 return (cache->null_value && !maxmin->null_value) ||
1412 (!cache->null_value && !maxmin->null_value &&
1414 return (maxmin->null_value && !cache->null_value) ||
1415 (!cache->null_value && !maxmin->null_value &&
1419 bool select_max_min_finder_subselect::cmp_decimal()
1421 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1422 type::Decimal cval, *cvalue= cache->val_decimal(&cval);
1423 type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
1425 return (cache->null_value && !maxmin->null_value) ||
1426 (!cache->null_value && !maxmin->null_value &&
1428 return (maxmin->null_value && !cache->null_value) ||
1429 (!cache->null_value && !maxmin->null_value &&
1433 bool select_max_min_finder_subselect::cmp_str()
1435 String *val1, *val2, buf1, buf2;
1436 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1441 val1= cache->val_str(&buf1);
1442 val2= maxmin->val_str(&buf1);
1444 return (cache->null_value && !maxmin->null_value) ||
1445 (!cache->null_value && !maxmin->null_value &&
1446 sortcmp(val1, val2, cache->collation.collation) > 0) ;
1447 return (maxmin->null_value && !cache->null_value) ||
1448 (!cache->null_value && !maxmin->null_value &&
1449 sortcmp(val1, val2, cache->collation.collation) < 0);
1452 bool select_exists_subselect::send_data(List<Item> &)
1454 Item_exists_subselect *it= (Item_exists_subselect *)item;
1455 if (unit->offset_limit_cnt)
1457 unit->offset_limit_cnt--;
1476 str_ref Session::copy_db_to()
const
1478 if (not impl_->schema->empty())
1479 return str_ref(mem.
strdup(*impl_->schema), impl_->schema->size());
1480 my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1488 void Tmp_Table_Param::init()
1490 field_count= sum_func_count= func_count= hidden_field_count= 0;
1491 group_parts= group_length= group_null_parts= 0;
1494 precomputed_group_by= 0;
1497 void Tmp_Table_Param::cleanup()
1502 boost::checked_array_delete(copy_field);
1503 save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
1507 void Session::send_kill_message()
const
1509 drizzled::error_t err=
static_cast<drizzled::error_t
>(killed_errno());
1511 my_message(err, ER(err), MYF(0));
1516 impl_->schema = boost::make_shared<std::string>(new_db);
1535 plugin_sessionvar_cleanup(
this);
1538 if (getKilled() || client->wasAborted())
1540 status_var.aborted_threads++;
1543 if (client->wasAborted())
1545 if (not getKilled() &&
variables.log_warnings > 1)
1547 errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
1549 , (impl_->schema->empty() ?
"unconnected" : impl_->schema->c_str())
1550 , security_ctx->username().empty() ?
"unauthenticated" : security_ctx->username().c_str()
1551 , security_ctx->address().c_str()
1552 , (main_da().is_error() ? main_da().message() : ER(ER_UNKNOWN_ERROR)));
1556 setKilled(Session::KILL_CONNECTION);
1560 if (errcode != EE_OK)
1563 client->sendError(errcode, ER(errcode));
1575 server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
1576 SERVER_QUERY_NO_INDEX_USED |
1577 SERVER_QUERY_NO_GOOD_INDEX_USED);
1589 void Open_tables_state::close_temporary_tables()
1597 for (table= temporary_tables; table; table= tmp_next)
1599 tmp_next= table->getNext();
1602 temporary_tables= NULL;
1609 void Open_tables_state::close_temporary_table(Table *table)
1611 if (table->getPrev())
1613 table->getPrev()->setNext(table->getNext());
1614 if (table->getPrev()->getNext())
1616 table->getNext()->setPrev(table->getPrev());
1622 assert(table == temporary_tables);
1628 temporary_tables= table->getNext();
1629 if (temporary_tables)
1631 table->getNext()->setPrev(NULL);
1645 void Open_tables_state::nukeTable(Table *table)
1647 plugin::StorageEngine& table_type= *table->getShare()->db_type();
1648 table->free_io_cache();
1649 table->delete_table();
1650 rm_temporary_table(table_type, identifier::Table(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath()));
1651 boost::checked_delete(table->getMutableShare());
1652 boost::checked_delete(table);
1658 void Session::refresh_status()
1661 memset(&status_var, 0,
sizeof(status_var));
1663 flush_status_time= time((time_t*) 0);
1664 current_global_counters.max_used_connections= 1;
1665 current_global_counters.connections= 0;
1668 user_var_entry* Session::getVariable(
str_ref name0,
bool create_if_not_exists)
1673 string name(name0.data(), name0.size());
1674 if (UserVars::mapped_type* iter= find_ptr(
user_vars, name))
1677 if (not create_if_not_exists)
1680 user_var_entry *entry=
new user_var_entry(name.c_str(), query_id);
1682 std::pair<UserVars::iterator, bool> returnable=
user_vars.insert(make_pair(name, entry));
1684 if (not returnable.second)
1686 boost::checked_delete(entry);
1692 void Session::setVariable(
const std::string &name,
const std::string &value)
1694 if (user_var_entry* var= getVariable(name,
true))
1696 var->update_hash(
false, value, STRING_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
false);
1702 for (
Table *table= temporary_tables ; table ; table= table->getNext())
1704 if (table->query_id == session_.
getQueryId())
1707 table->cursor->ha_reset();
1723 open_tables.clearDerivedTables();
1741 transaction.
stmt.reset();
1744 if (open_tables.lock)
1746 unlockTables(open_tables.lock);
1747 open_tables.lock= 0;
1766 if (lex().first_not_own_table() == *tables)
1768 lex().chop_off_not_own_tables();
1781 if (open_tables_from_list(&tables, &counter))
1784 if (not lock_tables(tables, counter, &need_reopen))
1787 if (not need_reopen)
1793 return handle_derived(&lex(), &derived_prepare) || handle_derived(&lex(), &derived_filling);
1802 bool Open_tables_state::rm_temporary_table(
const identifier::Table &identifier,
bool best_effort)
1804 if (plugin::StorageEngine::dropTable(session_, identifier))
1806 if (not best_effort)
1807 errmsg_printf(error::WARN, _(
"Could not remove temporary table: '%s', error: %d"), identifier.getSQLPath().c_str(), errno);
1811 bool Open_tables_state::rm_temporary_table(plugin::StorageEngine& base,
const identifier::Table &identifier)
1813 drizzled::error_t error;
1814 if (plugin::StorageEngine::dropTable(session_, base, identifier, error))
1816 errmsg_printf(error::WARN, _(
"Could not remove temporary table: '%s', error: %d"), identifier.getSQLPath().c_str(), error);
1820 table::Singular& Session::getInstanceTable()
1822 impl_->temporary_shares.push_back(
new table::Singular);
1823 return impl_->temporary_shares.back();
1847 impl_->temporary_shares.push_back(
new table::Singular(
this, field_list));
1848 return impl_->temporary_shares.back();
1851 void Session::clear_error(
bool full)
1857 drizzle_reset_errors(*
this,
true);
1860 void Session::clearDiagnostics()
1880 return impl_->diagnostics.is_error();
1884 void Session::my_ok(ha_rows affected_rows, ha_rows found_rows_arg, uint64_t passed_id,
const char *message)
1886 main_da().
set_ok_status(
this, affected_rows, found_rows_arg, passed_id, message);
1898 return variables.storage_engine ?
variables.storage_engine : global_system_variables.storage_engine;
1901 enum_tx_isolation Session::getTxIsolation()
const
1903 return (enum_tx_isolation)
variables.tx_isolation;
1908 return impl_->properties[arg];
1914 impl_->properties[arg]= value;
1917 plugin::EventObserverList* Session::getSchemaObservers(
const std::string &db_name)
1919 if (impl_c::schema_event_observers_t::mapped_type* i= find_ptr(impl_->schema_event_observers, db_name))
1924 plugin::EventObserverList* Session::setSchemaObservers(
const std::string &db_name, plugin::EventObserverList* observers)
1926 impl_->schema_event_observers.erase(db_name);
1928 impl_->schema_event_observers[db_name] = observers;
1932 util::string::ptr Session::schema()
const
1934 return impl_->schema;
1937 void Session::resetQueryString()
1940 impl_->state.reset();
1943 const boost::shared_ptr<session::State>& Session::state()
1945 return impl_->state;
1948 const std::string& display::type(drizzled::Session::global_read_lock_t type)
1950 static const std::string NONE=
"NONE";
1951 static const std::string GOT_GLOBAL_READ_LOCK=
"HAS GLOBAL READ LOCK";
1952 static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT=
"HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
1959 case Session::GOT_GLOBAL_READ_LOCK:
1960 return GOT_GLOBAL_READ_LOCK;
1961 case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
1962 return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1966 size_t display::max_string_length(drizzled::Session::global_read_lock_t)
1968 return display::type(Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT).size();