00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00024 #include <config.h>
00025
00026 #include <boost/checked_delete.hpp>
00027 #include <boost/filesystem.hpp>
00028 #include <boost/ptr_container/ptr_container.hpp>
00029 #include <drizzled/copy_field.h>
00030 #include <drizzled/catalog/local.h>
00031 #include <drizzled/diagnostics_area.h>
00032 #include <drizzled/display.h>
00033 #include <drizzled/drizzled.h>
00034 #include <drizzled/error.h>
00035 #include <drizzled/gettext.h>
00036 #include <drizzled/ha_data.h>
00037 #include <drizzled/identifier.h>
00038 #include <drizzled/internal/iocache.h>
00039 #include <drizzled/internal/thread_var.h>
00040 #include <drizzled/item/cache.h>
00041 #include <drizzled/item/empty_string.h>
00042 #include <drizzled/item/float.h>
00043 #include <drizzled/item/return_int.h>
00044 #include <drizzled/item/subselect.h>
00045 #include <drizzled/lock.h>
00046 #include <drizzled/open_tables_state.h>
00047 #include <drizzled/plugin/authentication.h>
00048 #include <drizzled/plugin/authorization.h>
00049 #include <drizzled/plugin/client.h>
00050 #include <drizzled/plugin/event_observer.h>
00051 #include <drizzled/plugin/logging.h>
00052 #include <drizzled/plugin/query_rewrite.h>
00053 #include <drizzled/plugin/scheduler.h>
00054 #include <drizzled/plugin/transactional_storage_engine.h>
00055 #include <drizzled/probes.h>
00056 #include <drizzled/pthread_globals.h>
00057 #include <drizzled/schema.h>
00058 #include <drizzled/select_dump.h>
00059 #include <drizzled/select_exists_subselect.h>
00060 #include <drizzled/select_export.h>
00061 #include <drizzled/select_max_min_finder_subselect.h>
00062 #include <drizzled/select_singlerow_subselect.h>
00063 #include <drizzled/select_subselect.h>
00064 #include <drizzled/select_to_file.h>
00065 #include <drizzled/session.h>
00066 #include <drizzled/session/cache.h>
00067 #include <drizzled/session/state.h>
00068 #include <drizzled/session/table_messages.h>
00069 #include <drizzled/session/times.h>
00070 #include <drizzled/session/transactions.h>
00071 #include <drizzled/show.h>
00072 #include <drizzled/sql_base.h>
00073 #include <drizzled/sql_lex.h>
00074 #include <drizzled/system_variables.h>
00075 #include <drizzled/statement.h>
00076 #include <drizzled/statistics_variables.h>
00077 #include <drizzled/table/singular.h>
00078 #include <drizzled/table_proto.h>
00079 #include <drizzled/tmp_table_param.h>
00080 #include <drizzled/transaction_services.h>
00081 #include <drizzled/user_var_entry.h>
00082 #include <drizzled/util/backtrace.h>
00083 #include <drizzled/util/find_ptr.h>
00084 #include <drizzled/util/functors.h>
00085 #include <drizzled/util/storable.h>
00086 #include <plugin/myisam/myisam.h>
00087
00088 #include <algorithm>
00089 #include <climits>
00090 #include <fcntl.h>
00091 #include <sys/stat.h>
00092
00093 using namespace std;
00094
00095 namespace fs= boost::filesystem;
00096
00097 namespace drizzled {
00098
00099 const char* const Session::DEFAULT_WHERE= "field list";
00100
00101 uint64_t g_refresh_version = 1;
00102
00103 bool Key_part_spec::operator==(const Key_part_spec& other) const
00104 {
00105 return length == other.length
00106 && field_name.size() == other.field_name.size()
00107 && not system_charset_info->strcasecmp(field_name.data(), other.field_name.data());
00108 }
00109
00110 Open_tables_state::Open_tables_state(Session& session, uint64_t version_arg) :
00111 version(version_arg),
00112 session_(session)
00113 {
00114 open_tables_= temporary_tables= derived_tables= NULL;
00115 extra_lock= lock= NULL;
00116 }
00117
00118
00119
00120
00121 int tmpfile(const char *prefix)
00122 {
00123 char filename[FN_REFLEN];
00124 int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
00125 if (fd >= 0)
00126 unlink(filename);
00127 return fd;
00128 }
00129
00130 void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
00131 {
00132 return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
00133 }
00134
00135 ResourceContext& Session::getResourceContext(const plugin::MonitoredInTransaction& monitored, size_t index)
00136 {
00137 return ha_data[monitored.getId()].resource_context[index];
00138 }
00139
00140 int64_t session_test_options(const Session *session, int64_t test_options)
00141 {
00142 return session->options & test_options;
00143 }
00144
00145 class Session::impl_c
00146 {
00147 public:
00148 typedef boost::unordered_map<std::string, util::Storable*, util::insensitive_hash, util::insensitive_equal_to> properties_t;
00149 typedef std::map<std::string, plugin::EventObserverList*> schema_event_observers_t;
00150
00151 impl_c(Session& session) :
00152 open_tables(session, g_refresh_version),
00153 schema(boost::make_shared<std::string>())
00154 {
00155 }
00156
00157 ~impl_c()
00158 {
00159 BOOST_FOREACH(properties_t::reference it, properties)
00160 delete it.second;
00161 }
00162
00163 Diagnostics_area diagnostics;
00164 memory::Root mem_root;
00165
00172 LEX lex;
00173 Open_tables_state open_tables;
00174 properties_t properties;
00175 schema_event_observers_t schema_event_observers;
00176 system_status_var status_var;
00177 session::TableMessages table_message_cache;
00178 util::string::mptr schema;
00179 boost::shared_ptr<session::State> state;
00180 boost::ptr_vector<table::Singular> temporary_shares;
00181 session::Times times;
00182 session::Transactions transaction;
00183 drizzle_system_variables variables;
00184 };
00185
00186 Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
00187 impl_(new impl_c(*this)),
00188 mem(impl_->mem_root),
00189 mem_root(&impl_->mem_root),
00190 query(new std::string),
00191 scheduler(NULL),
00192 variables(impl_->variables),
00193 status_var(impl_->status_var),
00194 lock_id(&main_lock_id),
00195 thread_stack(NULL),
00196 _where(Session::DEFAULT_WHERE),
00197 mysys_var(0),
00198 command(COM_CONNECT),
00199 ha_data(plugin::num_trx_monitored_objects),
00200 query_id(0),
00201 warn_query_id(0),
00202 transaction(impl_->transaction),
00203 open_tables(impl_->open_tables),
00204 times(impl_->times),
00205 first_successful_insert_id_in_prev_stmt(0),
00206 first_successful_insert_id_in_cur_stmt(0),
00207 limit_found_rows(0),
00208 options(session_startup_options),
00209 row_count_func(-1),
00210 sent_row_count(0),
00211 examined_row_count(0),
00212 used_tables(0),
00213 total_warn_count(0),
00214 row_count(0),
00215 thread_id(0),
00216 tmp_table(0),
00217 _global_read_lock(NONE),
00218 count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
00219 _killed(NOT_KILLED),
00220 no_errors(false),
00221 is_fatal_error(false),
00222 transaction_rollback_request(false),
00223 is_fatal_sub_stmt_error(0),
00224 derived_tables_processing(false),
00225 m_lip(NULL),
00226 arg_of_last_insert_id_function(false),
00227 _catalog(catalog_arg),
00228 transaction_message(NULL),
00229 statement_message(NULL),
00230 session_event_observers(NULL),
00231 xa_id(0),
00232 concurrent_execute_allowed(true),
00233 tablespace_op(false),
00234 use_usage(false),
00235 security_ctx(identifier::User::make_shared()),
00236 originating_server_uuid_set(false),
00237 client(client_arg)
00238 {
00239 client->setSession(this);
00240
00241
00242
00243
00244
00245
00246 mem.init(memory::ROOT_MIN_BLOCK_SIZE);
00247 cuted_fields= sent_row_count= row_count= 0L;
00248
00249 lex().current_select= 0;
00250 memset(&variables, 0, sizeof(variables));
00251 scoreboard_index= -1;
00252 originating_server_uuid= "";
00253 originating_commit_id= 0;
00254 cleanup_done= abort_on_warning= no_warnings_for_error= false;
00255
00256 resultset= NULL;
00257
00258
00259 proc_info="login";
00260
00261 plugin_sessionvar_init(this);
00262
00263
00264
00265
00266
00267 variables.pseudo_thread_id= thread_id;
00268 server_status= SERVER_STATUS_AUTOCOMMIT;
00269
00270 if (variables.max_join_size == HA_POS_ERROR)
00271 options |= OPTION_BIG_SELECTS;
00272 else
00273 options &= ~OPTION_BIG_SELECTS;
00274
00275 open_options=ha_open_options;
00276 update_lock_default= TL_WRITE;
00277 session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
00278 memset(warn_count, 0, sizeof(warn_count));
00279 memset(&status_var, 0, sizeof(status_var));
00280
00281
00282 warn_root.init(WARN_ALLOC_BLOCK_SIZE);
00283
00284 substitute_null_with_insert_id = false;
00285 lock_info.init();
00286 main_lock_id.info= &lock_info;
00287
00288 plugin::EventObserver::registerSessionEvents(*this);
00289 }
00290
00291 Diagnostics_area& Session::main_da()
00292 {
00293 return impl_->diagnostics;
00294 }
00295
00296 const LEX& Session::lex() const
00297 {
00298 return impl_->lex;
00299 }
00300
00301 LEX& Session::lex()
00302 {
00303 return impl_->lex;
00304 }
00305
00306 enum_sql_command Session::getSqlCommand() const
00307 {
00308 return lex().sql_command;
00309 }
00310
00311 session::TableMessages& Session::getMessageCache()
00312 {
00313 return impl_->table_message_cache;
00314 }
00315
00316 void statement::Statement::set_command(enum_sql_command v)
00317 {
00318 session().lex().sql_command= v;
00319 }
00320
00321 LEX& statement::Statement::lex()
00322 {
00323 return session().lex();
00324 }
00325
00326 session::Transactions& statement::Statement::transaction()
00327 {
00328 return session().transaction;
00329 }
00330
00331 void Session::add_item_to_list(Item *item)
00332 {
00333 lex().current_select->add_item_to_list(this, item);
00334 }
00335
00336 void Session::add_value_to_list(Item *value)
00337 {
00338 lex().value_list.push_back(value);
00339 }
00340
00341 void Session::add_order_to_list(Item *item, bool asc)
00342 {
00343 lex().current_select->add_order_to_list(this, item, asc);
00344 }
00345
00346 void Session::add_group_to_list(Item *item, bool asc)
00347 {
00348 lex().current_select->add_group_to_list(this, item, asc);
00349 }
00350
00351 void Session::free_items()
00352 {
00353
00354 for (Item* next; free_list; free_list= next)
00355 {
00356 next= free_list->next;
00357 free_list->delete_self();
00358 }
00359 }
00360
00361 void Session::setAbort(bool arg)
00362 {
00363 mysys_var->abort= arg;
00364 }
00365
00366 void Session::lockOnSys()
00367 {
00368 if (not mysys_var)
00369 return;
00370
00371 setAbort(true);
00372 boost::mutex::scoped_lock scopedLock(mysys_var->mutex);
00373 if (mysys_var->current_cond)
00374 {
00375 mysys_var->current_mutex->lock();
00376 mysys_var->current_cond->notify_all();
00377 mysys_var->current_mutex->unlock();
00378 }
00379 }
00380
00381 void Session::get_xid(DrizzleXid *xid) const
00382 {
00383 *xid = *(DrizzleXid *) &transaction.xid_state.xid;
00384 }
00385
00386
00387
00388 void Session::cleanup()
00389 {
00390 assert(not cleanup_done);
00391
00392 setKilled(KILL_CONNECTION);
00393 #ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
00394 if (transaction.xid_state.xa_state == XA_PREPARED)
00395 {
00396 #error xid_state in the cache should be replaced by the allocated value
00397 }
00398 #endif
00399 {
00400 TransactionServices::rollbackTransaction(*this, true);
00401 }
00402
00403 BOOST_FOREACH(UserVars::reference iter, user_vars)
00404 boost::checked_delete(iter.second);
00405 user_vars.clear();
00406
00407 open_tables.close_temporary_tables();
00408
00409 if (global_read_lock)
00410 unlockGlobalReadLock();
00411
00412 cleanup_done= true;
00413 }
00414
00415 Session::~Session()
00416 {
00417 if (client and client->isConnected())
00418 {
00419 assert(security_ctx);
00420 if (global_system_variables.log_warnings)
00421 {
00422 errmsg_printf(error::WARN, ER(ER_FORCING_CLOSE), internal::my_progname, thread_id, security_ctx->username().c_str());
00423 }
00424
00425 disconnect();
00426 }
00427
00428
00429 if (client)
00430 {
00431 client->close();
00432 boost::checked_delete(client);
00433 client= NULL;
00434 }
00435
00436 if (not cleanup_done)
00437 cleanup();
00438
00439 plugin::StorageEngine::closeConnection(*this);
00440 plugin_sessionvar_cleanup(this);
00441
00442 warn_root.free_root(MYF(0));
00443 mysys_var=0;
00444
00445 impl_->mem_root.free_root(MYF(0));
00446 setCurrentMemRoot(NULL);
00447 setCurrentSession(NULL);
00448
00449 plugin::Logging::postEndDo(this);
00450 plugin::EventObserver::deregisterSessionEvents(session_event_observers);
00451
00452 BOOST_FOREACH(impl_c::schema_event_observers_t::reference it, impl_->schema_event_observers)
00453 plugin::EventObserver::deregisterSchemaEvents(it.second);
00454 }
00455
00456 void Session::setClient(plugin::Client *client_arg)
00457 {
00458 client= client_arg;
00459 client->setSession(this);
00460 }
00461
00462 void Session::awake(Session::killed_state_t state_to_set)
00463 {
00464 if (state_to_set == Session::KILL_QUERY && command == COM_SLEEP)
00465 return;
00466
00467 setKilled(state_to_set);
00468 scheduler->killSession(this);
00469
00470 if (state_to_set != Session::KILL_QUERY)
00471 {
00472 DRIZZLE_CONNECTION_DONE(thread_id);
00473 }
00474
00475 if (mysys_var)
00476 {
00477 boost::mutex::scoped_lock scopedLock(mysys_var->mutex);
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 if (mysys_var->current_cond && mysys_var->current_mutex)
00499 {
00500 mysys_var->current_mutex->lock();
00501 mysys_var->current_cond->notify_all();
00502 mysys_var->current_mutex->unlock();
00503 }
00504 }
00505 }
00506
00507
00508
00509
00510
00511 void Session::storeGlobals()
00512 {
00513
00514
00515
00516
00517 assert(thread_stack);
00518 setCurrentSession(this);
00519 setCurrentMemRoot(&mem);
00520
00521 mysys_var= internal::my_thread_var2().get();
00522
00523
00524
00525
00526
00527 mysys_var->id= thread_id;
00528
00529
00530
00531
00532
00533 lock_info.init();
00534 }
00535
00536
00537
00538
00539
00540
00541
00542 void Session::prepareForQueries()
00543 {
00544 if (variables.max_join_size == HA_POS_ERROR)
00545 options |= OPTION_BIG_SELECTS;
00546
00547 open_tables.version= g_refresh_version;
00548 set_proc_info(NULL);
00549 command= COM_SLEEP;
00550 times.set_time();
00551
00552 mem.reset_defaults(variables.query_alloc_block_size, variables.query_prealloc_size);
00553 transaction.xid_state.xid.set_null();
00554 transaction.xid_state.in_session=1;
00555 if (use_usage)
00556 resetUsage();
00557 }
00558
00559 void Session::run()
00560 {
00561 storeGlobals();
00562 if (authenticate())
00563 {
00564 disconnect();
00565 return;
00566 }
00567 prepareForQueries();
00568 while (not client->haveError() && getKilled() != KILL_CONNECTION)
00569 {
00570 if (not executeStatement())
00571 break;
00572 }
00573 disconnect();
00574 }
00575
00576 bool Session::schedule(const shared_ptr& arg)
00577 {
00578 arg->scheduler= plugin::Scheduler::getScheduler();
00579 assert(arg->scheduler);
00580
00581 ++connection_count;
00582
00583 long current_connections= connection_count;
00584
00585 if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
00586 {
00587 current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
00588 }
00589
00590 current_global_counters.connections++;
00591 arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
00592
00593 session::Cache::insert(arg);
00594
00595 if (unlikely(plugin::EventObserver::connectSession(*arg)))
00596 {
00597
00598 }
00599
00600 if (plugin::Scheduler::getScheduler()->addSession(arg))
00601 {
00602 DRIZZLE_CONNECTION_START(arg->getSessionId());
00603 char error_message_buff[DRIZZLE_ERRMSG_SIZE];
00604
00605 arg->setKilled(Session::KILL_CONNECTION);
00606
00607 arg->status_var.aborted_connects++;
00608
00609
00610
00611 snprintf(error_message_buff, sizeof(error_message_buff), ER(ER_CANT_CREATE_THREAD), 1);
00612 arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
00613 return true;
00614 }
00615 return false;
00616 }
00617
00618
00619
00620
00621
00622 bool Session::isViewable(const identifier::User& user_arg) const
00623 {
00624 return plugin::Authorization::isAuthorized(user_arg, *this, false);
00625 }
00626
00627
00628 const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
00629 {
00630 const char* old_msg = get_proc_info();
00631 safe_mutex_assert_owner(mutex);
00632 mysys_var->current_mutex = &mutex;
00633 mysys_var->current_cond = &cond;
00634 this->set_proc_info(msg);
00635 return old_msg;
00636 }
00637
00638 void Session::exit_cond(const char* old_msg)
00639 {
00640
00641
00642
00643
00644
00645
00646 mysys_var->current_mutex->unlock();
00647 boost::mutex::scoped_lock scopedLock(mysys_var->mutex);
00648 mysys_var->current_mutex = 0;
00649 mysys_var->current_cond = 0;
00650 this->set_proc_info(old_msg);
00651 }
00652
00653 bool Session::authenticate()
00654 {
00655 if (client->authenticate())
00656 return false;
00657
00658 status_var.aborted_connects++;
00659
00660 return true;
00661 }
00662
00663 bool Session::checkUser(const std::string &passwd_str, const std::string &in_db)
00664 {
00665 if (not plugin::Authentication::isAuthenticated(*user(), passwd_str))
00666 {
00667 status_var.access_denied++;
00668
00669 return false;
00670 }
00671
00672
00673 if (not in_db.empty() && schema::change(*this, identifier::Schema(in_db)))
00674 return false;
00675 my_ok();
00676
00677
00678 return true;
00679 }
00680
00681 bool Session::executeStatement()
00682 {
00683
00684
00685
00686
00687 lex().current_select= 0;
00688 clear_error();
00689 main_da().reset_diagnostics_area();
00690 char *l_packet= 0;
00691 uint32_t packet_length;
00692 if (not client->readCommand(&l_packet, packet_length))
00693 return false;
00694
00695 if (getKilled() == KILL_CONNECTION)
00696 return false;
00697
00698 if (packet_length == 0)
00699 return true;
00700
00701 enum_server_command l_command= static_cast<enum_server_command>(l_packet[0]);
00702
00703 if (command >= COM_END)
00704 command= COM_END;
00705
00706 assert(packet_length);
00707 return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
00708 }
00709
00710 void Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
00711 {
00712
00713 while (in_packet_length > 0 && charset()->isspace(in_packet[0]))
00714 {
00715 in_packet++;
00716 in_packet_length--;
00717 }
00718 const char *pos= in_packet + in_packet_length;
00719 while (in_packet_length > 0 && (pos[-1] == ';' || charset()->isspace(pos[-1])))
00720 {
00721 pos--;
00722 in_packet_length--;
00723 }
00724
00725 util::string::mptr new_query= boost::make_shared<std::string>(in_packet, in_packet_length);
00726 plugin::QueryRewriter::rewriteQuery(*impl_->schema, *new_query);
00727 query= new_query;
00728 impl_->state= boost::make_shared<session::State>(in_packet, in_packet_length);
00729 }
00730
00731 bool Session::endTransaction(enum_mysql_completiontype completion)
00732 {
00733 bool do_release= 0;
00734 bool result= true;
00735
00736 if (transaction.xid_state.xa_state != XA_NOTR)
00737 {
00738 my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
00739 return false;
00740 }
00741 switch (completion)
00742 {
00743 case COMMIT:
00744
00745
00746
00747
00748
00749 server_status&= ~SERVER_STATUS_IN_TRANS;
00750 if (TransactionServices::commitTransaction(*this, true))
00751 result= false;
00752 options&= ~(OPTION_BEGIN);
00753 break;
00754 case COMMIT_RELEASE:
00755 do_release= 1;
00756 case COMMIT_AND_CHAIN:
00757 result= endActiveTransaction();
00758 if (result == true && completion == COMMIT_AND_CHAIN)
00759 result= startTransaction();
00760 break;
00761 case ROLLBACK_RELEASE:
00762 do_release= 1;
00763 case ROLLBACK:
00764 case ROLLBACK_AND_CHAIN:
00765 {
00766 server_status&= ~SERVER_STATUS_IN_TRANS;
00767 if (TransactionServices::rollbackTransaction(*this, true))
00768 result= false;
00769 options&= ~(OPTION_BEGIN);
00770 if (result == true && (completion == ROLLBACK_AND_CHAIN))
00771 result= startTransaction();
00772 break;
00773 }
00774 default:
00775 my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
00776 return false;
00777 }
00778
00779 if (not result)
00780 {
00781 my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
00782 }
00783 else if (result && do_release)
00784 {
00785 setKilled(Session::KILL_CONNECTION);
00786 }
00787
00788 return result;
00789 }
00790
00791 bool Session::endActiveTransaction()
00792 {
00793 bool result= true;
00794
00795 if (transaction.xid_state.xa_state != XA_NOTR)
00796 {
00797 my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
00798 return false;
00799 }
00800 if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
00801 {
00802 server_status&= ~SERVER_STATUS_IN_TRANS;
00803 if (TransactionServices::commitTransaction(*this, true))
00804 result= false;
00805 }
00806 options&= ~(OPTION_BEGIN);
00807 return result;
00808 }
00809
00810 bool Session::startTransaction(start_transaction_option_t opt)
00811 {
00812 assert(not inTransaction());
00813
00814 options|= OPTION_BEGIN;
00815 server_status|= SERVER_STATUS_IN_TRANS;
00816
00817 if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
00818 return false;
00819 return true;
00820 }
00821
00822 void Session::cleanup_after_query()
00823 {
00824
00825
00826
00827
00828 if (first_successful_insert_id_in_cur_stmt > 0)
00829 {
00830
00831 first_successful_insert_id_in_prev_stmt= first_successful_insert_id_in_cur_stmt;
00832 first_successful_insert_id_in_cur_stmt= 0;
00833 substitute_null_with_insert_id= true;
00834 }
00835
00836 arg_of_last_insert_id_function= false;
00837
00838
00839 free_items();
00840
00841
00842 _where= Session::DEFAULT_WHERE;
00843
00844
00845 impl_->temporary_shares.clear();
00846 }
00847
00858 lex_string_t* Session::make_lex_string(lex_string_t* lex_str, str_ref str)
00859 {
00860 if (not lex_str)
00861 lex_str= new (mem) lex_string_t;
00862 lex_str->assign(mem_root->strdup(str), str.size());
00863 return lex_str;
00864 }
00865
00866 void Session::send_explain_fields(select_result *result)
00867 {
00868 List<Item> field_list;
00869 Item *item;
00870 const charset_info_st* cs= system_charset_info;
00871 field_list.push_back(new Item_return_int("id",3, DRIZZLE_TYPE_LONGLONG));
00872 field_list.push_back(new Item_empty_string("select_type", 19, cs));
00873 field_list.push_back(item= new Item_empty_string("table", NAME_CHAR_LEN, cs));
00874 item->maybe_null= 1;
00875 field_list.push_back(item= new Item_empty_string("type", 10, cs));
00876 item->maybe_null= 1;
00877 field_list.push_back(item= new Item_empty_string("possible_keys", NAME_CHAR_LEN*MAX_KEY, cs));
00878 item->maybe_null=1;
00879 field_list.push_back(item= new Item_empty_string("key", NAME_CHAR_LEN, cs));
00880 item->maybe_null=1;
00881 field_list.push_back(item= new Item_empty_string("key_len", MAX_KEY * (MAX_KEY_LENGTH_DECIMAL_WIDTH + 1 ), cs));
00882 item->maybe_null=1;
00883 field_list.push_back(item= new Item_empty_string("ref", NAME_CHAR_LEN*MAX_REF_PARTS, cs));
00884 item->maybe_null=1;
00885 field_list.push_back(item= new Item_return_int("rows", 10, DRIZZLE_TYPE_LONGLONG));
00886 if (lex().describe & DESCRIBE_EXTENDED)
00887 {
00888 field_list.push_back(item= new Item_float("filtered", 0.1234, 2, 4));
00889 item->maybe_null=1;
00890 }
00891 item->maybe_null= 1;
00892 field_list.push_back(new Item_empty_string("Extra", 255, cs));
00893 result->send_fields(field_list);
00894 }
00895
00896 void select_result::send_error(drizzled::error_t errcode, const char *err)
00897 {
00898 my_message(errcode, err, MYF(0));
00899 }
00900
00901
00902
00903
00904
00905 void select_to_file::send_error(drizzled::error_t errcode,const char *err)
00906 {
00907 my_message(errcode, err, MYF(0));
00908 if (file > 0)
00909 {
00910 (void) cache->end_io_cache();
00911 (void) internal::my_close(file, MYF(0));
00912 (void) internal::my_delete(path.file_string().c_str(), MYF(0));
00913 file= -1;
00914 }
00915 }
00916
00917
00918 bool select_to_file::send_eof()
00919 {
00920 int error= test(cache->end_io_cache());
00921 if (internal::my_close(file, MYF(MY_WME)))
00922 error= 1;
00923 if (!error)
00924 {
00925
00926
00927
00928
00929
00930 session->my_ok(row_count);
00931 }
00932 file= -1;
00933 return error;
00934 }
00935
00936
00937 void select_to_file::cleanup()
00938 {
00939
00940 if (file >= 0)
00941 {
00942 (void) cache->end_io_cache();
00943 (void) internal::my_close(file, MYF(0));
00944 file= -1;
00945 }
00946 path= "";
00947 row_count= 0;
00948 }
00949
00950 select_to_file::select_to_file(file_exchange *ex)
00951 : exchange(ex),
00952 file(-1),
00953 cache(static_cast<internal::io_cache_st *>(memory::sql_calloc(sizeof(internal::io_cache_st)))),
00954 row_count(0L)
00955 {
00956 path= "";
00957 }
00958
00959 select_to_file::~select_to_file()
00960 {
00961 cleanup();
00962 }
00963
00964
00965
00966
00967
00968 select_export::~select_export()
00969 {
00970 session->sent_row_count=row_count;
00971 }
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990 static int create_file(Session& session,
00991 fs::path &target_path,
00992 file_exchange *exchange,
00993 internal::io_cache_st *cache)
00994 {
00995 fs::path to_file(exchange->file_name);
00996
00997 if (not to_file.has_root_directory())
00998 {
00999 target_path= fs::system_complete(catalog::local_identifier().getPath());
01000 util::string::ptr schema(session.schema());
01001 if (not schema->empty())
01002 {
01003 int count_elements= 0;
01004 for (fs::path::iterator it= to_file.begin(); it != to_file.end(); it++)
01005 count_elements++;
01006 if (count_elements == 1)
01007 target_path /= *schema;
01008 }
01009 target_path /= to_file;
01010 }
01011 else
01012 {
01013 target_path = exchange->file_name;
01014 }
01015
01016 if (not secure_file_priv.string().empty())
01017 {
01018 if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
01019 {
01020
01021 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
01022 return -1;
01023 }
01024 }
01025
01026 if (!access(target_path.file_string().c_str(), F_OK))
01027 {
01028 my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
01029 return -1;
01030 }
01031
01032 int file= internal::my_create(target_path.file_string().c_str(), 0666, O_WRONLY|O_EXCL, MYF(MY_WME));
01033 if (file < 0)
01034 return file;
01035 (void) fchmod(file, 0666);
01036 if (cache->init_io_cache(file, 0, internal::WRITE_CACHE, 0L, 1, MYF(MY_WME)))
01037 {
01038 internal::my_close(file, MYF(0));
01039 internal::my_delete(target_path.file_string().c_str(), MYF(0));
01040 return -1;
01041 }
01042 return file;
01043 }
01044
01045
01046 int
01047 select_export::prepare(List<Item> &list, Select_Lex_Unit *u)
01048 {
01049 bool blob_flag=0;
01050 bool string_results= false, non_string_results= false;
01051 unit= u;
01052 if ((uint32_t) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
01053 {
01054 path= exchange->file_name;
01055 }
01056
01057
01058 {
01059 List<Item>::iterator li(list.begin());
01060 while (Item* item= li++)
01061 {
01062 if (item->max_length >= MAX_BLOB_WIDTH)
01063 {
01064 blob_flag=1;
01065 break;
01066 }
01067
01068 if (item->result_type() == STRING_RESULT)
01069 string_results= true;
01070 else
01071 non_string_results= true;
01072 }
01073 }
01074 field_term_length=exchange->field_term->length();
01075 field_term_char= field_term_length ?
01076 (int) (unsigned char) (*exchange->field_term)[0] : INT_MAX;
01077 if (!exchange->line_term->length())
01078 exchange->line_term=exchange->field_term;
01079 field_sep_char= exchange->enclosed->length() ? (int) (unsigned char) (*exchange->enclosed)[0] : field_term_char;
01080 escape_char= exchange->escaped->length() ? (int) (unsigned char) (*exchange->escaped)[0] : -1;
01081 is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
01082 is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
01083 line_sep_char= exchange->line_term->length() ? (int) (unsigned char) (*exchange->line_term)[0] : INT_MAX;
01084 if (!field_term_length)
01085 exchange->opt_enclosed=0;
01086 if (!exchange->enclosed->length())
01087 exchange->opt_enclosed=1;
01088 fixed_row_size= (!field_term_length && !exchange->enclosed->length() &&
01089 !blob_flag);
01090 if ((is_ambiguous_field_sep && exchange->enclosed->empty() && (string_results || is_unsafe_field_sep)) ||
01091 (exchange->opt_enclosed && non_string_results && field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
01092 {
01093 my_error(ER_AMBIGUOUS_FIELD_TERM, MYF(0));
01094 return 1;
01095 }
01096
01097 if ((file= create_file(*session, path, exchange, cache)) < 0)
01098 return 1;
01099
01100 return 0;
01101 }
01102
01103 bool select_export::send_data(List<Item> &items)
01104 {
01105 char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
01106 bool space_inited=0;
01107 String tmp(buff,sizeof(buff),&my_charset_bin),*res;
01108 tmp.length(0);
01109
01110 if (unit->offset_limit_cnt)
01111 {
01112 unit->offset_limit_cnt--;
01113 return false;
01114 }
01115 row_count++;
01116 uint32_t used_length=0,items_left=items.size();
01117 List<Item>::iterator li(items.begin());
01118
01119 if (cache->write(exchange->line_start->ptr(), exchange->line_start->length()))
01120 return true;
01121
01122 while (Item* item=li++)
01123 {
01124 Item_result result_type=item->result_type();
01125 bool enclosed = (exchange->enclosed->length() &&
01126 (!exchange->opt_enclosed || result_type == STRING_RESULT));
01127 res=item->str_result(&tmp);
01128 if (res && enclosed)
01129 {
01130 if (cache->write(exchange->enclosed->ptr(), exchange->enclosed->length()))
01131 return true;
01132 }
01133 if (!res)
01134 {
01135 if (!fixed_row_size)
01136 {
01137 if (escape_char != -1)
01138 {
01139 null_buff[0]=escape_char;
01140 null_buff[1]='N';
01141 if (cache->write(null_buff, 2))
01142 return true;
01143 }
01144 else if (cache->write("NULL", 4))
01145 return true;
01146 }
01147 else
01148 {
01149 used_length=0;
01150 }
01151 }
01152 else
01153 {
01154 if (fixed_row_size)
01155 used_length= min(res->length(), static_cast<size_t>(item->max_length));
01156 else
01157 used_length= res->length();
01158
01159 if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
01160 escape_char != -1)
01161 {
01162 char *pos, *start, *end;
01163 const charset_info_st* const res_charset= res->charset();
01164
01165 for (start= pos= (char*) res->ptr(),end=pos+used_length; pos != end; pos++)
01166 {
01167 if (use_mb(res_charset))
01168 {
01169 if (int l= my_ismbchar(res_charset, pos, end))
01170 {
01171 pos += l - 1;
01172 continue;
01173 }
01174 }
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 if (needs_escaping(*pos, enclosed) &&
01209
01210
01211
01212
01213 (enclosed || !is_ambiguous_field_term ||
01214 (int) (unsigned char) *pos != field_term_char))
01215 {
01216 char tmp_buff[2];
01217 tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
01218 is_ambiguous_field_sep) ? field_sep_char : escape_char;
01219 tmp_buff[1]= *pos ? *pos : '0';
01220 if (cache->write(start, pos - start) || cache->write(tmp_buff, 2))
01221 return true;
01222 start=pos+1;
01223 }
01224 }
01225 if (cache->write(start, pos - start))
01226 return true;
01227 }
01228 else if (cache->write(res->ptr(), used_length))
01229 return true;
01230 }
01231 if (fixed_row_size)
01232 {
01233 if (item->max_length > used_length)
01234 {
01235
01236 if (!space_inited)
01237 {
01238 space_inited=1;
01239 memset(space, ' ', sizeof(space));
01240 }
01241 uint32_t length=item->max_length-used_length;
01242 for (; length > sizeof(space) ; length-=sizeof(space))
01243 {
01244 if (cache->write(space, sizeof(space)))
01245 return true;
01246 }
01247 if (cache->write(space, length))
01248 return true;
01249 }
01250 }
01251 if (res && enclosed)
01252 {
01253 if (cache->write(exchange->enclosed->ptr(), exchange->enclosed->length()))
01254 return true;
01255 }
01256 if (--items_left)
01257 {
01258 if (cache->write(exchange->field_term->ptr(), field_term_length))
01259 return true;
01260 }
01261 }
01262 if (cache->write(exchange->line_term->ptr(), exchange->line_term->length()))
01263 {
01264 return true;
01265 }
01266
01267 return false;
01268 }
01269
01270
01271
01272
01273
01274
01275
01276 int
01277 select_dump::prepare(List<Item> &, Select_Lex_Unit *u)
01278 {
01279 unit= u;
01280 return (file= create_file(*session, path, exchange, cache)) < 0;
01281 }
01282
01283
01284 bool select_dump::send_data(List<Item> &items)
01285 {
01286 List<Item>::iterator li(items.begin());
01287 char buff[MAX_FIELD_WIDTH];
01288 String tmp(buff,sizeof(buff),&my_charset_bin),*res;
01289 tmp.length(0);
01290
01291 if (unit->offset_limit_cnt)
01292 {
01293 unit->offset_limit_cnt--;
01294 return 0;
01295 }
01296 if (row_count++ > 1)
01297 {
01298 my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
01299 return 1;
01300 }
01301 while (Item* item=li++)
01302 {
01303 res=item->str_result(&tmp);
01304 if (!res)
01305 {
01306 if (cache->write("", 1))
01307 return 1;
01308 }
01309 else if (cache->write(res->ptr(), res->length()))
01310 {
01311 my_error(ER_ERROR_ON_WRITE, MYF(0), path.file_string().c_str(), errno);
01312 return 1;
01313 }
01314 }
01315 return 0;
01316 }
01317
01318
01319 select_subselect::select_subselect(Item_subselect *item_arg)
01320 {
01321 item= item_arg;
01322 }
01323
01324
01325 bool select_singlerow_subselect::send_data(List<Item> &items)
01326 {
01327 Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
01328 if (it->assigned())
01329 {
01330 my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
01331 return 1;
01332 }
01333 if (unit->offset_limit_cnt)
01334 {
01335 unit->offset_limit_cnt--;
01336 return 0;
01337 }
01338 List<Item>::iterator li(items.begin());
01339 Item *val_item;
01340 for (uint32_t i= 0; (val_item= li++); i++)
01341 it->store(i, val_item);
01342 it->assigned(1);
01343 return 0;
01344 }
01345
01346
01347 void select_max_min_finder_subselect::cleanup()
01348 {
01349 cache= 0;
01350 }
01351
01352
01353 bool select_max_min_finder_subselect::send_data(List<Item> &items)
01354 {
01355 Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
01356 List<Item>::iterator li(items.begin());
01357 Item *val_item= li++;
01358 it->register_value();
01359 if (it->assigned())
01360 {
01361 cache->store(val_item);
01362 if ((this->*op)())
01363 it->store(0, cache);
01364 }
01365 else
01366 {
01367 if (!cache)
01368 {
01369 cache= Item_cache::get_cache(val_item);
01370 switch (val_item->result_type())
01371 {
01372 case REAL_RESULT:
01373 op= &select_max_min_finder_subselect::cmp_real;
01374 break;
01375 case INT_RESULT:
01376 op= &select_max_min_finder_subselect::cmp_int;
01377 break;
01378 case STRING_RESULT:
01379 op= &select_max_min_finder_subselect::cmp_str;
01380 break;
01381 case DECIMAL_RESULT:
01382 op= &select_max_min_finder_subselect::cmp_decimal;
01383 break;
01384 case ROW_RESULT:
01385
01386 assert(0);
01387 op= 0;
01388 }
01389 }
01390 cache->store(val_item);
01391 it->store(0, cache);
01392 }
01393 it->assigned(1);
01394 return 0;
01395 }
01396
01397 bool select_max_min_finder_subselect::cmp_real()
01398 {
01399 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
01400 double val1= cache->val_real(), val2= maxmin->val_real();
01401 if (fmax)
01402 return (cache->null_value && !maxmin->null_value) ||
01403 (!cache->null_value && !maxmin->null_value &&
01404 val1 > val2);
01405 return (maxmin->null_value && !cache->null_value) ||
01406 (!cache->null_value && !maxmin->null_value &&
01407 val1 < val2);
01408 }
01409
01410 bool select_max_min_finder_subselect::cmp_int()
01411 {
01412 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
01413 int64_t val1= cache->val_int(), val2= maxmin->val_int();
01414 if (fmax)
01415 return (cache->null_value && !maxmin->null_value) ||
01416 (!cache->null_value && !maxmin->null_value &&
01417 val1 > val2);
01418 return (maxmin->null_value && !cache->null_value) ||
01419 (!cache->null_value && !maxmin->null_value &&
01420 val1 < val2);
01421 }
01422
01423 bool select_max_min_finder_subselect::cmp_decimal()
01424 {
01425 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
01426 type::Decimal cval, *cvalue= cache->val_decimal(&cval);
01427 type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
01428 if (fmax)
01429 return (cache->null_value && !maxmin->null_value) ||
01430 (!cache->null_value && !maxmin->null_value &&
01431 class_decimal_cmp(cvalue, mvalue) > 0) ;
01432 return (maxmin->null_value && !cache->null_value) ||
01433 (!cache->null_value && !maxmin->null_value &&
01434 class_decimal_cmp(cvalue,mvalue) < 0);
01435 }
01436
01437 bool select_max_min_finder_subselect::cmp_str()
01438 {
01439 String *val1, *val2, buf1, buf2;
01440 Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
01441
01442
01443
01444
01445 val1= cache->val_str(&buf1);
01446 val2= maxmin->val_str(&buf1);
01447 if (fmax)
01448 return (cache->null_value && !maxmin->null_value) ||
01449 (!cache->null_value && !maxmin->null_value &&
01450 sortcmp(val1, val2, cache->collation.collation) > 0) ;
01451 return (maxmin->null_value && !cache->null_value) ||
01452 (!cache->null_value && !maxmin->null_value &&
01453 sortcmp(val1, val2, cache->collation.collation) < 0);
01454 }
01455
01456 bool select_exists_subselect::send_data(List<Item> &)
01457 {
01458 Item_exists_subselect *it= (Item_exists_subselect *)item;
01459 if (unit->offset_limit_cnt)
01460 {
01461 unit->offset_limit_cnt--;
01462 return 0;
01463 }
01464 it->value= 1;
01465 it->assigned(1);
01466 return 0;
01467 }
01468
01469
01470
01471
01472
01473 void Session::end_statement()
01474 {
01475
01476 lex().end();
01477 resetResultsetMessage();
01478 }
01479
01480 str_ref Session::copy_db_to() const
01481 {
01482 if (not impl_->schema->empty())
01483 return str_ref(mem.strdup(*impl_->schema), impl_->schema->size());
01484 my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
01485 return str_ref();
01486 }
01487
01488
01489
01490
01491
01492 void Tmp_Table_Param::init()
01493 {
01494 field_count= sum_func_count= func_count= hidden_field_count= 0;
01495 group_parts= group_length= group_null_parts= 0;
01496 quick_group= 1;
01497 table_charset= 0;
01498 precomputed_group_by= 0;
01499 }
01500
01501 void Tmp_Table_Param::cleanup()
01502 {
01503
01504 if (copy_field)
01505 {
01506 boost::checked_array_delete(copy_field);
01507 save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
01508 }
01509 }
01510
01511 void Session::send_kill_message() const
01512 {
01513 drizzled::error_t err= static_cast<drizzled::error_t>(killed_errno());
01514 if (err != EE_OK)
01515 my_message(err, ER(err), MYF(0));
01516 }
01517
01518 void Session::set_schema(const std::string& new_db)
01519 {
01520 impl_->schema = boost::make_shared<std::string>(new_db);
01521 }
01522
01523
01530 void Session::markTransactionForRollback(bool all)
01531 {
01532 is_fatal_sub_stmt_error= true;
01533 transaction_rollback_request= all;
01534 }
01535
01536 void Session::disconnect(error_t errcode)
01537 {
01538
01539 plugin_sessionvar_cleanup(this);
01540
01541
01542 if (getKilled() || client->wasAborted())
01543 {
01544 status_var.aborted_threads++;
01545 }
01546
01547 if (client->wasAborted())
01548 {
01549 if (not getKilled() && variables.log_warnings > 1)
01550 {
01551 errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
01552 , thread_id
01553 , (impl_->schema->empty() ? "unconnected" : impl_->schema->c_str())
01554 , security_ctx->username().empty() ? "unauthenticated" : security_ctx->username().c_str()
01555 , security_ctx->address().c_str()
01556 , (main_da().is_error() ? main_da().message() : ER(ER_UNKNOWN_ERROR)));
01557 }
01558 }
01559
01560 setKilled(Session::KILL_CONNECTION);
01561
01562 if (client->isConnected())
01563 {
01564 if (errcode != EE_OK)
01565 {
01566
01567 client->sendError(errcode, ER(errcode));
01568 }
01569 client->close();
01570 }
01571 }
01572
01573 void Session::reset_for_next_command()
01574 {
01575 free_list= 0;
01576 select_number= 1;
01577
01578 is_fatal_error= false;
01579 server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
01580 SERVER_QUERY_NO_INDEX_USED |
01581 SERVER_QUERY_NO_GOOD_INDEX_USED);
01582
01583 clear_error();
01584 main_da().reset_diagnostics_area();
01585 total_warn_count=0;
01586 sent_row_count= examined_row_count= 0;
01587 }
01588
01589
01590
01591
01592
01593 void Open_tables_state::close_temporary_tables()
01594 {
01595 Table *table;
01596 Table *tmp_next;
01597
01598 if (not temporary_tables)
01599 return;
01600
01601 for (table= temporary_tables; table; table= tmp_next)
01602 {
01603 tmp_next= table->getNext();
01604 nukeTable(table);
01605 }
01606 temporary_tables= NULL;
01607 }
01608
01609
01610
01611
01612
01613 void Open_tables_state::close_temporary_table(Table *table)
01614 {
01615 if (table->getPrev())
01616 {
01617 table->getPrev()->setNext(table->getNext());
01618 if (table->getPrev()->getNext())
01619 {
01620 table->getNext()->setPrev(table->getPrev());
01621 }
01622 }
01623 else
01624 {
01625
01626 assert(table == temporary_tables);
01627
01628
01629
01630
01631
01632 temporary_tables= table->getNext();
01633 if (temporary_tables)
01634 {
01635 table->getNext()->setPrev(NULL);
01636 }
01637 }
01638 nukeTable(table);
01639 }
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649 void Open_tables_state::nukeTable(Table *table)
01650 {
01651 plugin::StorageEngine& table_type= *table->getShare()->db_type();
01652 table->free_io_cache();
01653 table->delete_table();
01654 rm_temporary_table(table_type, identifier::Table(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath()));
01655 boost::checked_delete(table->getMutableShare());
01656 boost::checked_delete(table);
01657 }
01658
01660 extern time_t flush_status_time;
01661
01662 void Session::refresh_status()
01663 {
01664
01665 memset(&status_var, 0, sizeof(status_var));
01666
01667 flush_status_time= time((time_t*) 0);
01668 current_global_counters.max_used_connections= 1;
01669 current_global_counters.connections= 0;
01670 }
01671
01672 user_var_entry* Session::getVariable(str_ref name0, bool create_if_not_exists)
01673 {
01674 if (cleanup_done)
01675 return NULL;
01676
01677 string name(name0.data(), name0.size());
01678 if (UserVars::mapped_type* iter= find_ptr(user_vars, name))
01679 return *iter;
01680
01681 if (not create_if_not_exists)
01682 return NULL;
01683
01684 user_var_entry *entry= new user_var_entry(name.c_str(), query_id);
01685
01686 std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
01687
01688 if (not returnable.second)
01689 {
01690 boost::checked_delete(entry);
01691 }
01692
01693 return entry;
01694 }
01695
01696 void Session::setVariable(const std::string &name, const std::string &value)
01697 {
01698 if (user_var_entry* var= getVariable(name, true))
01699 {
01700 var->update_hash(false, value, STRING_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, false);
01701 }
01702 }
01703
01704 void Open_tables_state::mark_temp_tables_as_free_for_reuse()
01705 {
01706 for (Table *table= temporary_tables ; table ; table= table->getNext())
01707 {
01708 if (table->query_id == session_.getQueryId())
01709 {
01710 table->query_id= 0;
01711 table->cursor->ha_reset();
01712 }
01713 }
01714 }
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725 void Session::close_thread_tables()
01726 {
01727 open_tables.clearDerivedTables();
01728
01729
01730
01731
01732 open_tables.mark_temp_tables_as_free_for_reuse();
01733
01734
01735
01736
01737
01738
01739
01740
01741 {
01742 main_da().can_overwrite_status= true;
01743 TransactionServices::autocommitOrRollback(*this, is_error());
01744 main_da().can_overwrite_status= false;
01745 transaction.stmt.reset();
01746 }
01747
01748 if (open_tables.lock)
01749 {
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759 unlockTables(open_tables.lock);
01760 open_tables.lock= 0;
01761 }
01762
01763
01764
01765
01766
01767
01768
01769 if (open_tables.open_tables_)
01770 open_tables.close_open_tables();
01771 }
01772
01773 void Session::close_tables_for_reopen(TableList **tables)
01774 {
01775
01776
01777
01778
01779 if (lex().first_not_own_table() == *tables)
01780 *tables= 0;
01781 lex().chop_off_not_own_tables();
01782 for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
01783 tmp->table= 0;
01784 close_thread_tables();
01785 }
01786
01787 bool Session::openTablesLock(TableList *tables)
01788 {
01789 uint32_t counter;
01790 bool need_reopen;
01791
01792 for ( ; ; )
01793 {
01794 if (open_tables_from_list(&tables, &counter))
01795 return true;
01796
01797 if (not lock_tables(tables, counter, &need_reopen))
01798 break;
01799
01800 if (not need_reopen)
01801 return true;
01802
01803 close_tables_for_reopen(&tables);
01804 }
01805
01806 return handle_derived(&lex(), &derived_prepare) || handle_derived(&lex(), &derived_filling);
01807 }
01808
01809
01810
01811
01812
01813
01814
01815 bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
01816 {
01817 if (plugin::StorageEngine::dropTable(session_, identifier))
01818 return false;
01819 if (not best_effort)
01820 errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"), identifier.getSQLPath().c_str(), errno);
01821 return true;
01822 }
01823
01824 bool Open_tables_state::rm_temporary_table(plugin::StorageEngine& base, const identifier::Table &identifier)
01825 {
01826 drizzled::error_t error;
01827 if (plugin::StorageEngine::dropTable(session_, base, identifier, error))
01828 return false;
01829 errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"), identifier.getSQLPath().c_str(), error);
01830 return true;
01831 }
01832
01833 table::Singular& Session::getInstanceTable()
01834 {
01835 impl_->temporary_shares.push_back(new table::Singular);
01836 return impl_->temporary_shares.back();
01837 }
01838
01839
01858 table::Singular& Session::getInstanceTable(std::list<CreateField>& field_list)
01859 {
01860 impl_->temporary_shares.push_back(new table::Singular(this, field_list));
01861 return impl_->temporary_shares.back();
01862 }
01863
01864 void Session::clear_error(bool full)
01865 {
01866 if (main_da().is_error())
01867 main_da().reset_diagnostics_area();
01868
01869 if (full)
01870 drizzle_reset_errors(*this, true);
01871 }
01872
01873 void Session::clearDiagnostics()
01874 {
01875 main_da().reset_diagnostics_area();
01876 }
01877
01891 bool Session::is_error() const
01892 {
01893 return impl_->diagnostics.is_error();
01894 }
01895
01897 void Session::my_ok(ha_rows affected_rows, ha_rows found_rows_arg, uint64_t passed_id, const char *message)
01898 {
01899 main_da().set_ok_status(this, affected_rows, found_rows_arg, passed_id, message);
01900 }
01901
01904 void Session::my_eof()
01905 {
01906 main_da().set_eof_status(this);
01907 }
01908
01909 plugin::StorageEngine* Session::getDefaultStorageEngine()
01910 {
01911 return variables.storage_engine ? variables.storage_engine : global_system_variables.storage_engine;
01912 }
01913
01914 enum_tx_isolation Session::getTxIsolation() const
01915 {
01916 return (enum_tx_isolation)variables.tx_isolation;
01917 }
01918
01919 drizzled::util::Storable* Session::getProperty0(const std::string& arg)
01920 {
01921 return impl_->properties[arg];
01922 }
01923
01924 void Session::setProperty0(const std::string& arg, drizzled::util::Storable* value)
01925 {
01926
01927 impl_->properties[arg]= value;
01928 }
01929
01930 plugin::EventObserverList* Session::getSchemaObservers(const std::string &db_name)
01931 {
01932 if (impl_c::schema_event_observers_t::mapped_type* i= find_ptr(impl_->schema_event_observers, db_name))
01933 return *i;
01934 return NULL;
01935 }
01936
01937 plugin::EventObserverList* Session::setSchemaObservers(const std::string &db_name, plugin::EventObserverList* observers)
01938 {
01939 impl_->schema_event_observers.erase(db_name);
01940 if (observers)
01941 impl_->schema_event_observers[db_name] = observers;
01942 return observers;
01943 }
01944
01945 util::string::ptr Session::schema() const
01946 {
01947 return impl_->schema;
01948 }
01949
01950 void Session::resetQueryString()
01951 {
01952 query.reset();
01953 impl_->state.reset();
01954 }
01955
01956 const boost::shared_ptr<session::State>& Session::state()
01957 {
01958 return impl_->state;
01959 }
01960
01961 const std::string& display::type(drizzled::Session::global_read_lock_t type)
01962 {
01963 static const std::string NONE= "NONE";
01964 static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
01965 static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
01966
01967 switch (type)
01968 {
01969 default:
01970 case Session::NONE:
01971 return NONE;
01972 case Session::GOT_GLOBAL_READ_LOCK:
01973 return GOT_GLOBAL_READ_LOCK;
01974 case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
01975 return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
01976 }
01977 }
01978
01979 size_t display::max_string_length(drizzled::Session::global_read_lock_t)
01980 {
01981 return display::type(Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT).size();
01982 }
01983
01984 }