~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Stewart Smith
  • Date: 2011-01-14 05:09:04 UTC
  • mto: (2086.1.3 build)
  • mto: This revision was merged to the branch mainline in revision 2087.
  • Revision ID: stewart@flamingspork.com-20110114050904-a98kswwpqnpl413s
add a bit of a note on how variables docs should be expanded

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
49
49
#include "drizzled/transaction_services.h"
50
50
#include "drizzled/drizzled.h"
51
51
 
 
52
#include "drizzled/identifier.h"
 
53
 
52
54
#include "drizzled/table/instance.h"
53
55
 
54
56
#include "plugin/myisam/myisam.h"
99
101
/*
100
102
  The following functions form part of the C plugin API
101
103
*/
102
 
int mysql_tmpfile(const char *prefix)
 
104
int tmpfile(const char *prefix)
103
105
{
104
106
  char filename[FN_REFLEN];
105
107
  int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
159
161
  return (enum_tx_isolation)session->variables.tx_isolation;
160
162
}
161
163
 
162
 
Session::Session(plugin::Client *client_arg) :
 
164
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
163
165
  Open_tables_state(refresh_version),
164
166
  mem_root(&main_mem_root),
165
167
  xa_id(0),
166
168
  lex(&main_lex),
167
169
  query(new std::string),
168
170
  _schema(new std::string("")),
169
 
  catalog("LOCAL"),
170
171
  client(client_arg),
171
172
  scheduler(NULL),
172
173
  scheduler_arg(NULL),
173
174
  lock_id(&main_lock_id),
174
 
  user_time(0),
 
175
  thread_stack(NULL),
 
176
  security_ctx(identifier::User::make_shared()),
 
177
  where(Session::DEFAULT_WHERE),
 
178
  dbug_sentry(Session_SENTRY_MAGIC),
 
179
  mysys_var(0),
 
180
  command(COM_CONNECT),
 
181
  file_id(0),
 
182
  _epoch(boost::gregorian::date(1970,1,1)),
 
183
  _connect_time(boost::posix_time::microsec_clock::universal_time()),
 
184
  utime_after_lock(0),
175
185
  ha_data(plugin::num_trx_monitored_objects),
 
186
  query_id(0),
 
187
  warn_query_id(0),
176
188
  concurrent_execute_allowed(true),
177
189
  arg_of_last_insert_id_function(false),
178
190
  first_successful_insert_id_in_prev_stmt(0),
179
191
  first_successful_insert_id_in_cur_stmt(0),
180
192
  limit_found_rows(0),
 
193
  options(session_startup_options),
 
194
  row_count_func(-1),
 
195
  sent_row_count(0),
 
196
  examined_row_count(0),
 
197
  used_tables(0),
 
198
  total_warn_count(0),
 
199
  col_access(0),
 
200
  statement_id_counter(0),
 
201
  row_count(0),
 
202
  thread_id(0),
 
203
  tmp_table(0),
181
204
  _global_read_lock(NONE),
 
205
  count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
182
206
  _killed(NOT_KILLED),
183
207
  some_tables_deleted(false),
184
208
  no_errors(false),
193
217
  transaction_message(NULL),
194
218
  statement_message(NULL),
195
219
  session_event_observers(NULL),
 
220
  _catalog(catalog_arg),
196
221
  use_usage(false)
197
222
{
198
223
  client->setSession(this);
203
228
    will be re-initialized in init_for_queries().
204
229
  */
205
230
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
206
 
  thread_stack= NULL;
207
 
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
208
 
  col_access= 0;
209
 
  tmp_table= 0;
210
 
  used_tables= 0;
211
231
  cuted_fields= sent_row_count= row_count= 0L;
212
 
  row_count_func= -1;
213
 
  statement_id_counter= 0UL;
214
232
  // Must be reset to handle error with Session's created for init of mysqld
215
233
  lex->current_select= 0;
216
 
  start_time=(time_t) 0;
217
 
  start_utime= 0L;
218
 
  utime_after_lock= 0L;
219
234
  memset(&variables, 0, sizeof(variables));
220
 
  thread_id= 0;
221
 
  file_id = 0;
222
 
  query_id= 0;
223
 
  warn_query_id= 0;
224
 
  mysys_var= 0;
225
235
  scoreboard_index= -1;
226
 
  dbug_sentry=Session_SENTRY_MAGIC;
227
236
  cleanup_done= abort_on_warning= no_warnings_for_error= false;  
228
237
 
229
238
  /* query_cache init */
232
241
 
233
242
  /* Variables with default values */
234
243
  proc_info="login";
235
 
  where= Session::DEFAULT_WHERE;
236
 
  command= COM_CONNECT;
237
244
 
238
245
  plugin_sessionvar_init(this);
239
246
  /*
243
250
  */
244
251
  variables.pseudo_thread_id= thread_id;
245
252
  server_status= SERVER_STATUS_AUTOCOMMIT;
246
 
  options= session_startup_options;
247
253
 
248
254
  if (variables.max_join_size == HA_POS_ERROR)
249
255
    options |= OPTION_BIG_SELECTS;
255
261
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
256
262
  warn_list.empty();
257
263
  memset(warn_count, 0, sizeof(warn_count));
258
 
  total_warn_count= 0;
259
264
  memset(&status_var, 0, sizeof(status_var));
260
265
 
261
266
  /* Initialize sub structures */
376
381
{
377
382
  this->checkSentry();
378
383
 
379
 
  if (client->isConnected())
 
384
  if (client and client->isConnected())
380
385
  {
 
386
    assert(security_ctx);
381
387
    if (global_system_variables.log_warnings)
382
 
        errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
383
 
                      thread_id,
384
 
                      (getSecurityContext().getUser().c_str() ?
385
 
                       getSecurityContext().getUser().c_str() : ""));
386
 
    disconnect(0, false);
 
388
    {
 
389
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),
 
390
                    internal::my_progname,
 
391
                    thread_id,
 
392
                    security_ctx->username().c_str());
 
393
    }
 
394
 
 
395
    disconnect();
387
396
  }
388
397
 
389
398
  /* Close connection */
390
 
  client->close();
391
 
  delete client;
 
399
  if (client)
 
400
  {
 
401
    client->close();
 
402
    delete client;
 
403
  }
392
404
 
393
405
  if (cleanup_done == false)
394
406
    cleanup();
530
542
{
531
543
  if (storeGlobals())
532
544
  {
533
 
    disconnect(ER_OUT_OF_RESOURCES, true);
 
545
    disconnect(ER_OUT_OF_RESOURCES);
534
546
    status_var.aborted_connects++;
535
547
    return true;
536
548
  }
541
553
{
542
554
  if (initGlobals() || authenticate())
543
555
  {
544
 
    disconnect(0, true);
 
556
    disconnect();
545
557
    return;
546
558
  }
547
559
 
553
565
      break;
554
566
  }
555
567
 
556
 
  disconnect(0, true);
 
568
  disconnect();
557
569
}
558
570
 
559
571
bool Session::schedule(Session::shared_ptr &arg)
561
573
  arg->scheduler= plugin::Scheduler::getScheduler();
562
574
  assert(arg->scheduler);
563
575
 
564
 
  connection_count.increment();
565
 
 
566
 
  if (connection_count > current_global_counters.max_used_connections)
 
576
  ++connection_count;
 
577
 
 
578
  long current_connections= connection_count;
 
579
 
 
580
  if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
567
581
  {
568
 
    current_global_counters.max_used_connections= connection_count;
 
582
    current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
569
583
  }
570
584
 
571
585
  current_global_counters.connections++;
603
617
/*
604
618
  Is this session viewable by the current user?
605
619
*/
606
 
bool Session::isViewable() const
 
620
bool Session::isViewable(identifier::User::const_reference user_arg) const
607
621
{
608
 
  return plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
609
 
                                             this,
610
 
                                             false);
 
622
  return plugin::Authorization::isAuthorized(user_arg, this, false);
611
623
}
612
624
 
613
625
 
638
650
 
639
651
bool Session::authenticate()
640
652
{
641
 
  lex->start(this);
642
653
  if (client->authenticate())
643
654
    return false;
644
655
 
651
662
                        const std::string &in_db)
652
663
{
653
664
  bool is_authenticated=
654
 
    plugin::Authentication::isAuthenticated(getSecurityContext(),
655
 
                                            passwd_str);
 
665
    plugin::Authentication::isAuthenticated(user(), passwd_str);
656
666
 
657
667
  if (is_authenticated != true)
658
668
  {
665
675
  if (not in_db.empty())
666
676
  {
667
677
    SchemaIdentifier identifier(in_db);
668
 
    if (mysql_change_db(this, identifier))
 
678
    if (change_db(this, identifier))
669
679
    {
670
 
      /* mysql_change_db() has pushed the error message. */
 
680
      /* change_db() has pushed the error message. */
671
681
      return false;
672
682
    }
673
683
  }
791
801
 
792
802
  if (result == false)
793
803
  {
794
 
    my_error(killed_errno(), MYF(0));
 
804
    my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
795
805
  }
796
806
  else if ((result == true) && do_release)
797
807
  {
1504
1514
bool select_max_min_finder_subselect::cmp_decimal()
1505
1515
{
1506
1516
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1507
 
  my_decimal cval, *cvalue= cache->val_decimal(&cval);
1508
 
  my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
 
1517
  type::Decimal cval, *cvalue= cache->val_decimal(&cval);
 
1518
  type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
1509
1519
  if (fmax)
1510
1520
    return (cache->null_value && !maxmin->null_value) ||
1511
1521
      (!cache->null_value && !maxmin->null_value &&
1512
 
       my_decimal_cmp(cvalue, mvalue) > 0) ;
 
1522
       class_decimal_cmp(cvalue, mvalue) > 0) ;
1513
1523
  return (maxmin->null_value && !cache->null_value) ||
1514
1524
    (!cache->null_value && !maxmin->null_value &&
1515
 
     my_decimal_cmp(cvalue,mvalue) < 0);
 
1525
     class_decimal_cmp(cvalue,mvalue) < 0);
1516
1526
}
1517
1527
 
1518
1528
bool select_max_min_finder_subselect::cmp_str()
1599
1609
  if (copy_field)
1600
1610
  {
1601
1611
    delete [] copy_field;
1602
 
    save_copy_field= copy_field= 0;
 
1612
    save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
1603
1613
  }
1604
1614
}
1605
1615
 
1645
1655
  }
1646
1656
}
1647
1657
 
1648
 
void Session::disconnect(uint32_t errcode, bool should_lock)
 
1658
void Session::disconnect(enum error_t errcode)
1649
1659
{
1650
1660
  /* Allow any plugins to cleanup their session variables */
1651
1661
  plugin_sessionvar_cleanup(this);
1660
1670
  {
1661
1671
    if (not getKilled() && variables.log_warnings > 1)
1662
1672
    {
1663
 
      SecurityContext *sctx= &security_ctx;
1664
 
 
1665
1673
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1666
1674
                  , thread_id
1667
1675
                  , (_schema->empty() ? "unconnected" : _schema->c_str())
1668
 
                  , sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1669
 
                  , sctx->getIp().c_str()
 
1676
                  , security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
 
1677
                  , security_ctx->address().c_str()
1670
1678
                  , (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1671
1679
    }
1672
1680
  }
1673
1681
 
1674
 
  /* Close out our connection to the client */
1675
 
  if (should_lock)
1676
 
    session::Cache::singleton().mutex().lock();
1677
 
 
1678
1682
  setKilled(Session::KILL_CONNECTION);
1679
1683
 
1680
1684
  if (client->isConnected())
1681
1685
  {
1682
 
    if (errcode)
 
1686
    if (errcode != EE_OK)
1683
1687
    {
1684
1688
      /*my_error(errcode, ER(errcode));*/
1685
1689
      client->sendError(errcode, ER(errcode));
1686
1690
    }
1687
1691
    client->close();
1688
1692
  }
1689
 
 
1690
 
  if (should_lock)
1691
 
  {
1692
 
    session::Cache::singleton().mutex().unlock();
1693
 
  }
1694
1693
}
1695
1694
 
1696
1695
void Session::reset_for_next_command()
1786
1785
 
1787
1786
  delete table->getMutableShare();
1788
1787
 
1789
 
  /* This makes me sad, but we're allocating it via malloc */
1790
1788
  delete table;
1791
1789
}
1792
1790
 
1922
1920
  /*
1923
1921
    Note that we need to hold table::Cache::singleton().mutex() while changing the
1924
1922
    open_tables list. Another thread may work on it.
1925
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
1923
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
1926
1924
    Closing a MERGE child before the parent would be fatal if the
1927
1925
    other thread tries to abort the MERGE lock in between.
1928
1926
  */
1956
1954
 
1957
1955
    if (not lock_tables(tables, counter, &need_reopen))
1958
1956
      break;
 
1957
 
1959
1958
    if (not need_reopen)
1960
1959
      return true;
 
1960
 
1961
1961
    close_tables_for_reopen(&tables);
1962
1962
  }
1963
 
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
1964
 
       (
1965
 
        mysql_handle_derived(lex, &mysql_derived_filling))))
 
1963
 
 
1964
  if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
1966
1965
    return true;
1967
1966
 
1968
1967
  return false;
1976
1975
 
1977
1976
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
1978
1977
{
1979
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1978
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1980
1979
  {
1981
1980
    if (not best_effort)
1982
1981
    {
1994
1993
 
1995
1994
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
1996
1995
{
 
1996
  drizzled::error_t error;
1997
1997
  assert(base);
1998
1998
 
1999
 
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
 
1999
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
2000
2000
  {
2001
2001
    std::string path;
2002
2002
    identifier.getSQLPath(path);
2003
2003
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2004
 
                  path.c_str(), errno);
 
2004
                  path.c_str(), error);
2005
2005
 
2006
2006
    return true;
2007
2007
  }