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++;
669 if (not in_db.empty() && schema::change(*
this,
identifier::Schema(catalog().identifier(), in_db)))
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);
709 while (not v.empty() && charset()->isspace(v.front()))
711 while (not v.empty() && (v.back() ==
';' || charset()->isspace(v.back())))
714 util::string::mptr new_query= boost::make_shared<std::string>(v.data(), v.size());
717 impl_->state= boost::make_shared<session::State>(v);
725 if (transaction.xid_state.xa_state != XA_NOTR)
727 my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
738 server_status&= ~SERVER_STATUS_IN_TRANS;
745 case COMMIT_AND_CHAIN:
746 result= endActiveTransaction();
747 if (result ==
true && completion == COMMIT_AND_CHAIN)
748 result= startTransaction();
750 case ROLLBACK_RELEASE:
753 case ROLLBACK_AND_CHAIN:
755 server_status&= ~SERVER_STATUS_IN_TRANS;
756 if (TransactionServices::rollbackTransaction(*
this,
true))
759 if (result ==
true && (completion == ROLLBACK_AND_CHAIN))
760 result= startTransaction();
764 my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
770 my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
772 else if (result && do_release)
774 setKilled(Session::KILL_CONNECTION);
780 bool Session::endActiveTransaction()
784 if (transaction.xid_state.xa_state != XA_NOTR)
786 my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
789 if (
options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
791 server_status&= ~SERVER_STATUS_IN_TRANS;
799 bool Session::startTransaction(start_transaction_option_t opt)
804 server_status|= SERVER_STATUS_IN_TRANS;
825 arg_of_last_insert_id_function=
false;
834 impl_->temporary_shares.clear();
860 field_list.push_back(
new Item_return_int(
"id",3, DRIZZLE_TYPE_LONGLONG));
866 field_list.push_back(item=
new Item_empty_string(
"possible_keys", NAME_CHAR_LEN*MAX_KEY, cs));
870 field_list.push_back(item=
new Item_empty_string(
"key_len", MAX_KEY * (MAX_KEY_LENGTH_DECIMAL_WIDTH + 1 ), cs));
872 field_list.push_back(item=
new Item_empty_string(
"ref", NAME_CHAR_LEN*MAX_REF_PARTS, cs));
874 field_list.push_back(item=
new Item_return_int(
"rows", 10, DRIZZLE_TYPE_LONGLONG));
875 if (lex().describe & DESCRIBE_EXTENDED)
877 field_list.push_back(item=
new Item_float(
"filtered", 0.1234, 2, 4));
881 field_list.push_back(
new Item_empty_string(
"Extra", 255, cs));
882 result->send_fields(field_list);
885 void select_result::send_error(drizzled::error_t errcode,
const char *err)
887 my_message(errcode, err, MYF(0));
894 void select_to_file::send_error(drizzled::error_t errcode,
const char *err)
896 my_message(errcode, err, MYF(0));
899 (void) cache->end_io_cache();
900 (void) internal::my_close(file, MYF(0));
901 (void) internal::my_delete(path.file_string().c_str(), MYF(0));
907 bool select_to_file::send_eof()
909 int error= test(cache->end_io_cache());
910 if (internal::my_close(file, MYF(MY_WME)))
926 void select_to_file::cleanup()
931 (void) cache->end_io_cache();
932 (void) internal::my_close(file, MYF(0));
939 select_to_file::select_to_file(file_exchange *ex)
942 cache(static_cast<internal::io_cache_st *>(memory::sql_calloc(sizeof(internal::io_cache_st)))),
948 select_to_file::~select_to_file()
957 select_export::~select_export()
979 static int create_file(Session& session,
980 fs::path &target_path,
981 file_exchange *exchange,
982 internal::io_cache_st *cache)
984 fs::path to_file(exchange->file_name);
986 if (not to_file.has_root_directory())
988 target_path= fs::system_complete(catalog::local_identifier().getPath());
989 util::string::ptr schema(session.schema());
990 if (not schema->empty())
992 int count_elements= 0;
993 for (fs::path::iterator it= to_file.begin(); it != to_file.end(); it++)
995 if (count_elements == 1)
996 target_path /= *schema;
998 target_path /= to_file;
1002 target_path = exchange->file_name;
1005 if (not secure_file_priv.string().empty())
1007 if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1010 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"--secure-file-priv");
1015 if (!access(target_path.file_string().c_str(), F_OK))
1017 my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1021 int file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME));
1024 (void) fchmod(file, 0666);
1025 if (cache->init_io_cache(file, 0, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1027 internal::my_close(file, MYF(0));
1028 internal::my_delete(target_path.file_string().c_str(), MYF(0));
1036 select_export::prepare(List<Item> &list, Select_Lex_Unit *u)
1039 bool string_results=
false, non_string_results=
false;
1041 if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1043 path= exchange->file_name;
1048 List<Item>::iterator li(list.begin());
1049 while (Item* item= li++)
1051 if (item->max_length >= MAX_BLOB_WIDTH)
1057 if (item->result_type() == STRING_RESULT)
1058 string_results=
true;
1060 non_string_results=
true;
1063 field_term_length=exchange->field_term->length();
1064 field_term_char= field_term_length ?
1065 (int) (
unsigned char) (*exchange->field_term)[0] : INT_MAX;
1066 if (!exchange->line_term->length())
1067 exchange->line_term=exchange->field_term;
1068 field_sep_char= exchange->enclosed->length() ? (int) (
unsigned char) (*exchange->enclosed)[0] : field_term_char;
1069 escape_char= exchange->escaped->length() ? (int) (
unsigned char) (*exchange->escaped)[0] : -1;
1070 is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
1071 is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
1072 line_sep_char= exchange->line_term->length() ? (int) (
unsigned char) (*exchange->line_term)[0] : INT_MAX;
1073 if (!field_term_length)
1074 exchange->opt_enclosed=0;
1075 if (!exchange->enclosed->length())
1076 exchange->opt_enclosed=1;
1077 fixed_row_size= (!field_term_length && !exchange->enclosed->length() &&
1079 if ((is_ambiguous_field_sep && exchange->enclosed->empty() && (string_results || is_unsafe_field_sep)) ||
1080 (exchange->opt_enclosed && non_string_results && field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
1082 my_error(ER_AMBIGUOUS_FIELD_TERM, MYF(0));
1086 if ((file= create_file(*session, path, exchange, cache)) < 0)
1092 bool select_export::send_data(List<Item> &items)
1094 char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
1095 bool space_inited=0;
1096 String tmp(buff,
sizeof(buff),&my_charset_bin),*res;
1099 if (unit->offset_limit_cnt)
1101 unit->offset_limit_cnt--;
1105 uint32_t used_length=0,items_left=items.size();
1106 List<Item>::iterator li(items.begin());
1108 if (cache->write(exchange->line_start->ptr(), exchange->line_start->length()))
1111 while (Item* item=li++)
1113 Item_result result_type=item->result_type();
1114 bool enclosed = (exchange->enclosed->length() &&
1115 (!exchange->opt_enclosed || result_type == STRING_RESULT));
1116 res=item->str_result(&tmp);
1117 if (res && enclosed)
1119 if (cache->write(exchange->enclosed->ptr(), exchange->enclosed->length()))
1124 if (!fixed_row_size)
1126 if (escape_char != -1)
1128 null_buff[0]=escape_char;
1130 if (cache->write(null_buff, 2))
1133 else if (cache->write(
"NULL", 4))
1144 used_length= min(res->length(),
static_cast<size_t>(item->max_length));
1146 used_length= res->length();
1148 if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1151 char *pos, *start, *end;
1152 const charset_info_st*
const res_charset= res->charset();
1154 for (start= pos= (
char*) res->ptr(),end=pos+used_length; pos != end; pos++)
1156 if (use_mb(res_charset))
1158 if (
int l= my_ismbchar(res_charset, pos, end))
1197 if (needs_escaping(*pos, enclosed) &&
1202 (enclosed || !is_ambiguous_field_term ||
1203 (int) (
unsigned char) *pos != field_term_char))
1206 tmp_buff[0]= ((int) (
unsigned char) *pos == field_sep_char &&
1207 is_ambiguous_field_sep) ? field_sep_char : escape_char;
1208 tmp_buff[1]= *pos ? *pos :
'0';
1209 if (cache->write(start, pos - start) || cache->write(tmp_buff, 2))
1214 if (cache->write(start, pos - start))
1217 else if (cache->write(res->ptr(), used_length))
1222 if (item->max_length > used_length)
1228 memset(space,
' ',
sizeof(space));
1230 uint32_t length=item->max_length-used_length;
1231 for (; length >
sizeof(space) ; length-=
sizeof(space))
1233 if (cache->write(space,
sizeof(space)))
1236 if (cache->write(space, length))
1240 if (res && enclosed)
1242 if (cache->write(exchange->enclosed->ptr(), exchange->enclosed->length()))
1247 if (cache->write(exchange->field_term->ptr(), field_term_length))
1251 if (cache->write(exchange->line_term->ptr(), exchange->line_term->length()))
1266 select_dump::prepare(List<Item> &, Select_Lex_Unit *u)
1269 return (file= create_file(*session, path, exchange, cache)) < 0;
1273 bool select_dump::send_data(List<Item> &items)
1275 List<Item>::iterator li(items.begin());
1276 char buff[MAX_FIELD_WIDTH];
1277 String tmp(buff,
sizeof(buff),&my_charset_bin),*res;
1280 if (unit->offset_limit_cnt)
1282 unit->offset_limit_cnt--;
1285 if (row_count++ > 1)
1287 my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
1290 while (Item* item=li++)
1292 res=item->str_result(&tmp);
1295 if (cache->write(
"", 1))
1298 else if (cache->write(res->ptr(), res->length()))
1300 my_error(ER_ERROR_ON_WRITE, MYF(0), path.file_string().c_str(), errno);
1308 select_subselect::select_subselect(Item_subselect *item_arg)
1314 bool select_singlerow_subselect::send_data(List<Item> &items)
1316 Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
1319 my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
1322 if (unit->offset_limit_cnt)
1324 unit->offset_limit_cnt--;
1327 List<Item>::iterator li(items.begin());
1329 for (uint32_t i= 0; (val_item= li++); i++)
1330 it->store(i, val_item);
1336 void select_max_min_finder_subselect::cleanup()
1342 bool select_max_min_finder_subselect::send_data(List<Item> &items)
1344 Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
1345 List<Item>::iterator li(items.begin());
1346 Item *val_item= li++;
1347 it->register_value();
1350 cache->store(val_item);
1352 it->store(0, cache);
1358 cache= Item_cache::get_cache(val_item);
1359 switch (val_item->result_type())
1362 op= &select_max_min_finder_subselect::cmp_real;
1365 op= &select_max_min_finder_subselect::cmp_int;
1368 op= &select_max_min_finder_subselect::cmp_str;
1370 case DECIMAL_RESULT:
1371 op= &select_max_min_finder_subselect::cmp_decimal;
1379 cache->store(val_item);
1380 it->store(0, cache);
1386 bool select_max_min_finder_subselect::cmp_real()
1388 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1389 double val1= cache->val_real(), val2= maxmin->val_real();
1391 return (cache->null_value && !maxmin->null_value) ||
1392 (!cache->null_value && !maxmin->null_value &&
1394 return (maxmin->null_value && !cache->null_value) ||
1395 (!cache->null_value && !maxmin->null_value &&
1399 bool select_max_min_finder_subselect::cmp_int()
1401 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1402 int64_t val1= cache->val_int(), val2= maxmin->val_int();
1404 return (cache->null_value && !maxmin->null_value) ||
1405 (!cache->null_value && !maxmin->null_value &&
1407 return (maxmin->null_value && !cache->null_value) ||
1408 (!cache->null_value && !maxmin->null_value &&
1412 bool select_max_min_finder_subselect::cmp_decimal()
1414 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1415 type::Decimal cval, *cvalue= cache->val_decimal(&cval);
1416 type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
1418 return (cache->null_value && !maxmin->null_value) ||
1419 (!cache->null_value && !maxmin->null_value &&
1421 return (maxmin->null_value && !cache->null_value) ||
1422 (!cache->null_value && !maxmin->null_value &&
1426 bool select_max_min_finder_subselect::cmp_str()
1428 String *val1, *val2, buf1, buf2;
1429 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1434 val1= cache->val_str(&buf1);
1435 val2= maxmin->val_str(&buf1);
1437 return (cache->null_value && !maxmin->null_value) ||
1438 (!cache->null_value && !maxmin->null_value &&
1439 sortcmp(val1, val2, cache->collation.collation) > 0) ;
1440 return (maxmin->null_value && !cache->null_value) ||
1441 (!cache->null_value && !maxmin->null_value &&
1442 sortcmp(val1, val2, cache->collation.collation) < 0);
1445 bool select_exists_subselect::send_data(List<Item> &)
1447 Item_exists_subselect *it= (Item_exists_subselect *)item;
1448 if (unit->offset_limit_cnt)
1450 unit->offset_limit_cnt--;
1469 str_ref Session::copy_db_to()
const
1471 if (not impl_->schema->empty())
1472 return str_ref(mem.
strdup(*impl_->schema), impl_->schema->size());
1473 my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1481 void Tmp_Table_Param::init()
1483 field_count= sum_func_count= func_count= hidden_field_count= 0;
1484 group_parts= group_length= group_null_parts= 0;
1487 precomputed_group_by= 0;
1490 void Tmp_Table_Param::cleanup()
1495 boost::checked_array_delete(copy_field);
1496 save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
1500 void Session::send_kill_message()
const
1502 drizzled::error_t err=
static_cast<drizzled::error_t
>(killed_errno());
1504 my_message(err, ER(err), MYF(0));
1509 impl_->schema = boost::make_shared<std::string>(new_db);
1528 plugin_sessionvar_cleanup(
this);
1531 if (getKilled() || client->wasAborted())
1533 status_var.aborted_threads++;
1536 if (client->wasAborted())
1538 if (not getKilled() &&
variables.log_warnings > 1)
1540 errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
1542 , (impl_->schema->empty() ?
"unconnected" : impl_->schema->c_str())
1543 , security_ctx->username().empty() ?
"unauthenticated" : security_ctx->username().c_str()
1544 , security_ctx->address().c_str()
1545 , (main_da().is_error() ? main_da().message() : ER(ER_UNKNOWN_ERROR)));
1549 setKilled(Session::KILL_CONNECTION);
1553 if (errcode != EE_OK)
1556 client->sendError(errcode, ER(errcode));
1568 server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
1569 SERVER_QUERY_NO_INDEX_USED |
1570 SERVER_QUERY_NO_GOOD_INDEX_USED);
1582 void Open_tables_state::close_temporary_tables()
1590 for (table= temporary_tables; table; table= tmp_next)
1592 tmp_next= table->getNext();
1595 temporary_tables= NULL;
1602 void Open_tables_state::close_temporary_table(Table *table)
1604 if (table->getPrev())
1606 table->getPrev()->setNext(table->getNext());
1607 if (table->getPrev()->getNext())
1609 table->getNext()->setPrev(table->getPrev());
1615 assert(table == temporary_tables);
1621 temporary_tables= table->getNext();
1622 if (temporary_tables)
1624 table->getNext()->setPrev(NULL);
1638 void Open_tables_state::nukeTable(Table *table)
1640 plugin::StorageEngine& table_type= *table->getShare()->db_type();
1641 table->free_io_cache();
1642 table->delete_table();
1643 rm_temporary_table(table_type, identifier::Table(table->getShare()->getTableIdentifier().getCatalog(), table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath()));
1644 boost::checked_delete(table->getMutableShare());
1645 boost::checked_delete(table);
1651 void Session::refresh_status()
1654 memset(&status_var, 0,
sizeof(status_var));
1656 flush_status_time= time((time_t*) 0);
1657 current_global_counters.max_used_connections= 1;
1658 current_global_counters.connections= 0;
1661 user_var_entry* Session::getVariable(
str_ref name0,
bool create_if_not_exists)
1666 string name(name0.data(), name0.size());
1667 if (UserVars::mapped_type* iter= find_ptr(
user_vars, name))
1670 if (not create_if_not_exists)
1673 user_var_entry *entry=
new user_var_entry(name.c_str(), query_id);
1675 std::pair<UserVars::iterator, bool> returnable=
user_vars.insert(make_pair(name, entry));
1677 if (not returnable.second)
1679 boost::checked_delete(entry);
1685 void Session::setVariable(
const std::string &name,
const std::string &value)
1687 if (user_var_entry* var= getVariable(name,
true))
1689 var->update_hash(
false, value, STRING_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
false);
1695 for (
Table *table= temporary_tables ; table ; table= table->getNext())
1697 if (table->query_id == session_.
getQueryId())
1700 table->cursor->ha_reset();
1716 open_tables.clearDerivedTables();
1734 transaction.
stmt.reset();
1737 if (open_tables.lock)
1739 unlockTables(open_tables.lock);
1740 open_tables.lock= 0;
1759 if (lex().first_not_own_table() == *tables)
1761 lex().chop_off_not_own_tables();
1774 if (open_tables_from_list(&tables, &counter))
1777 if (not lock_tables(tables, counter, &need_reopen))
1780 if (not need_reopen)
1786 return handle_derived(&lex(), &derived_prepare) || handle_derived(&lex(), &derived_filling);
1795 bool Open_tables_state::rm_temporary_table(
const identifier::Table &identifier,
bool best_effort)
1797 if (plugin::StorageEngine::dropTable(session_, identifier))
1799 if (not best_effort)
1800 errmsg_printf(error::WARN, _(
"Could not remove temporary table: '%s', error: %d"), identifier.getSQLPath().c_str(), errno);
1804 bool Open_tables_state::rm_temporary_table(plugin::StorageEngine& base,
const identifier::Table &identifier)
1806 drizzled::error_t error;
1807 if (plugin::StorageEngine::dropTable(session_, base, identifier, error))
1809 errmsg_printf(error::WARN, _(
"Could not remove temporary table: '%s', error: %d"), identifier.getSQLPath().c_str(), error);
1813 table::Singular& Session::getInstanceTable()
1815 impl_->temporary_shares.push_back(
new table::Singular);
1816 return impl_->temporary_shares.back();
1840 impl_->temporary_shares.push_back(
new table::Singular(
this, field_list));
1841 return impl_->temporary_shares.back();
1844 void Session::clear_error(
bool full)
1850 drizzle_reset_errors(*
this,
true);
1853 void Session::clearDiagnostics()
1873 return impl_->diagnostics.is_error();
1877 void Session::my_ok(ha_rows affected_rows, ha_rows found_rows_arg, uint64_t passed_id,
const char *message)
1879 main_da().
set_ok_status(
this, affected_rows, found_rows_arg, passed_id, message);
1891 return variables.storage_engine ?
variables.storage_engine : global_system_variables.storage_engine;
1894 enum_tx_isolation Session::getTxIsolation()
const
1896 return (enum_tx_isolation)
variables.tx_isolation;
1901 return impl_->properties[arg];
1907 impl_->properties[arg]= value;
1910 plugin::EventObserverList* Session::getSchemaObservers(
const std::string &db_name)
1912 if (impl_c::schema_event_observers_t::mapped_type* i= find_ptr(impl_->schema_event_observers, db_name))
1917 plugin::EventObserverList* Session::setSchemaObservers(
const std::string &db_name, plugin::EventObserverList* observers)
1919 impl_->schema_event_observers.erase(db_name);
1921 impl_->schema_event_observers[db_name] = observers;
1925 util::string::ptr Session::schema()
const
1927 return impl_->schema;
1930 void Session::resetQueryString()
1933 impl_->state.reset();
1936 const boost::shared_ptr<session::State>& Session::state()
1938 return impl_->state;
1941 const std::string& display::type(drizzled::Session::global_read_lock_t type)
1943 static const std::string NONE=
"NONE";
1944 static const std::string GOT_GLOBAL_READ_LOCK=
"HAS GLOBAL READ LOCK";
1945 static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT=
"HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
1952 case Session::GOT_GLOBAL_READ_LOCK:
1953 return GOT_GLOBAL_READ_LOCK;
1954 case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
1955 return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1959 size_t display::max_string_length(drizzled::Session::global_read_lock_t)
1961 return display::type(Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT).size();