~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

This patch completes the first step in the splitting of
the XA resource manager API from the storage engine API,
as outlined in the specification here:

http://drizzle.org/wiki/XaStorageEngine

* Splits plugin::StorageEngine into a base StorageEngine
  class and two derived classes, TransactionalStorageEngine
  and XaStorageEngine.  XaStorageEngine derives from
  TransactionalStorageEngine and creates the XA Resource
  Manager API for storage engines.

  - The methods moved from StorageEngine to TransactionalStorageEngine
    include releaseTemporaryLatches(), startConsistentSnapshot(), 
    commit(), rollback(), setSavepoint(), releaseSavepoint(),
    rollbackToSavepoint() and hasTwoPhaseCommit()
  - The methods moved from StorageEngine to XaStorageEngine
    include recover(), commitXid(), rollbackXid(), and prepare()

* Places all static "EngineVector"s into their proper
  namespaces (typedefs belong in header files, not implementation files)
  and places all static methods corresponding
  to either only transactional engines or only XA engines
  into their respective files in /drizzled/plugin/

* Modifies the InnoDB "handler" files to extend plugin::XaStorageEngine
  and not plugin::StorageEngine

The next step, as outlined in the wiki spec page above, is to isolate
the XA Resource Manager API into its own plugin class and modify
plugin::XaStorageEngine to implement plugin::XaResourceManager via
composition.  This is necessary to enable building plugins which can
participate in an XA transaction *without having to have that plugin
implement the entire storage engine API*

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#include <config.h>
 
16
#include "config.h"
17
17
 
18
18
#define DRIZZLE_LEX 1
19
19
 
20
 
#include <drizzled/item/num.h>
21
 
#include <drizzled/abort_exception.h>
22
20
#include <drizzled/my_hash.h>
23
21
#include <drizzled/error.h>
24
22
#include <drizzled/nested_join.h>
25
23
#include <drizzled/query_id.h>
26
 
#include <drizzled/transaction_services.h>
27
24
#include <drizzled/sql_parse.h>
28
25
#include <drizzled/data_home.h>
29
26
#include <drizzled/sql_base.h>
30
27
#include <drizzled/show.h>
 
28
#include <drizzled/db.h>
 
29
#include <drizzled/plugin/info_schema_table.h>
31
30
#include <drizzled/function/time/unix_timestamp.h>
32
31
#include <drizzled/function/get_system_var.h>
33
32
#include <drizzled/item/cmpfunc.h>
34
33
#include <drizzled/item/null.h>
35
34
#include <drizzled/session.h>
36
 
#include <drizzled/session/cache.h>
37
35
#include <drizzled/sql_load.h>
38
36
#include <drizzled/lock.h>
39
37
#include <drizzled/select_send.h>
40
38
#include <drizzled/plugin/client.h>
41
39
#include <drizzled/statement.h>
42
40
#include <drizzled/statement/alter_table.h>
43
 
#include <drizzled/probes.h>
44
 
#include <drizzled/global_charset_info.h>
45
 
 
46
 
#include <drizzled/plugin/logging.h>
47
 
#include <drizzled/plugin/query_rewrite.h>
48
 
#include <drizzled/plugin/query_cache.h>
49
 
#include <drizzled/plugin/authorization.h>
50
 
#include <drizzled/optimizer/explain_plan.h>
51
 
#include <drizzled/pthread_globals.h>
52
 
#include <drizzled/plugin/event_observer.h>
53
 
#include <drizzled/visibility.h>
54
 
 
55
 
#include <drizzled/schema.h>
 
41
#include "drizzled/probes.h"
 
42
#include "drizzled/session_list.h"
 
43
#include "drizzled/global_charset_info.h"
 
44
#include "drizzled/transaction_services.h"
 
45
 
 
46
#include "drizzled/plugin/logging.h"
 
47
#include "drizzled/plugin/info_schema_table.h"
 
48
#include "drizzled/optimizer/explain_plan.h"
 
49
#include "drizzled/pthread_globals.h"
56
50
 
57
51
#include <limits.h>
58
52
 
59
53
#include <bitset>
60
54
#include <algorithm>
61
 
#include <boost/date_time.hpp>
62
 
#include <drizzled/internal/my_sys.h>
 
55
 
 
56
#include "drizzled/internal/my_sys.h"
63
57
 
64
58
using namespace std;
65
59
 
66
 
extern int base_sql_parse(drizzled::Session *session); // from sql_yacc.cc
 
60
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
67
61
 
68
62
namespace drizzled
69
63
{
70
64
 
71
65
/* Prototypes */
72
 
bool my_yyoverflow(short **a, ParserType **b, ulong *yystacksize);
 
66
bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
73
67
static bool parse_sql(Session *session, Lex_input_stream *lip);
74
 
void parse(Session *session, const char *inBuf, uint32_t length);
 
68
static void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
69
                 const char ** found_semicolon);
75
70
 
76
71
/**
77
72
  @defgroup Runtime_Environment Runtime Environment
81
76
extern size_t my_thread_stack_size;
82
77
extern const CHARSET_INFO *character_set_filesystem;
83
78
 
84
 
namespace
85
 
{
86
 
 
87
 
static const std::string command_name[COM_END+1]={
88
 
  "Sleep",
89
 
  "Quit",
90
 
  "Init DB",
91
 
  "Query",
92
 
  "Shutdown",
93
 
  "Connect",
94
 
  "Ping",
95
 
  "Error"  // Last command number
 
79
const LEX_STRING command_name[COM_END+1]={
 
80
  { C_STRING_WITH_LEN("Sleep") },
 
81
  { C_STRING_WITH_LEN("Quit") },
 
82
  { C_STRING_WITH_LEN("Init DB") },
 
83
  { C_STRING_WITH_LEN("Query") },
 
84
  { C_STRING_WITH_LEN("Shutdown") },
 
85
  { C_STRING_WITH_LEN("Connect") },
 
86
  { C_STRING_WITH_LEN("Ping") },
 
87
  { C_STRING_WITH_LEN("Error") }  // Last command number
96
88
};
97
89
 
98
 
}
99
 
 
100
90
const char *xa_state_names[]={
101
91
  "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
102
92
};
115
105
*/
116
106
bitset<CF_BIT_SIZE> sql_command_flags[SQLCOM_END+1];
117
107
 
118
 
const std::string &getCommandName(const enum_server_command& command)
119
 
{
120
 
  return command_name[command];
121
 
}
122
 
 
123
108
void init_update_queries(void)
124
109
{
125
110
  uint32_t x;
145
130
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
146
131
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
147
132
 
 
133
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
 
134
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
 
135
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
 
136
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
 
137
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
148
138
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
149
139
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
140
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
150
141
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
151
142
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
152
143
 
 
144
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
145
                                               CF_SHOW_TABLE_COMMAND);
 
146
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
147
                                                CF_SHOW_TABLE_COMMAND);
153
148
  /*
154
149
    The following admin table operations are allowed
155
150
    on log tables.
168
163
                         can be zero.
169
164
 
170
165
  @todo
171
 
    set session->getLex()->sql_command to SQLCOM_END here.
 
166
    set session->lex->sql_command to SQLCOM_END here.
172
167
  @todo
173
168
    The following has to be changed to an 8 byte integer
174
169
 
184
179
  bool error= 0;
185
180
  Query_id &query_id= Query_id::get_query_id();
186
181
 
187
 
  DRIZZLE_COMMAND_START(session->thread_id, command);
 
182
  DRIZZLE_COMMAND_START(session->thread_id,
 
183
                        command);
188
184
 
189
185
  session->command= command;
190
 
  session->getLex()->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
 
186
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
191
187
  session->set_time();
192
188
  session->setQueryId(query_id.value());
193
189
 
197
193
    break;
198
194
  /* Increase id and count all other statements. */
199
195
  default:
200
 
    session->status_var.questions++;
 
196
    statistic_increment(session->status_var.questions, &LOCK_status);
201
197
    query_id.next();
202
198
  }
203
199
 
204
 
  /* @todo set session->getLex()->sql_command to SQLCOM_END here */
 
200
  /* TODO: set session->lex->sql_command to SQLCOM_END here */
205
201
 
206
202
  plugin::Logging::preDo(session);
207
 
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
208
 
  {
209
 
    // We should do something about an error...
210
 
  }
211
203
 
212
204
  session->server_status&=
213
205
           ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
214
206
  switch (command) {
215
207
  case COM_INIT_DB:
216
208
  {
217
 
    if (packet_length == 0)
218
 
    {
219
 
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
220
 
      break;
221
 
    }
222
 
 
223
 
    string tmp(packet, packet_length);
224
 
 
225
 
    identifier::Schema identifier(tmp);
226
 
 
227
 
    if (not schema::change(*session, identifier))
 
209
    LEX_STRING tmp;
 
210
    status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
 
211
    tmp.str= packet;
 
212
    tmp.length= packet_length;
 
213
    if (!mysql_change_db(session, &tmp, false))
228
214
    {
229
215
      session->my_ok();
230
216
    }
232
218
  }
233
219
  case COM_QUERY:
234
220
  {
235
 
    if (not session->readAndStoreQuery(packet, packet_length))
 
221
    if (! session->readAndStoreQuery(packet, packet_length))
236
222
      break;                                    // fatal error is set
237
 
    DRIZZLE_QUERY_START(session->getQueryString()->c_str(),
 
223
    DRIZZLE_QUERY_START(session->query,
238
224
                        session->thread_id,
239
 
                        const_cast<const char *>(session->schema()->c_str()));
 
225
                        const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
 
226
    const char* end_of_stmt= NULL;
240
227
 
241
 
    parse(session, session->getQueryString()->c_str(), session->getQueryString()->length());
 
228
    mysql_parse(session, session->query, session->query_length, &end_of_stmt);
242
229
 
243
230
    break;
244
231
  }
249
236
    break;
250
237
  case COM_SHUTDOWN:
251
238
  {
252
 
    session->status_var.com_other++;
 
239
    status_var_increment(session->status_var.com_other);
253
240
    session->my_eof();
254
241
    session->close_thread_tables();                     // Free before kill
255
242
    kill_drizzle();
257
244
    break;
258
245
  }
259
246
  case COM_PING:
260
 
    session->status_var.com_other++;
 
247
    status_var_increment(session->status_var.com_other);
261
248
    session->my_ok();                           // Tell client we are alive
262
249
    break;
263
250
  case COM_SLEEP:
271
258
  /* If commit fails, we should be able to reset the OK status. */
272
259
  session->main_da.can_overwrite_status= true;
273
260
  TransactionServices &transaction_services= TransactionServices::singleton();
274
 
  transaction_services.autocommitOrRollback(*session, session->is_error());
 
261
  transaction_services.ha_autocommit_or_rollback(session, session->is_error());
275
262
  session->main_da.can_overwrite_status= false;
276
263
 
277
264
  session->transaction.stmt.reset();
283
270
    if (! session->main_da.is_set())
284
271
      session->send_kill_message();
285
272
  }
286
 
  if (session->getKilled() == Session::KILL_QUERY || session->getKilled() == Session::KILL_BAD_DATA)
 
273
  if (session->killed == Session::KILL_QUERY || session->killed == Session::KILL_BAD_DATA)
287
274
  {
288
 
    session->setKilled(Session::NOT_KILLED);
289
 
    session->setAbort(false);
 
275
    session->killed= Session::NOT_KILLED;
 
276
    session->mysys_var->abort= 0;
290
277
  }
291
278
 
292
279
  /* Can not be true, but do not take chances in production. */
296
283
  {
297
284
  case Diagnostics_area::DA_ERROR:
298
285
    /* The query failed, send error to log and abort bootstrap. */
299
 
    session->getClient()->sendError(session->main_da.sql_errno(),
 
286
    session->client->sendError(session->main_da.sql_errno(),
300
287
                               session->main_da.message());
301
288
    break;
302
289
 
303
290
  case Diagnostics_area::DA_EOF:
304
 
    session->getClient()->sendEOF();
 
291
    session->client->sendEOF();
305
292
    break;
306
293
 
307
294
  case Diagnostics_area::DA_OK:
308
 
    session->getClient()->sendOK();
 
295
    session->client->sendOK();
309
296
    break;
310
297
 
311
298
  case Diagnostics_area::DA_DISABLED:
313
300
 
314
301
  case Diagnostics_area::DA_EMPTY:
315
302
  default:
316
 
    session->getClient()->sendOK();
 
303
    session->client->sendOK();
317
304
    break;
318
305
  }
319
306
 
324
311
  session->close_thread_tables();
325
312
 
326
313
  plugin::Logging::postDo(session);
327
 
  if (unlikely(plugin::EventObserver::afterStatement(*session)))
328
 
  {
329
 
    // We should do something about an error...
330
 
  }
331
314
 
332
315
  /* Store temp state for processlist */
333
316
  session->set_proc_info("cleaning up");
334
317
  session->command= COM_SLEEP;
335
 
  session->resetQueryString();
 
318
  memset(session->process_list_info, 0, PROCESS_LIST_WIDTH);
 
319
  session->query= 0;
 
320
  session->query_length= 0;
336
321
 
337
322
  session->set_proc_info(NULL);
338
 
  session->mem_root->free_root(MYF(memory::KEEP_PREALLOC));
 
323
  free_root(session->mem_root,MYF(memory::KEEP_PREALLOC));
339
324
 
340
325
  if (DRIZZLE_QUERY_DONE_ENABLED() || DRIZZLE_COMMAND_DONE_ENABLED())
341
326
  {
375
360
    1                 out of memory or SHOW commands are not allowed
376
361
                      in this version of the server.
377
362
*/
378
 
static bool _schema_select(Session *session, Select_Lex *sel,
379
 
                           const string& schema_table_name)
380
 
{
381
 
  LEX_STRING db, table;
382
 
  bitset<NUM_OF_TABLE_OPTIONS> table_options;
383
 
  /*
384
 
     We have to make non const db_name & table_name
385
 
     because of lower_case_table_names
386
 
  */
387
 
  session->make_lex_string(&db, "data_dictionary", sizeof("data_dictionary"), false);
388
 
  session->make_lex_string(&table, schema_table_name, false);
389
 
 
390
 
  if (! sel->add_table_to_list(session, new Table_ident(db, table),
391
 
                               NULL, table_options, TL_READ))
392
 
  {
393
 
    return true;
394
 
  }
395
 
  return false;
396
 
}
397
 
 
398
 
int prepare_new_schema_table(Session *session, LEX *lex,
399
 
                             const string& schema_table_name)
 
363
 
 
364
int prepare_schema_table(Session *session, LEX *lex, Table_ident *table_ident,
 
365
                         const string& schema_table_name)
400
366
{
401
367
  Select_Lex *schema_select_lex= NULL;
402
368
 
 
369
 
 
370
  if (schema_table_name.compare("TABLES") == 0 ||
 
371
      schema_table_name.compare("TABLE_NAMES") == 0)
 
372
  {
 
373
    LEX_STRING db;
 
374
    size_t dummy;
 
375
    if (lex->select_lex.db == NULL &&
 
376
        lex->copy_db_to(&lex->select_lex.db, &dummy))
 
377
    {
 
378
      return (1);
 
379
    }
 
380
    schema_select_lex= new Select_Lex();
 
381
    db.str= schema_select_lex->db= lex->select_lex.db;
 
382
    schema_select_lex->table_list.first= NULL;
 
383
    db.length= strlen(db.str);
 
384
 
 
385
    if (check_db_name(&db))
 
386
    {
 
387
      my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
 
388
      return (1);
 
389
    }
 
390
  }
 
391
  else if (schema_table_name.compare("COLUMNS") == 0 ||
 
392
           schema_table_name.compare("STATISTICS") == 0)
 
393
  {
 
394
    assert(table_ident);
 
395
    TableList **query_tables_last= lex->query_tables_last;
 
396
    schema_select_lex= new Select_Lex();
 
397
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
398
    schema_select_lex->parent_lex= lex;
 
399
    schema_select_lex->init_query();
 
400
    if (! schema_select_lex->add_table_to_list(session, table_ident, 0, 0, TL_READ))
 
401
    {
 
402
      return (1);
 
403
    }
 
404
    lex->query_tables_last= query_tables_last;
 
405
  }
 
406
 
403
407
  Select_Lex *select_lex= lex->current_select;
404
408
  assert(select_lex);
405
 
  if (_schema_select(session, select_lex, schema_table_name))
 
409
  if (make_schema_select(session, select_lex, schema_table_name))
406
410
  {
407
411
    return(1);
408
412
  }
443
447
    true        Error
444
448
*/
445
449
 
446
 
static int execute_command(Session *session)
 
450
static int
 
451
mysql_execute_command(Session *session)
447
452
{
448
453
  bool res= false;
449
 
 
 
454
  LEX  *lex= session->lex;
450
455
  /* first Select_Lex (have special meaning for many of non-SELECTcommands) */
451
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
452
 
 
 
456
  Select_Lex *select_lex= &lex->select_lex;
453
457
  /* list of all tables in query */
454
458
  TableList *all_tables;
 
459
  /* A peek into the query string */
 
460
  size_t proc_info_len= session->query_length > PROCESS_LIST_WIDTH ?
 
461
                        PROCESS_LIST_WIDTH : session->query_length;
 
462
 
 
463
  memcpy(session->process_list_info, session->query, proc_info_len);
 
464
  session->process_list_info[proc_info_len]= '\0';
455
465
 
456
466
  /*
457
467
    In many cases first table of main Select_Lex have special meaning =>
468
478
    assert(first_table == all_tables);
469
479
    assert(first_table == all_tables && first_table != 0);
470
480
  */
471
 
  session->getLex()->first_lists_tables_same();
472
 
 
 
481
  lex->first_lists_tables_same();
473
482
  /* should be assigned after making first tables same */
474
 
  all_tables= session->getLex()->query_tables;
475
 
 
 
483
  all_tables= lex->query_tables;
476
484
  /* set context for commands which do not use setup_tables */
477
 
  select_lex->context.resolve_in_table_list_only((TableList*)select_lex->table_list.first);
 
485
  select_lex->
 
486
    context.resolve_in_table_list_only((TableList*)select_lex->
 
487
                                       table_list.first);
478
488
 
479
489
  /*
480
490
    Reset warning count for each query that uses tables
483
493
    variables, but for now this is probably good enough.
484
494
    Don't reset warnings when executing a stored routine.
485
495
  */
486
 
  if (all_tables || ! session->getLex()->is_single_level_stmt())
 
496
  if (all_tables || ! lex->is_single_level_stmt())
487
497
  {
488
498
    drizzle_reset_errors(session, 0);
489
499
  }
490
500
 
 
501
  status_var_increment(session->status_var.com_stat[lex->sql_command]);
 
502
 
491
503
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
492
504
 
493
 
  if (! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
494
 
      && ! session->inTransaction()
495
 
      && session->getLex()->statement->isTransactional())
496
 
  {
497
 
    if (session->startTransaction() == false)
498
 
    {
499
 
      my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
500
 
      return true;
501
 
    }
502
 
  }
503
 
 
504
505
  /* now we are ready to execute the statement */
505
 
  res= session->getLex()->statement->execute();
 
506
  res= lex->statement->execute();
 
507
 
506
508
  session->set_proc_info("query end");
 
509
 
507
510
  /*
508
511
    The return value for ROW_COUNT() is "implementation dependent" if the
509
512
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
510
513
    wants. We also keep the last value in case of SQLCOM_CALL or
511
514
    SQLCOM_EXECUTE.
512
515
  */
513
 
  if (! (sql_command_flags[session->getLex()->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
 
516
  if (! (sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
514
517
  {
515
518
    session->row_count_func= -1;
516
519
  }
517
520
 
518
521
  return (res || session->is_error());
519
522
}
 
523
 
520
524
bool execute_sqlcom_select(Session *session, TableList *all_tables)
521
525
{
522
 
  LEX   *lex= session->getLex();
 
526
  LEX   *lex= session->lex;
523
527
  select_result *result=lex->result;
524
528
  bool res= false;
525
529
  /* assign global limit variable if limit is not given */
529
533
      param->select_limit=
530
534
        new Item_int((uint64_t) session->variables.select_limit);
531
535
  }
532
 
 
533
 
  if (all_tables
534
 
      && ! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
535
 
      && ! session->inTransaction()
536
 
      && ! lex->statement->isShow())
537
 
  {
538
 
    if (session->startTransaction() == false)
539
 
    {
540
 
      my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
541
 
      return true;
542
 
    }
543
 
  }
544
 
 
545
 
  if (not (res= session->openTablesLock(all_tables)))
 
536
  if (!(res= session->openTablesLock(all_tables)))
546
537
  {
547
538
    if (lex->describe)
548
539
    {
556
547
        return true;
557
548
      session->send_explain_fields(result);
558
549
      optimizer::ExplainPlan planner;
559
 
      res= planner.explainUnion(session, &session->getLex()->unit, result);
 
550
      res= planner.explainUnion(session, &session->lex->unit, result);
560
551
      if (lex->describe & DESCRIBE_EXTENDED)
561
552
      {
562
553
        char buff[1024];
563
554
        String str(buff,(uint32_t) sizeof(buff), system_charset_info);
564
555
        str.length(0);
565
 
        session->getLex()->unit.print(&str, QT_ORDINARY);
 
556
        session->lex->unit.print(&str, QT_ORDINARY);
566
557
        str.append('\0');
567
558
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
568
559
                     ER_YES, str.ptr());
571
562
        result->abort();
572
563
      else
573
564
        result->send_eof();
574
 
 
575
565
      delete result;
576
566
    }
577
567
    else
578
568
    {
579
569
      if (!result && !(result= new select_send()))
580
570
        return true;
581
 
 
582
 
      /* Init the Query Cache plugin */
583
 
      plugin::QueryCache::prepareResultset(session); 
584
571
      res= handle_select(session, lex, result, 0);
585
 
      /* Send the Resultset to the cache */
586
 
      plugin::QueryCache::setResultset(session); 
587
 
 
588
572
      if (result != lex->result)
589
573
        delete result;
590
574
    }
596
580
#define MY_YACC_INIT 1000                       // Start with big alloc
597
581
#define MY_YACC_MAX  32000                      // Because of 'short'
598
582
 
599
 
bool my_yyoverflow(short **yyss, ParserType **yyvs, ulong *yystacksize)
 
583
bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
600
584
{
601
 
  LEX   *lex= current_session->getLex();
 
585
  LEX   *lex= current_session->lex;
602
586
  ulong old_info=0;
603
587
  if ((uint32_t) *yystacksize >= MY_YACC_MAX)
604
588
    return 1;
621
605
    memcpy(lex->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
622
606
  }
623
607
  *yyss=(short*) lex->yacc_yyss;
624
 
  *yyvs=(ParserType*) lex->yacc_yyvs;
 
608
  *yyvs=(YYSTYPE*) lex->yacc_yyvs;
625
609
  return 0;
626
610
}
627
611
 
628
612
 
629
613
void
630
 
init_select(LEX *lex)
 
614
mysql_init_select(LEX *lex)
631
615
{
632
616
  Select_Lex *select_lex= lex->current_select;
633
617
  select_lex->init_select();
641
625
 
642
626
 
643
627
bool
644
 
new_select(LEX *lex, bool move_down)
 
628
mysql_new_select(LEX *lex, bool move_down)
645
629
{
646
630
  Select_Lex *select_lex;
647
631
  Session *session= lex->session;
648
632
 
649
633
  if (!(select_lex= new (session->mem_root) Select_Lex()))
650
 
    return true;
651
 
 
 
634
    return(1);
652
635
  select_lex->select_number= ++session->select_number;
653
636
  select_lex->parent_lex= lex; /* Used in init_query. */
654
637
  select_lex->init_query();
655
638
  select_lex->init_select();
656
639
  lex->nest_level++;
657
 
 
658
640
  if (lex->nest_level > (int) MAX_SELECT_NESTING)
659
641
  {
660
642
    my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING);
661
643
    return(1);
662
644
  }
663
 
 
664
645
  select_lex->nest_level= lex->nest_level;
665
646
  if (move_down)
666
647
  {
688
669
    if (lex->current_select->order_list.first && !lex->current_select->braces)
689
670
    {
690
671
      my_error(ER_WRONG_USAGE, MYF(0), "UNION", "order_st BY");
691
 
      return true;
 
672
      return(1);
692
673
    }
693
 
 
694
674
    select_lex->include_neighbour(lex->current_select);
695
675
    Select_Lex_Unit *unit= select_lex->master_unit();
696
 
 
697
 
    if (not unit->fake_select_lex && unit->add_fake_select_lex(lex->session))
698
 
      return true;
699
 
 
 
676
    if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->session))
 
677
      return(1);
700
678
    select_lex->context.outer_context=
701
679
                unit->first_select()->context.outer_context;
702
680
  }
709
687
    list
710
688
  */
711
689
  select_lex->context.resolve_in_select_list= true;
712
 
 
713
 
  return false;
 
690
  return(0);
714
691
}
715
692
 
716
693
/**
723
700
  @param var_name               Variable name
724
701
*/
725
702
 
726
 
void create_select_for_variable(Session *session, const char *var_name)
 
703
void create_select_for_variable(const char *var_name)
727
704
{
 
705
  Session *session;
728
706
  LEX *lex;
729
707
  LEX_STRING tmp, null_lex_string;
730
708
  Item *var;
731
709
  char buff[MAX_SYS_VAR_LENGTH*2+4+8];
732
710
  char *end= buff;
733
711
 
734
 
  lex= session->getLex();
735
 
  init_select(lex);
 
712
  session= current_session;
 
713
  lex= session->lex;
 
714
  mysql_init_select(lex);
736
715
  lex->sql_command= SQLCOM_SELECT;
737
716
  tmp.str= (char*) var_name;
738
717
  tmp.length=strlen(var_name);
743
722
  */
744
723
  if ((var= get_system_var(session, OPT_SESSION, tmp, null_lex_string)))
745
724
  {
746
 
    end+= snprintf(buff, sizeof(buff), "@@session.%s", var_name);
 
725
    end+= sprintf(buff, "@@session.%s", var_name);
747
726
    var->set_name(buff, end-buff, system_charset_info);
748
727
    session->add_item_to_list(var);
749
728
  }
 
729
  return;
750
730
}
751
731
 
752
732
 
756
736
  @param       session     Current thread
757
737
  @param       inBuf   Begining of the query text
758
738
  @param       length  Length of the query text
 
739
  @param[out]  found_semicolon For multi queries, position of the character of
 
740
                               the next query in the query text.
759
741
*/
760
742
 
761
 
void parse(Session *session, const char *inBuf, uint32_t length)
 
743
static void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
744
                 const char ** found_semicolon)
762
745
{
763
 
  session->getLex()->start(session);
764
 
 
 
746
  /*
 
747
    Warning.
 
748
    The purpose of query_cache_send_result_to_client() is to lookup the
 
749
    query in the query cache first, to avoid parsing and executing it.
 
750
    So, the natural implementation would be to:
 
751
    - first, call query_cache_send_result_to_client,
 
752
    - second, if caching failed, initialise the lexical and syntactic parser.
 
753
    The problem is that the query cache depends on a clean initialization
 
754
    of (among others) lex->safe_to_cache_query and session->server_status,
 
755
    which are reset respectively in
 
756
    - lex_start()
 
757
    - mysql_reset_session_for_next_command()
 
758
    So, initializing the lexical analyser *before* using the query cache
 
759
    is required for the cache to work properly.
 
760
    FIXME: cleanup the dependencies in the code to simplify this.
 
761
  */
 
762
  lex_start(session);
765
763
  session->reset_for_next_command();
766
 
  /* Check if the Query is Cached if and return true if yes
767
 
   * TODO the plugin has to make sure that the query is cacheble
768
 
   * by setting the query_safe_cache param to TRUE
769
 
   */
770
 
  bool res= true;
771
 
  if (plugin::QueryCache::isCached(session))
772
 
  {
773
 
    res= plugin::QueryCache::sendCachedResultset(session);
774
 
  }
775
 
  if (not res)
776
 
  {
777
 
    return;
778
 
  }
779
 
  LEX *lex= session->getLex();
780
 
  Lex_input_stream lip(session, inBuf, length);
781
 
  bool err= parse_sql(session, &lip);
782
 
  if (!err)
783
 
  {
 
764
 
 
765
  {
 
766
    LEX *lex= session->lex;
 
767
 
 
768
    Lex_input_stream lip(session, inBuf, length);
 
769
 
 
770
    bool err= parse_sql(session, &lip);
 
771
    *found_semicolon= lip.found_semicolon;
 
772
 
 
773
    if (!err)
784
774
    {
785
 
      if (not session->is_error())
786
775
      {
787
 
        DRIZZLE_QUERY_EXEC_START(session->getQueryString()->c_str(),
788
 
                                 session->thread_id,
789
 
                                 const_cast<const char *>(session->schema()->c_str()));
790
 
        // Implement Views here --Brian
791
 
        /* Actually execute the query */
792
 
        try 
793
 
        {
794
 
          execute_command(session);
795
 
        }
796
 
        catch (...)
797
 
        {
798
 
          // Just try to catch any random failures that could have come
799
 
          // during execution.
800
 
          DRIZZLE_ABORT;
801
 
        }
802
 
        DRIZZLE_QUERY_EXEC_DONE(0);
 
776
        if (! session->is_error())
 
777
        {
 
778
          /*
 
779
            Binlog logs a string starting from session->query and having length
 
780
            session->query_length; so we set session->query_length correctly (to not
 
781
            log several statements in one event, when we executed only first).
 
782
            We set it to not see the ';' (otherwise it would get into binlog
 
783
            and Query_log_event::print() would give ';;' output).
 
784
            This also helps display only the current query in SHOW
 
785
            PROCESSLIST.
 
786
            Note that we don't need LOCK_thread_count to modify query_length.
 
787
          */
 
788
          if (*found_semicolon &&
 
789
              (session->query_length= (ulong)(*found_semicolon - session->query)))
 
790
            session->query_length--;
 
791
          DRIZZLE_QUERY_EXEC_START(session->query,
 
792
                                   session->thread_id,
 
793
                                   const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
 
794
          /* Actually execute the query */
 
795
          mysql_execute_command(session);
 
796
          DRIZZLE_QUERY_EXEC_DONE(0);
 
797
        }
803
798
      }
804
799
    }
805
 
  }
806
 
  else
807
 
  {
808
 
    assert(session->is_error());
809
 
  }
810
 
  lex->unit.cleanup();
811
 
  session->set_proc_info("freeing items");
812
 
  session->end_statement();
813
 
  session->cleanup_after_query();
814
 
  session->set_end_timer();
 
800
    else
 
801
    {
 
802
      assert(session->is_error());
 
803
    }
 
804
    lex->unit.cleanup();
 
805
    session->set_proc_info("freeing items");
 
806
    session->end_statement();
 
807
    session->cleanup_after_query();
 
808
  }
 
809
 
 
810
  return;
815
811
}
816
812
 
817
813
 
833
829
                       List<String> *interval_list, const CHARSET_INFO * const cs)
834
830
{
835
831
  register CreateField *new_field;
836
 
  LEX  *lex= session->getLex();
 
832
  LEX  *lex= session->lex;
837
833
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
838
834
 
839
835
  if (check_identifier_name(field_name, ER_TOO_LONG_IDENT))
847
843
                      &default_key_create_info,
848
844
                      0, lex->col_list);
849
845
    statement->alter_info.key_list.push_back(key);
850
 
    lex->col_list.clear();
 
846
    lex->col_list.empty();
851
847
  }
852
848
  if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
853
849
  {
857
853
                 &default_key_create_info, 0,
858
854
                 lex->col_list);
859
855
    statement->alter_info.key_list.push_back(key);
860
 
    lex->col_list.clear();
 
856
    lex->col_list.empty();
861
857
  }
862
858
 
863
859
  if (default_value)
871
867
    */
872
868
    if (default_value->type() == Item::FUNC_ITEM &&
873
869
        !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
874
 
         (type == DRIZZLE_TYPE_TIMESTAMP or type == DRIZZLE_TYPE_MICROTIME)))
 
870
         type == DRIZZLE_TYPE_TIMESTAMP))
875
871
    {
876
872
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
877
873
      return true;
879
875
    else if (default_value->type() == Item::NULL_ITEM)
880
876
    {
881
877
      default_value= 0;
882
 
      if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG)
 
878
      if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
 
879
          NOT_NULL_FLAG)
883
880
      {
884
881
        my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
885
882
        return true;
892
889
    }
893
890
  }
894
891
 
895
 
  if (on_update_value && (type != DRIZZLE_TYPE_TIMESTAMP and type != DRIZZLE_TYPE_MICROTIME))
 
892
  if (on_update_value && type != DRIZZLE_TYPE_TIMESTAMP)
896
893
  {
897
894
    my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
898
895
    return true;
911
908
}
912
909
 
913
910
 
 
911
/** Store position for column in ALTER TABLE .. ADD column. */
 
912
 
 
913
void store_position_for_column(const char *name)
 
914
{
 
915
  current_session->lex->last_field->after=const_cast<char*> (name);
 
916
}
 
917
 
914
918
/**
915
919
  Add a table to list of used tables.
916
920
 
931
935
*/
932
936
 
933
937
TableList *Select_Lex::add_table_to_list(Session *session,
934
 
                                         Table_ident *table,
935
 
                                         LEX_STRING *alias,
936
 
                                         const bitset<NUM_OF_TABLE_OPTIONS>& table_options,
937
 
                                         thr_lock_type lock_type,
938
 
                                         List<Index_hint> *index_hints_arg,
939
 
                                         LEX_STRING *option)
 
938
                                             Table_ident *table,
 
939
                                             LEX_STRING *alias,
 
940
                                             uint32_t table_options,
 
941
                                             thr_lock_type lock_type,
 
942
                                             List<Index_hint> *index_hints_arg,
 
943
                                             LEX_STRING *option)
940
944
{
941
 
  TableList *ptr;
 
945
  register TableList *ptr;
942
946
  TableList *previous_table_ref; /* The table preceding the current one. */
943
947
  char *alias_str;
944
 
  LEX *lex= session->getLex();
 
948
  LEX *lex= session->lex;
945
949
 
946
950
  if (!table)
947
951
    return NULL;                                // End of memory
948
952
  alias_str= alias ? alias->str : table->table.str;
949
 
  if (! table_options.test(TL_OPTION_ALIAS) &&
 
953
  if (!test(table_options & TL_OPTION_ALIAS) &&
950
954
      check_table_name(table->table.str, table->table.length))
951
955
  {
952
956
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
953
957
    return NULL;
954
958
  }
955
959
 
956
 
  if (table->is_derived_table() == false && table->db.str)
 
960
  if (table->is_derived_table() == false && table->db.str &&
 
961
      check_db_name(&table->db))
957
962
  {
958
 
    my_casedn_str(files_charset_info, table->db.str);
959
 
 
960
 
    identifier::Schema schema_identifier(string(table->db.str));
961
 
    if (not schema::check(*session, schema_identifier))
962
 
    {
963
 
 
964
 
      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
965
 
      return NULL;
966
 
    }
 
963
    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
964
    return NULL;
967
965
  }
968
966
 
969
967
  if (!alias)                                   /* Alias is case sensitive */
974
972
                 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
975
973
      return NULL;
976
974
    }
977
 
    if (!(alias_str= (char*) session->getMemRoot()->duplicate(alias_str,table->table.length+1)))
 
975
    if (!(alias_str= (char*) session->memdup(alias_str,table->table.length+1)))
978
976
      return NULL;
979
977
  }
980
978
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
981
979
    return NULL;
982
 
 
983
980
  if (table->db.str)
984
981
  {
985
 
    ptr->setIsFqtn(true);
986
 
    ptr->setSchemaName(table->db.str);
 
982
    ptr->is_fqtn= true;
 
983
    ptr->db= table->db.str;
987
984
    ptr->db_length= table->db.length;
988
985
  }
989
 
  else if (lex->copy_db_to(ptr->getSchemaNamePtr(), &ptr->db_length))
 
986
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
990
987
    return NULL;
991
988
  else
992
 
    ptr->setIsFqtn(false);
 
989
    ptr->is_fqtn= false;
993
990
 
994
991
  ptr->alias= alias_str;
995
 
  ptr->setIsAlias(alias ? true : false);
996
 
  ptr->setTableName(table->table.str);
 
992
  ptr->is_alias= alias ? true : false;
 
993
  if (table->table.length)
 
994
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
995
  ptr->table_name=table->table.str;
997
996
  ptr->table_name_length=table->table.length;
998
997
  ptr->lock_type=   lock_type;
999
 
  ptr->force_index= table_options.test(TL_OPTION_FORCE_INDEX);
1000
 
  ptr->ignore_leaves= table_options.test(TL_OPTION_IGNORE_LEAVES);
 
998
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
 
999
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
1000
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
1001
1001
  ptr->derived=     table->sel;
 
1002
  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
 
1003
                                      INFORMATION_SCHEMA_NAME.c_str()))
 
1004
  {
 
1005
    plugin::InfoSchemaTable *schema_table= plugin::InfoSchemaTable::getTable(ptr->table_name);
 
1006
    if (!schema_table ||
 
1007
        (schema_table->isHidden() &&
 
1008
         ((sql_command_flags[lex->sql_command].test(CF_BIT_STATUS_COMMAND)) == 0 ||
 
1009
          /*
 
1010
            this check is used for show columns|keys from I_S hidden table
 
1011
          */
 
1012
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
1013
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
1014
    {
 
1015
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
1016
               ptr->table_name, INFORMATION_SCHEMA_NAME.c_str());
 
1017
      return NULL;
 
1018
    }
 
1019
  }
1002
1020
  ptr->select_lex=  lex->current_select;
1003
1021
  ptr->index_hints= index_hints_arg;
1004
1022
  ptr->option= option ? option->str : 0;
1010
1028
         tables ;
1011
1029
         tables=tables->next_local)
1012
1030
    {
1013
 
      if (not my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
1014
 
          not my_strcasecmp(system_charset_info, ptr->getSchemaName(), tables->getSchemaName()))
 
1031
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
 
1032
          !strcmp(ptr->db, tables->db))
1015
1033
      {
1016
1034
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
1017
1035
        return NULL;
1075
1093
bool Select_Lex::init_nested_join(Session *session)
1076
1094
{
1077
1095
  TableList *ptr;
1078
 
  NestedJoin *nested_join;
 
1096
  nested_join_st *nested_join;
1079
1097
 
1080
1098
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1081
 
                                       sizeof(NestedJoin))))
 
1099
                                       sizeof(nested_join_st))))
1082
1100
    return true;
1083
 
  ptr->setNestedJoin(((NestedJoin*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1084
 
  nested_join= ptr->getNestedJoin();
 
1101
  nested_join= ptr->nested_join=
 
1102
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
1103
 
1085
1104
  join_list->push_front(ptr);
1086
 
  ptr->setEmbedding(embedding);
1087
 
  ptr->setJoinList(join_list);
 
1105
  ptr->embedding= embedding;
 
1106
  ptr->join_list= join_list;
1088
1107
  ptr->alias= (char*) "(nested_join)";
1089
1108
  embedding= ptr;
1090
1109
  join_list= &nested_join->join_list;
1091
 
  join_list->clear();
 
1110
  join_list->empty();
1092
1111
  return false;
1093
1112
}
1094
1113
 
1110
1129
TableList *Select_Lex::end_nested_join(Session *)
1111
1130
{
1112
1131
  TableList *ptr;
1113
 
  NestedJoin *nested_join;
 
1132
  nested_join_st *nested_join;
1114
1133
 
1115
1134
  assert(embedding);
1116
1135
  ptr= embedding;
1117
 
  join_list= ptr->getJoinList();
1118
 
  embedding= ptr->getEmbedding();
1119
 
  nested_join= ptr->getNestedJoin();
 
1136
  join_list= ptr->join_list;
 
1137
  embedding= ptr->embedding;
 
1138
  nested_join= ptr->nested_join;
1120
1139
  if (nested_join->join_list.elements == 1)
1121
1140
  {
1122
1141
    TableList *embedded= nested_join->join_list.head();
1123
1142
    join_list->pop();
1124
 
    embedded->setJoinList(join_list);
1125
 
    embedded->setEmbedding(embedding);
 
1143
    embedded->join_list= join_list;
 
1144
    embedded->embedding= embedding;
1126
1145
    join_list->push_front(embedded);
1127
1146
    ptr= embedded;
1128
1147
  }
1151
1170
TableList *Select_Lex::nest_last_join(Session *session)
1152
1171
{
1153
1172
  TableList *ptr;
1154
 
  NestedJoin *nested_join;
 
1173
  nested_join_st *nested_join;
1155
1174
  List<TableList> *embedded_list;
1156
1175
 
1157
1176
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1158
 
                                          sizeof(NestedJoin))))
 
1177
                                       sizeof(nested_join_st))))
1159
1178
    return NULL;
1160
 
  ptr->setNestedJoin(((NestedJoin*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1161
 
  nested_join= ptr->getNestedJoin();
1162
 
  ptr->setEmbedding(embedding);
1163
 
  ptr->setJoinList(join_list);
 
1179
  nested_join= ptr->nested_join=
 
1180
    ((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList))));
 
1181
 
 
1182
  ptr->embedding= embedding;
 
1183
  ptr->join_list= join_list;
1164
1184
  ptr->alias= (char*) "(nest_last_join)";
1165
1185
  embedded_list= &nested_join->join_list;
1166
 
  embedded_list->clear();
 
1186
  embedded_list->empty();
1167
1187
 
1168
1188
  for (uint32_t i=0; i < 2; i++)
1169
1189
  {
1170
1190
    TableList *table= join_list->pop();
1171
 
    table->setJoinList(embedded_list);
1172
 
    table->setEmbedding(ptr);
 
1191
    table->join_list= embedded_list;
 
1192
    table->embedding= ptr;
1173
1193
    embedded_list->push_back(table);
1174
1194
    if (table->natural_join)
1175
1195
    {
1205
1225
void Select_Lex::add_joined_table(TableList *table)
1206
1226
{
1207
1227
  join_list->push_front(table);
1208
 
  table->setJoinList(join_list);
1209
 
  table->setEmbedding(embedding);
 
1228
  table->join_list= join_list;
 
1229
  table->embedding= embedding;
1210
1230
}
1211
1231
 
1212
1232
 
1266
1286
 
1267
1287
void Select_Lex::set_lock_for_tables(thr_lock_type lock_type)
1268
1288
{
 
1289
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
1290
 
1269
1291
  for (TableList *tables= (TableList*) table_list.first;
1270
1292
       tables;
1271
1293
       tables= tables->next_local)
1272
1294
  {
1273
1295
    tables->lock_type= lock_type;
 
1296
    tables->updating=  for_update;
1274
1297
  }
 
1298
  return;
1275
1299
}
1276
1300
 
1277
1301
 
1282
1306
    This object is created for any union construct containing a union
1283
1307
    operation and also for any single select union construct of the form
1284
1308
    @verbatim
1285
 
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
 
1309
    (SELECT ... order_st BY order_list [LIMIT n]) order_st BY ...
1286
1310
    @endvarbatim
1287
1311
    or of the form
1288
1312
    @varbatim
1289
 
    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
 
1313
    (SELECT ... order_st BY LIMIT n) order_st BY ...
1290
1314
    @endvarbatim
1291
1315
 
1292
1316
  @param session_arg               thread handle
1311
1335
  fake_select_lex->include_standalone(this,
1312
1336
                                      (Select_Lex_Node**)&fake_select_lex);
1313
1337
  fake_select_lex->select_number= INT_MAX;
1314
 
  fake_select_lex->parent_lex= session_arg->getLex(); /* Used in init_query. */
 
1338
  fake_select_lex->parent_lex= session_arg->lex; /* Used in init_query. */
1315
1339
  fake_select_lex->make_empty_select();
1316
1340
  fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
1317
1341
  fake_select_lex->select_limit= 0;
1318
1342
 
1319
1343
  fake_select_lex->context.outer_context=first_sl->context.outer_context;
1320
 
  /* allow item list resolving in fake select for ORDER BY */
 
1344
  /* allow item list resolving in fake select for order_st BY */
1321
1345
  fake_select_lex->context.resolve_in_select_list= true;
1322
1346
  fake_select_lex->context.select_lex= fake_select_lex;
1323
1347
 
1325
1349
  {
1326
1350
    /*
1327
1351
      This works only for
1328
 
      (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
1329
 
      (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
 
1352
      (SELECT ... order_st BY list [LIMIT n]) order_st BY order_list [LIMIT m],
 
1353
      (SELECT ... LIMIT n) order_st BY order_list [LIMIT m]
1330
1354
      just before the parser starts processing order_list
1331
1355
    */
1332
1356
    global_parameters= fake_select_lex;
1333
1357
    fake_select_lex->no_table_names_allowed= 1;
1334
 
    session_arg->getLex()->current_select= fake_select_lex;
 
1358
    session_arg->lex->current_select= fake_select_lex;
1335
1359
  }
1336
 
  session_arg->getLex()->pop_context();
 
1360
  session_arg->lex->pop_context();
1337
1361
  return(0);
1338
1362
}
1339
1363
 
1369
1393
    left_op->first_leaf_for_name_resolution();
1370
1394
  on_context->last_name_resolution_table=
1371
1395
    right_op->last_leaf_for_name_resolution();
1372
 
  return session->getLex()->push_context(on_context);
 
1396
  return session->lex->push_context(on_context);
1373
1397
}
1374
1398
 
1375
1399
 
1449
1473
 
1450
1474
 
1451
1475
/**
 
1476
  kill on thread.
 
1477
 
 
1478
  @param session                        Thread class
 
1479
  @param id                     Thread id
 
1480
  @param only_kill_query        Should it kill the query or the connection
 
1481
 
 
1482
  @note
 
1483
    This is written such that we have a short lock on LOCK_thread_count
 
1484
*/
 
1485
 
 
1486
static unsigned int
 
1487
kill_one_thread(Session *, ulong id, bool only_kill_query)
 
1488
{
 
1489
  Session *tmp= NULL;
 
1490
  uint32_t error=ER_NO_SUCH_THREAD;
 
1491
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
1492
  
 
1493
  for( vector<Session*>::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
 
1494
  {
 
1495
    if ((*it)->thread_id == id)
 
1496
    {
 
1497
      tmp= *it;
 
1498
      pthread_mutex_lock(&tmp->LOCK_delete);    // Lock from delete
 
1499
      break;
 
1500
    }
 
1501
  }
 
1502
  pthread_mutex_unlock(&LOCK_thread_count);
 
1503
  if (tmp)
 
1504
  {
 
1505
    tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
 
1506
    error=0;
 
1507
    pthread_mutex_unlock(&tmp->LOCK_delete);
 
1508
  }
 
1509
  return(error);
 
1510
}
 
1511
 
 
1512
 
 
1513
/*
 
1514
  kills a thread and sends response
 
1515
 
 
1516
  SYNOPSIS
 
1517
    sql_kill()
 
1518
    session                     Thread class
 
1519
    id                  Thread id
 
1520
    only_kill_query     Should it kill the query or the connection
 
1521
*/
 
1522
 
 
1523
void sql_kill(Session *session, ulong id, bool only_kill_query)
 
1524
{
 
1525
  uint32_t error;
 
1526
  if (!(error= kill_one_thread(session, id, only_kill_query)))
 
1527
    session->my_ok();
 
1528
  else
 
1529
    my_error(error, MYF(0), id);
 
1530
}
 
1531
 
 
1532
 
 
1533
/**
1452
1534
  Check if the select is a simple select (not an union).
1453
1535
 
1454
1536
  @retval
1457
1539
    1   error   ; In this case the error messege is sent to the client
1458
1540
*/
1459
1541
 
1460
 
bool check_simple_select(Session::pointer session)
 
1542
bool check_simple_select()
1461
1543
{
1462
 
  if (session->getLex()->current_select != &session->getLex()->select_lex)
 
1544
  Session *session= current_session;
 
1545
  LEX *lex= session->lex;
 
1546
  if (lex->current_select != &lex->select_lex)
1463
1547
  {
1464
1548
    char command[80];
1465
1549
    Lex_input_stream *lip= session->m_lip;
1519
1603
bool update_precheck(Session *session, TableList *)
1520
1604
{
1521
1605
  const char *msg= 0;
1522
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
 
1606
  LEX *lex= session->lex;
 
1607
  Select_Lex *select_lex= &lex->select_lex;
1523
1608
 
1524
 
  if (session->getLex()->select_lex.item_list.elements != session->getLex()->value_list.elements)
 
1609
  if (session->lex->select_lex.item_list.elements != session->lex->value_list.elements)
1525
1610
  {
1526
1611
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
1527
1612
    return(true);
1528
1613
  }
1529
1614
 
1530
 
  if (session->getLex()->select_lex.table_list.elements > 1)
 
1615
  if (session->lex->select_lex.table_list.elements > 1)
1531
1616
  {
1532
1617
    if (select_lex->order_list.elements)
1533
1618
      msg= "ORDER BY";
1557
1642
 
1558
1643
bool insert_precheck(Session *session, TableList *)
1559
1644
{
 
1645
  LEX *lex= session->lex;
 
1646
 
1560
1647
  /*
1561
1648
    Check that we have modify privileges for the first table and
1562
1649
    select privileges for the rest
1563
1650
  */
1564
 
  if (session->getLex()->update_list.elements != session->getLex()->value_list.elements)
 
1651
  if (lex->update_list.elements != lex->value_list.elements)
1565
1652
  {
1566
1653
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
1567
1654
    return(true);
1571
1658
 
1572
1659
 
1573
1660
/**
 
1661
  CREATE TABLE query pre-check.
 
1662
 
 
1663
  @param session                        Thread handler
 
1664
  @param tables         Global table list
 
1665
  @param create_table           Table which will be created
 
1666
 
 
1667
  @retval
 
1668
    false   OK
 
1669
  @retval
 
1670
    true   Error
 
1671
*/
 
1672
 
 
1673
bool create_table_precheck(TableIdentifier &identifier)
 
1674
{
 
1675
  if (strcmp(identifier.getDBName(), "information_schema") == 0)
 
1676
  {
 
1677
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
1678
    return true;
 
1679
  }
 
1680
 
 
1681
  return false;
 
1682
}
 
1683
 
 
1684
 
 
1685
/**
1574
1686
  negate given expression.
1575
1687
 
1576
1688
  @param session  thread handler
1588
1700
  {
1589
1701
    /* it is NOT(NOT( ... )) */
1590
1702
    Item *arg= ((Item_func *) expr)->arguments()[0];
1591
 
    enum_parsing_place place= session->getLex()->current_select->parsing_place;
 
1703
    enum_parsing_place place= session->lex->current_select->parsing_place;
1592
1704
    if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING)
1593
1705
      return arg;
1594
1706
    /*
1637
1749
}
1638
1750
 
1639
1751
 
1640
 
bool check_identifier_name(LEX_STRING *str, error_t err_code,
 
1752
bool check_identifier_name(LEX_STRING *str, uint32_t err_code,
1641
1753
                           uint32_t max_char_length,
1642
1754
                           const char *param_for_err_msg)
1643
1755
{
1663
1775
 
1664
1776
  switch (err_code)
1665
1777
  {
1666
 
  case EE_OK:
 
1778
  case 0:
1667
1779
    break;
1668
1780
  case ER_WRONG_STRING_LENGTH:
1669
1781
    my_error(err_code, MYF(0), str->str, param_for_err_msg, max_char_length);
1675
1787
    assert(0);
1676
1788
    break;
1677
1789
  }
1678
 
 
1679
1790
  return true;
1680
1791
}
1681
1792
 
1696
1807
{
1697
1808
  assert(session->m_lip == NULL);
1698
1809
 
1699
 
  DRIZZLE_QUERY_PARSE_START(session->getQueryString()->c_str());
 
1810
  DRIZZLE_QUERY_PARSE_START(session->query);
1700
1811
 
1701
1812
  /* Set Lex_input_stream. */
1702
1813
 
1704
1815
 
1705
1816
  /* Parse the query. */
1706
1817
 
1707
 
  bool parse_status= base_sql_parse(session) != 0;
 
1818
  bool mysql_parse_status= DRIZZLEparse(session) != 0;
1708
1819
 
1709
1820
  /* Check that if DRIZZLEparse() failed, session->is_error() is set. */
1710
1821
 
1711
 
  assert(!parse_status || session->is_error());
 
1822
  assert(!mysql_parse_status || session->is_error());
1712
1823
 
1713
1824
  /* Reset Lex_input_stream. */
1714
1825
 
1715
1826
  session->m_lip= NULL;
1716
1827
 
1717
 
  DRIZZLE_QUERY_PARSE_DONE(parse_status || session->is_fatal_error);
 
1828
  DRIZZLE_QUERY_PARSE_DONE(mysql_parse_status || session->is_fatal_error);
1718
1829
 
1719
1830
  /* That's it. */
1720
1831
 
1721
 
  return parse_status || session->is_fatal_error;
 
1832
  return mysql_parse_status || session->is_fatal_error;
1722
1833
}
1723
1834
 
1724
1835
/**