~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Monty Taylor
  • Date: 2010-12-26 01:32:11 UTC
  • mto: This revision was merged to the branch mainline in revision 2038.
  • Revision ID: mordred@inaugust.com-20101226013211-c1tx52h7evovmijg
fixed dict and eval.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 */
23
23
 
24
24
#include "config.h"
25
 
 
26
 
#include <drizzled/copy_field.h>
27
25
#include "drizzled/session.h"
28
26
#include "drizzled/session/cache.h"
 
27
#include <sys/stat.h>
29
28
#include "drizzled/error.h"
30
29
#include "drizzled/gettext.h"
31
30
#include "drizzled/query_id.h"
52
51
 
53
52
#include "drizzled/identifier.h"
54
53
 
55
 
#include <drizzled/refresh_version.h>
56
 
 
57
 
#include "drizzled/table/singular.h"
 
54
#include "drizzled/table/instance.h"
58
55
 
59
56
#include "plugin/myisam/myisam.h"
60
57
#include "drizzled/internal/iocache.h"
65
62
 
66
63
#include "drizzled/display.h"
67
64
 
 
65
#include <fcntl.h>
68
66
#include <algorithm>
69
67
#include <climits>
70
 
#include <fcntl.h>
71
 
#include <sys/stat.h>
72
 
 
73
68
#include <boost/filesystem.hpp>
74
 
#include <boost/checked_delete.hpp>
75
69
 
76
70
#include "drizzled/util/backtrace.h"
77
71
 
107
101
/*
108
102
  The following functions form part of the C plugin API
109
103
*/
110
 
int tmpfile(const char *prefix)
 
104
int mysql_tmpfile(const char *prefix)
111
105
{
112
106
  char filename[FN_REFLEN];
113
107
  int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
118
112
  return fd;
119
113
}
120
114
 
 
115
int session_tablespace_op(const Session *session)
 
116
{
 
117
  return test(session->tablespace_op);
 
118
}
 
119
 
 
120
/**
 
121
   Set the process info field of the Session structure.
 
122
 
 
123
   This function is used by plug-ins. Internally, the
 
124
   Session::set_proc_info() function should be used.
 
125
 
 
126
   @see Session::set_proc_info
 
127
 */
 
128
void set_session_proc_info(Session *session, const char *info)
 
129
{
 
130
  session->set_proc_info(info);
 
131
}
 
132
 
 
133
const char *get_session_proc_info(Session *session)
 
134
{
 
135
  return session->get_proc_info();
 
136
}
 
137
 
121
138
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
122
139
{
123
140
  return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
134
151
  return session->options & test_options;
135
152
}
136
153
 
137
 
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
 
154
int session_sql_command(const Session *session)
 
155
{
 
156
  return (int) session->lex->sql_command;
 
157
}
 
158
 
 
159
enum_tx_isolation session_tx_isolation(const Session *session)
 
160
{
 
161
  return (enum_tx_isolation)session->variables.tx_isolation;
 
162
}
 
163
 
 
164
Session::Session(plugin::Client *client_arg) :
138
165
  Open_tables_state(refresh_version),
139
166
  mem_root(&main_mem_root),
140
167
  xa_id(0),
141
168
  lex(&main_lex),
142
169
  query(new std::string),
143
170
  _schema(new std::string("")),
 
171
  catalog("LOCAL"),
144
172
  client(client_arg),
145
173
  scheduler(NULL),
146
174
  scheduler_arg(NULL),
147
175
  lock_id(&main_lock_id),
148
176
  thread_stack(NULL),
149
177
  security_ctx(identifier::User::make_shared()),
150
 
  _where(Session::DEFAULT_WHERE),
151
 
  dbug_sentry(Session_SENTRY_MAGIC),
152
 
  mysys_var(0),
153
 
  command(COM_CONNECT),
154
 
  file_id(0),
155
 
  _epoch(boost::gregorian::date(1970,1,1)),
156
 
  _connect_time(boost::posix_time::microsec_clock::universal_time()),
157
 
  utime_after_lock(0),
 
178
  user_time(0),
158
179
  ha_data(plugin::num_trx_monitored_objects),
159
 
  query_id(0),
160
 
  warn_query_id(0),
161
180
  concurrent_execute_allowed(true),
162
181
  arg_of_last_insert_id_function(false),
163
182
  first_successful_insert_id_in_prev_stmt(0),
164
183
  first_successful_insert_id_in_cur_stmt(0),
165
184
  limit_found_rows(0),
166
 
  options(session_startup_options),
167
 
  row_count_func(-1),
168
 
  sent_row_count(0),
169
 
  examined_row_count(0),
170
 
  used_tables(0),
171
 
  total_warn_count(0),
172
 
  col_access(0),
173
 
  statement_id_counter(0),
174
 
  row_count(0),
175
 
  thread_id(0),
176
 
  tmp_table(0),
177
185
  _global_read_lock(NONE),
178
 
  count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
179
186
  _killed(NOT_KILLED),
180
187
  some_tables_deleted(false),
181
188
  no_errors(false),
183
190
  is_fatal_error(false),
184
191
  transaction_rollback_request(false),
185
192
  is_fatal_sub_stmt_error(0),
 
193
  derived_tables_processing(false),
186
194
  tablespace_op(false),
187
 
  derived_tables_processing(false),
188
195
  m_lip(NULL),
189
196
  cached_table(0),
190
197
  transaction_message(NULL),
191
198
  statement_message(NULL),
192
199
  session_event_observers(NULL),
193
 
  _catalog(catalog_arg),
194
200
  use_usage(false)
195
201
{
196
202
  client->setSession(this);
201
207
    will be re-initialized in init_for_queries().
202
208
  */
203
209
  memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
 
210
  count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
211
  col_access= 0;
 
212
  tmp_table= 0;
 
213
  used_tables= 0;
204
214
  cuted_fields= sent_row_count= row_count= 0L;
 
215
  row_count_func= -1;
 
216
  statement_id_counter= 0UL;
205
217
  // Must be reset to handle error with Session's created for init of mysqld
206
218
  lex->current_select= 0;
 
219
  start_time=(time_t) 0;
 
220
  start_utime= 0L;
 
221
  utime_after_lock= 0L;
207
222
  memset(&variables, 0, sizeof(variables));
 
223
  thread_id= 0;
 
224
  file_id = 0;
 
225
  query_id= 0;
 
226
  warn_query_id= 0;
 
227
  mysys_var= 0;
208
228
  scoreboard_index= -1;
 
229
  dbug_sentry=Session_SENTRY_MAGIC;
209
230
  cleanup_done= abort_on_warning= no_warnings_for_error= false;  
210
231
 
211
232
  /* query_cache init */
214
235
 
215
236
  /* Variables with default values */
216
237
  proc_info="login";
 
238
  where= Session::DEFAULT_WHERE;
 
239
  command= COM_CONNECT;
217
240
 
218
241
  plugin_sessionvar_init(this);
219
242
  /*
223
246
  */
224
247
  variables.pseudo_thread_id= thread_id;
225
248
  server_status= SERVER_STATUS_AUTOCOMMIT;
 
249
  options= session_startup_options;
226
250
 
227
251
  if (variables.max_join_size == HA_POS_ERROR)
228
252
    options |= OPTION_BIG_SELECTS;
234
258
  session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
235
259
  warn_list.empty();
236
260
  memset(warn_count, 0, sizeof(warn_count));
 
261
  total_warn_count= 0;
237
262
  memset(&status_var, 0, sizeof(status_var));
238
263
 
239
264
  /* Initialize sub structures */
269
294
  m_internal_handler= handler;
270
295
}
271
296
 
272
 
bool Session::handle_error(drizzled::error_t sql_errno, const char *message,
273
 
                           DRIZZLE_ERROR::enum_warning_level level)
 
297
bool Session::handle_error(uint32_t sql_errno, const char *message,
 
298
                       DRIZZLE_ERROR::enum_warning_level level)
274
299
{
275
300
  if (m_internal_handler)
276
301
  {
326
351
#endif
327
352
  {
328
353
    TransactionServices &transaction_services= TransactionServices::singleton();
329
 
    transaction_services.rollbackTransaction(*this, true);
 
354
    transaction_services.rollbackTransaction(this, true);
330
355
    xid_cache_delete(&transaction.xid_state);
331
356
  }
332
357
 
335
360
       iter++)
336
361
  {
337
362
    user_var_entry *entry= (*iter).second;
338
 
    boost::checked_delete(entry);
 
363
    delete entry;
339
364
  }
340
365
  user_vars.clear();
341
366
 
354
379
{
355
380
  this->checkSentry();
356
381
 
357
 
  if (client and client->isConnected())
 
382
  if (client->isConnected())
358
383
  {
359
384
    assert(security_ctx);
360
385
    if (global_system_variables.log_warnings)
361
386
    {
362
 
      errmsg_printf(error::WARN, ER(ER_FORCING_CLOSE),
 
387
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),
363
388
                    internal::my_progname,
364
389
                    thread_id,
365
390
                    security_ctx->username().c_str());
366
391
    }
367
392
 
368
 
    disconnect();
 
393
    disconnect(0, false);
369
394
  }
370
395
 
371
396
  /* Close connection */
372
 
  if (client)
373
 
  {
374
 
    client->close();
375
 
    boost::checked_delete(client);
376
 
    client= NULL;
377
 
  }
 
397
  client->close();
 
398
  delete client;
378
399
 
379
400
  if (cleanup_done == false)
380
401
    cleanup();
392
413
 
393
414
  plugin::Logging::postEndDo(this);
394
415
  plugin::EventObserver::deregisterSessionEvents(*this); 
 
416
 
 
417
  for (PropertyMap::iterator iter= life_properties.begin(); iter != life_properties.end(); iter++)
 
418
  {
 
419
    delete (*iter).second;
 
420
  }
 
421
  life_properties.clear();
395
422
}
396
423
 
397
424
void Session::setClient(plugin::Client *client_arg)
510
537
{
511
538
  if (storeGlobals())
512
539
  {
513
 
    disconnect(ER_OUT_OF_RESOURCES);
 
540
    disconnect(ER_OUT_OF_RESOURCES, true);
514
541
    status_var.aborted_connects++;
515
542
    return true;
516
543
  }
521
548
{
522
549
  if (initGlobals() || authenticate())
523
550
  {
524
 
    disconnect();
 
551
    disconnect(0, true);
525
552
    return;
526
553
  }
527
554
 
533
560
      break;
534
561
  }
535
562
 
536
 
  disconnect();
 
563
  disconnect(0, true);
537
564
}
538
565
 
539
566
bool Session::schedule(Session::shared_ptr &arg)
541
568
  arg->scheduler= plugin::Scheduler::getScheduler();
542
569
  assert(arg->scheduler);
543
570
 
544
 
  ++connection_count;
545
 
 
546
 
  long current_connections= connection_count;
547
 
 
548
 
  if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
 
571
  connection_count.increment();
 
572
 
 
573
  if (connection_count > current_global_counters.max_used_connections)
549
574
  {
550
 
    current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
 
575
    current_global_counters.max_used_connections= connection_count;
551
576
  }
552
577
 
553
578
  current_global_counters.connections++;
585
610
/*
586
611
  Is this session viewable by the current user?
587
612
*/
588
 
bool Session::isViewable(identifier::User::const_reference user_arg) const
 
613
bool Session::isViewable() const
589
614
{
590
 
  return plugin::Authorization::isAuthorized(user_arg, this, false);
 
615
  return plugin::Authorization::isAuthorized(current_session->user(),
 
616
                                             this,
 
617
                                             false);
591
618
}
592
619
 
593
620
 
618
645
 
619
646
bool Session::authenticate()
620
647
{
 
648
  lex->start(this);
621
649
  if (client->authenticate())
622
650
    return false;
623
651
 
642
670
  /* Change database if necessary */
643
671
  if (not in_db.empty())
644
672
  {
645
 
    identifier::Schema identifier(in_db);
646
 
    if (change_db(this, identifier))
 
673
    SchemaIdentifier identifier(in_db);
 
674
    if (mysql_change_db(this, identifier))
647
675
    {
648
 
      /* change_db() has pushed the error message. */
 
676
      /* mysql_change_db() has pushed the error message. */
649
677
      return false;
650
678
    }
651
679
  }
713
741
    plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
714
742
  }
715
743
  query.reset(new_query);
716
 
  _state.reset(new session::State(in_packet, in_packet_length));
 
744
  _state.reset(new State(in_packet, in_packet_length));
717
745
 
718
746
  return true;
719
747
}
738
766
       * (Which of course should never happen...)
739
767
       */
740
768
      server_status&= ~SERVER_STATUS_IN_TRANS;
741
 
      if (transaction_services.commitTransaction(*this, true))
 
769
      if (transaction_services.commitTransaction(this, true))
742
770
        result= false;
743
771
      options&= ~(OPTION_BEGIN);
744
772
      break;
755
783
    case ROLLBACK_AND_CHAIN:
756
784
    {
757
785
      server_status&= ~SERVER_STATUS_IN_TRANS;
758
 
      if (transaction_services.rollbackTransaction(*this, true))
 
786
      if (transaction_services.rollbackTransaction(this, true))
759
787
        result= false;
760
788
      options&= ~(OPTION_BEGIN);
761
789
      if (result == true && (completion == ROLLBACK_AND_CHAIN))
769
797
 
770
798
  if (result == false)
771
799
  {
772
 
    my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
 
800
    my_error(killed_errno(), MYF(0));
773
801
  }
774
802
  else if ((result == true) && do_release)
775
803
  {
792
820
  if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
793
821
  {
794
822
    server_status&= ~SERVER_STATUS_IN_TRANS;
795
 
    if (transaction_services.commitTransaction(*this, true))
 
823
    if (transaction_services.commitTransaction(this, true))
796
824
      result= false;
797
825
  }
798
826
  options&= ~(OPTION_BEGIN);
803
831
{
804
832
  bool result= true;
805
833
 
806
 
  assert(! inTransaction());
807
 
 
808
 
  options|= OPTION_BEGIN;
809
 
  server_status|= SERVER_STATUS_IN_TRANS;
810
 
 
811
 
  if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
 
834
  if (! endActiveTransaction())
812
835
  {
813
836
    result= false;
814
837
  }
 
838
  else
 
839
  {
 
840
    options|= OPTION_BEGIN;
 
841
    server_status|= SERVER_STATUS_IN_TRANS;
 
842
 
 
843
    if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
 
844
    {
 
845
      result= false;
 
846
    }
 
847
  }
815
848
 
816
849
  return result;
817
850
}
833
866
    first_successful_insert_id_in_cur_stmt= 0;
834
867
    substitute_null_with_insert_id= true;
835
868
  }
836
 
 
837
869
  arg_of_last_insert_id_function= false;
838
 
 
839
870
  /* Free Items that were created during this execution */
840
871
  free_items();
841
 
 
842
 
  /* Reset _where. */
843
 
  _where= Session::DEFAULT_WHERE;
 
872
  /* Reset where. */
 
873
  where= Session::DEFAULT_WHERE;
844
874
 
845
875
  /* Reset the temporary shares we built */
846
876
  for_each(temporary_shares.begin(),
871
901
                                     bool allocate_lex_string)
872
902
{
873
903
  if (allocate_lex_string)
874
 
    if (!(lex_str= (LEX_STRING *)getMemRoot()->allocate(sizeof(LEX_STRING))))
 
904
    if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
875
905
      return 0;
876
906
  if (!(lex_str->str= mem_root->strmake_root(str, length)))
877
907
    return 0;
917
947
  return (result->send_fields(field_list));
918
948
}
919
949
 
920
 
void select_result::send_error(drizzled::error_t errcode, const char *err)
 
950
void select_result::send_error(uint32_t errcode, const char *err)
921
951
{
922
952
  my_message(errcode, err, MYF(0));
923
953
}
926
956
  Handling writing to file
927
957
************************************************************************/
928
958
 
929
 
void select_to_file::send_error(drizzled::error_t errcode,const char *err)
 
959
void select_to_file::send_error(uint32_t errcode,const char *err)
930
960
{
931
961
  my_message(errcode, err, MYF(0));
932
962
  if (file > 0)
1480
1510
bool select_max_min_finder_subselect::cmp_decimal()
1481
1511
{
1482
1512
  Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1483
 
  type::Decimal cval, *cvalue= cache->val_decimal(&cval);
1484
 
  type::Decimal mval, *mvalue= maxmin->val_decimal(&mval);
 
1513
  my_decimal cval, *cvalue= cache->val_decimal(&cval);
 
1514
  my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
1485
1515
  if (fmax)
1486
1516
    return (cache->null_value && !maxmin->null_value) ||
1487
1517
      (!cache->null_value && !maxmin->null_value &&
1488
 
       class_decimal_cmp(cvalue, mvalue) > 0) ;
 
1518
       my_decimal_cmp(cvalue, mvalue) > 0) ;
1489
1519
  return (maxmin->null_value && !cache->null_value) ||
1490
1520
    (!cache->null_value && !maxmin->null_value &&
1491
 
     class_decimal_cmp(cvalue,mvalue) < 0);
 
1521
     my_decimal_cmp(cvalue,mvalue) < 0);
1492
1522
}
1493
1523
 
1494
1524
bool select_max_min_finder_subselect::cmp_str()
1574
1604
  /* Fix for Intel compiler */
1575
1605
  if (copy_field)
1576
1606
  {
1577
 
    boost::checked_array_delete(copy_field);
1578
 
    save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
 
1607
    delete [] copy_field;
 
1608
    save_copy_field= copy_field= 0;
1579
1609
  }
1580
1610
}
1581
1611
 
1582
1612
void Session::send_kill_message() const
1583
1613
{
1584
 
  drizzled::error_t err= static_cast<drizzled::error_t>(killed_errno());
1585
 
  if (err != EE_OK)
 
1614
  int err= killed_errno();
 
1615
  if (err)
1586
1616
    my_message(err, ER(err), MYF(0));
1587
1617
}
1588
1618
 
1612
1642
  @param  session   Thread handle
1613
1643
  @param  all   true <=> rollback main transaction.
1614
1644
*/
1615
 
void Session::markTransactionForRollback(bool all)
 
1645
void mark_transaction_to_rollback(Session *session, bool all)
1616
1646
{
1617
 
  is_fatal_sub_stmt_error= true;
1618
 
  transaction_rollback_request= all;
 
1647
  if (session)
 
1648
  {
 
1649
    session->is_fatal_sub_stmt_error= true;
 
1650
    session->transaction_rollback_request= all;
 
1651
  }
1619
1652
}
1620
1653
 
1621
 
void Session::disconnect(enum error_t errcode)
 
1654
void Session::disconnect(uint32_t errcode, bool should_lock)
1622
1655
{
1623
1656
  /* Allow any plugins to cleanup their session variables */
1624
1657
  plugin_sessionvar_cleanup(this);
1633
1666
  {
1634
1667
    if (not getKilled() && variables.log_warnings > 1)
1635
1668
    {
1636
 
      errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
 
1669
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1637
1670
                  , thread_id
1638
1671
                  , (_schema->empty() ? "unconnected" : _schema->c_str())
1639
1672
                  , security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
1642
1675
    }
1643
1676
  }
1644
1677
 
 
1678
  /* Close out our connection to the client */
 
1679
  if (should_lock)
 
1680
    session::Cache::singleton().mutex().lock();
 
1681
 
1645
1682
  setKilled(Session::KILL_CONNECTION);
1646
1683
 
1647
1684
  if (client->isConnected())
1648
1685
  {
1649
 
    if (errcode != EE_OK)
 
1686
    if (errcode)
1650
1687
    {
1651
1688
      /*my_error(errcode, ER(errcode));*/
1652
1689
      client->sendError(errcode, ER(errcode));
1653
1690
    }
1654
1691
    client->close();
1655
1692
  }
 
1693
 
 
1694
  if (should_lock)
 
1695
  {
 
1696
    session::Cache::singleton().mutex().unlock();
 
1697
  }
1656
1698
}
1657
1699
 
1658
1700
void Session::reset_for_next_command()
1743
1785
  table->free_io_cache();
1744
1786
  table->delete_table();
1745
1787
 
1746
 
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
 
1788
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1747
1789
  rm_temporary_table(table_type, identifier);
1748
1790
 
1749
 
  boost::checked_delete(table->getMutableShare());
 
1791
  delete table->getMutableShare();
1750
1792
 
1751
 
  boost::checked_delete(table);
 
1793
  /* This makes me sad, but we're allocating it via malloc */
 
1794
  delete table;
1752
1795
}
1753
1796
 
1754
1797
/** Clear most status variables. */
1771
1814
 
1772
1815
user_var_entry *Session::getVariable(const std::string  &name, bool create_if_not_exists)
1773
1816
{
1774
 
  if (cleanup_done)
1775
 
    return NULL;
 
1817
  UserVarsRange ppp= user_vars.equal_range(name);
1776
1818
 
1777
 
  UserVars::iterator iter= user_vars.find(name);
1778
 
  if (iter != user_vars.end())
 
1819
  for (UserVars::iterator iter= ppp.first;
 
1820
       iter != ppp.second; ++iter)
 
1821
  {
1779
1822
    return (*iter).second;
 
1823
  }
1780
1824
 
1781
1825
  if (not create_if_not_exists)
1782
1826
    return NULL;
1791
1835
 
1792
1836
  if (not returnable.second)
1793
1837
  {
1794
 
    boost::checked_delete(entry);
 
1838
    delete entry;
1795
1839
  }
1796
1840
 
1797
1841
  return entry;
1800
1844
void Session::setVariable(const std::string &name, const std::string &value)
1801
1845
{
1802
1846
  user_var_entry *updateable_var= getVariable(name.c_str(), true);
1803
 
  if (updateable_var)
1804
 
  {
1805
 
    updateable_var->update_hash(false,
1806
 
                                (void*)value.c_str(),
1807
 
                                static_cast<uint32_t>(value.length()), STRING_RESULT,
1808
 
                                &my_charset_bin,
1809
 
                                DERIVATION_IMPLICIT, false);
1810
 
  }
 
1847
 
 
1848
  updateable_var->update_hash(false,
 
1849
                              (void*)value.c_str(),
 
1850
                              static_cast<uint32_t>(value.length()), STRING_RESULT,
 
1851
                              &my_charset_bin,
 
1852
                              DERIVATION_IMPLICIT, false);
1811
1853
}
1812
1854
 
1813
1855
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1862
1904
  {
1863
1905
    TransactionServices &transaction_services= TransactionServices::singleton();
1864
1906
    main_da.can_overwrite_status= true;
1865
 
    transaction_services.autocommitOrRollback(*this, is_error());
 
1907
    transaction_services.autocommitOrRollback(this, is_error());
1866
1908
    main_da.can_overwrite_status= false;
1867
1909
    transaction.stmt.reset();
1868
1910
  }
1884
1926
  /*
1885
1927
    Note that we need to hold table::Cache::singleton().mutex() while changing the
1886
1928
    open_tables list. Another thread may work on it.
1887
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
1929
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1888
1930
    Closing a MERGE child before the parent would be fatal if the
1889
1931
    other thread tries to abort the MERGE lock in between.
1890
1932
  */
1918
1960
 
1919
1961
    if (not lock_tables(tables, counter, &need_reopen))
1920
1962
      break;
1921
 
 
1922
1963
    if (not need_reopen)
1923
1964
      return true;
1924
 
 
1925
1965
    close_tables_for_reopen(&tables);
1926
1966
  }
1927
 
 
1928
 
  if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
 
1967
  if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
 
1968
       (
 
1969
        mysql_handle_derived(lex, &mysql_derived_filling))))
1929
1970
    return true;
1930
1971
 
1931
1972
  return false;
1937
1978
  might be an issue (lame engines).
1938
1979
*/
1939
1980
 
1940
 
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
 
1981
bool Open_tables_state::rm_temporary_table(const TableIdentifier &identifier, bool best_effort)
1941
1982
{
1942
 
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
 
1983
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1943
1984
  {
1944
1985
    if (not best_effort)
1945
1986
    {
1946
1987
      std::string path;
1947
1988
      identifier.getSQLPath(path);
1948
 
      errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
 
1989
      errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
1949
1990
                    path.c_str(), errno);
1950
1991
    }
1951
1992
 
1955
1996
  return false;
1956
1997
}
1957
1998
 
1958
 
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
 
1999
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const TableIdentifier &identifier)
1959
2000
{
1960
 
  drizzled::error_t error;
1961
2001
  assert(base);
1962
2002
 
1963
 
  if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
 
2003
  if (plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier))
1964
2004
  {
1965
2005
    std::string path;
1966
2006
    identifier.getSQLPath(path);
1967
 
    errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1968
 
                  path.c_str(), error);
 
2007
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
 
2008
                  path.c_str(), errno);
1969
2009
 
1970
2010
    return true;
1971
2011
  }
1989
2029
  {
1990
2030
    bool have_proto= false;
1991
2031
 
1992
 
    message::Table *proto= table->getShare()->getTableMessage();
1993
 
    if (table->getShare()->getTableMessage())
 
2032
    message::Table *proto= table->getShare()->getTableProto();
 
2033
    if (table->getShare()->getTableProto())
1994
2034
      have_proto= true;
1995
2035
 
1996
2036
    const char *answer= have_proto ? "true" : "false";
2007
2047
  }
2008
2048
}
2009
2049
 
2010
 
table::Singular *Session::getInstanceTable()
2011
 
{
2012
 
  temporary_shares.push_back(new table::Singular()); // This will not go into the tableshare cache, so no key is used.
2013
 
 
2014
 
  table::Singular *tmp_share= temporary_shares.back();
 
2050
bool Session::TableMessages::storeTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2051
{
 
2052
  table_message_cache.insert(make_pair(identifier.getPath(), table_message));
 
2053
 
 
2054
  return true;
 
2055
}
 
2056
 
 
2057
bool Session::TableMessages::removeTableMessage(const TableIdentifier &identifier)
 
2058
{
 
2059
  TableMessageCache::iterator iter;
 
2060
 
 
2061
  iter= table_message_cache.find(identifier.getPath());
 
2062
 
 
2063
  if (iter == table_message_cache.end())
 
2064
    return false;
 
2065
 
 
2066
  table_message_cache.erase(iter);
 
2067
 
 
2068
  return true;
 
2069
}
 
2070
 
 
2071
bool Session::TableMessages::getTableMessage(const TableIdentifier &identifier, message::Table &table_message)
 
2072
{
 
2073
  TableMessageCache::iterator iter;
 
2074
 
 
2075
  iter= table_message_cache.find(identifier.getPath());
 
2076
 
 
2077
  if (iter == table_message_cache.end())
 
2078
    return false;
 
2079
 
 
2080
  table_message.CopyFrom(((*iter).second));
 
2081
 
 
2082
  return true;
 
2083
}
 
2084
 
 
2085
bool Session::TableMessages::doesTableMessageExist(const TableIdentifier &identifier)
 
2086
{
 
2087
  TableMessageCache::iterator iter;
 
2088
 
 
2089
  iter= table_message_cache.find(identifier.getPath());
 
2090
 
 
2091
  if (iter == table_message_cache.end())
 
2092
  {
 
2093
    return false;
 
2094
  }
 
2095
 
 
2096
  return true;
 
2097
}
 
2098
 
 
2099
bool Session::TableMessages::renameTableMessage(const TableIdentifier &from, const TableIdentifier &to)
 
2100
{
 
2101
  TableMessageCache::iterator iter;
 
2102
 
 
2103
  table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
 
2104
 
 
2105
  iter= table_message_cache.find(to.getPath());
 
2106
 
 
2107
  if (iter == table_message_cache.end())
 
2108
  {
 
2109
    return false;
 
2110
  }
 
2111
 
 
2112
  (*iter).second.set_schema(to.getSchemaName());
 
2113
  (*iter).second.set_name(to.getTableName());
 
2114
 
 
2115
  return true;
 
2116
}
 
2117
 
 
2118
table::Instance *Session::getInstanceTable()
 
2119
{
 
2120
  temporary_shares.push_back(new table::Instance()); // This will not go into the tableshare cache, so no key is used.
 
2121
 
 
2122
  table::Instance *tmp_share= temporary_shares.back();
2015
2123
 
2016
2124
  assert(tmp_share);
2017
2125
 
2037
2145
  @return
2038
2146
    0 if out of memory, Table object in case of success
2039
2147
*/
2040
 
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
 
2148
table::Instance *Session::getInstanceTable(List<CreateField> &field_list)
2041
2149
{
2042
 
  temporary_shares.push_back(new table::Singular(this, field_list)); // This will not go into the tableshare cache, so no key is used.
 
2150
  temporary_shares.push_back(new table::Instance(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2043
2151
 
2044
 
  table::Singular *tmp_share= temporary_shares.back();
 
2152
  table::Instance *tmp_share= temporary_shares.back();
2045
2153
 
2046
2154
  assert(tmp_share);
2047
2155