~drizzle-trunk/drizzle/development

2096.1.14 by Brian Aker
Pull in more C code from parser.
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2010 Brian Aker
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 */
20
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
21
#include <config.h>
2207.8.4 by Olaf van der Spek
Refactor includes
22
#include <drizzled/session.h>
2096.1.14 by Brian Aker
Pull in more C code from parser.
23
#include <drizzled/parser.h>
2198.1.1 by Olaf van der Spek
Remove unnecessary alter* includes
24
#include <drizzled/alter_info.h>
25
#include <drizzled/alter_drop.h>
2198.1.2 by Olaf van der Spek
Refactor includes
26
#include <drizzled/item/subselect.h>
2234.1.4 by Olaf van der Spek
Refactor includes
27
#include <drizzled/sql_lex.h>
2096.1.14 by Brian Aker
Pull in more C code from parser.
28
2198.1.1 by Olaf van der Spek
Remove unnecessary alter* includes
29
namespace drizzled {
30
namespace parser {
2096.1.14 by Brian Aker
Pull in more C code from parser.
31
32
/**
33
  Helper to resolve the SQL:2003 Syntax exception 1) in <in predicate>.
34
  See SQL:2003, Part 2, section 8.4 <in predicate>, Note 184, page 383.
35
  This function returns the proper item for the SQL expression
36
  <code>left [NOT] IN ( expr )</code>
37
  @param session the current thread
38
  @param left the in predicand
39
  @param equal true for IN predicates, false for NOT IN predicates
40
  @param expr first and only expression of the in value list
41
  @return an expression representing the IN predicate.
42
*/
43
44
Item* handle_sql2003_note184_exception(Session *session, Item* left, bool equal, Item *expr)
45
{
46
  /*
47
    Relevant references for this issue:
48
    - SQL:2003, Part 2, section 8.4 <in predicate>, page 383,
49
    - SQL:2003, Part 2, section 7.2 <row value expression>, page 296,
50
    - SQL:2003, Part 2, section 6.3 <value expression primary>, page 174,
51
    - SQL:2003, Part 2, section 7.15 <subquery>, page 370,
52
    - SQL:2003 Feature F561, "Full value expressions".
53
54
    The exception in SQL:2003 Note 184 means:
55
    Item_singlerow_subselect, which corresponds to a <scalar subquery>,
56
    should be re-interpreted as an Item_in_subselect, which corresponds
57
    to a <table subquery> when used inside an <in predicate>.
58
59
    Our reading of Note 184 is reccursive, so that all:
60
    - IN (( <subquery> ))
61
    - IN ((( <subquery> )))
62
    - IN '('^N <subquery> ')'^N
63
    - etc
64
    should be interpreted as a <table subquery>, no matter how deep in the
65
    expression the <subquery> is.
66
  */
67
68
  Item *result;
69
70
  if (expr->type() == Item::SUBSELECT_ITEM)
71
  {
72
    Item_subselect *expr2 = (Item_subselect*) expr;
73
74
    if (expr2->substype() == Item_subselect::SINGLEROW_SUBS)
75
    {
76
      Item_singlerow_subselect *expr3 = (Item_singlerow_subselect*) expr2;
77
      Select_Lex *subselect;
78
79
      /*
80
        Implement the mandated change, by altering the semantic tree:
81
          left IN Item_singlerow_subselect(subselect)
82
        is modified to
83
          left IN (subselect)
84
        which is represented as
85
          Item_in_subselect(left, subselect)
86
      */
87
      subselect= expr3->invalidate_and_restore_select_lex();
88
      result= new (session->mem_root) Item_in_subselect(left, subselect);
89
90
      if (! equal)
91
        result = negate_expression(session, result);
92
93
      return(result);
94
    }
95
  }
96
97
  if (equal)
98
    result= new (session->mem_root) Item_func_eq(left, expr);
99
  else
100
    result= new (session->mem_root) Item_func_ne(left, expr);
101
102
  return(result);
103
}
104
105
/**
106
   @brief Creates a new Select_Lex for a UNION branch.
107
108
   Sets up and initializes a Select_Lex structure for a query once the parser
109
   discovers a UNION token. The current Select_Lex is pushed on the stack and
110
   the new Select_Lex becomes the current one..=
111
112
   @lex The parser state.
113
114
   @is_union_distinct True if the union preceding the new select statement
115
   uses UNION DISTINCT.
116
117
   @return <code>false</code> if successful, <code>true</code> if an error was
118
   reported. In the latter case parsing should stop.
119
 */
120
bool add_select_to_union_list(Session *session, LEX *lex, bool is_union_distinct)
121
{
122
  if (lex->result)
123
  {
124
    /* Only the last SELECT can have  INTO...... */
125
    my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
126
    return true;
127
  }
128
  if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
129
  {
2104.3.5 by Brian Aker
Fixed case where parser error message might be null.
130
    my_parse_error(session->m_lip);
2096.1.14 by Brian Aker
Pull in more C code from parser.
131
    return true;
132
  }
133
  /* This counter shouldn't be incremented for UNION parts */
134
  lex->nest_level--;
135
  if (new_select(lex, 0))
136
    return true;
137
  init_select(lex);
138
  lex->current_select->linkage=UNION_TYPE;
139
  if (is_union_distinct) /* UNION DISTINCT - remember position */
140
    lex->current_select->master_unit()->union_distinct=
141
      lex->current_select;
142
  return false;
143
}
144
145
/**
146
   @brief Initializes a Select_Lex for a query within parentheses (aka
147
   braces).
148
149
   @return false if successful, true if an error was reported. In the latter
150
   case parsing should stop.
151
 */
152
bool setup_select_in_parentheses(Session *session, LEX *lex)
153
{
154
  Select_Lex * sel= lex->current_select;
155
  if (sel->set_braces(1))
156
  {
2104.3.5 by Brian Aker
Fixed case where parser error message might be null.
157
    my_parse_error(session->m_lip);
2096.1.14 by Brian Aker
Pull in more C code from parser.
158
    return true;
159
  }
160
  if (sel->linkage == UNION_TYPE &&
161
      !sel->master_unit()->first_select()->braces &&
162
      sel->master_unit()->first_select()->linkage ==
163
      UNION_TYPE)
164
  {
2104.3.5 by Brian Aker
Fixed case where parser error message might be null.
165
    my_parse_error(session->m_lip);
2096.1.14 by Brian Aker
Pull in more C code from parser.
166
    return true;
167
  }
168
  if (sel->linkage == UNION_TYPE &&
169
      sel->olap != UNSPECIFIED_OLAP_TYPE &&
170
      sel->master_unit()->fake_select_lex)
171
  {
172
    my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY");
173
    return true;
174
  }
175
  /* select in braces, can't contain global parameters */
176
  if (sel->master_unit()->fake_select_lex)
177
    sel->master_unit()->global_parameters=
178
      sel->master_unit()->fake_select_lex;
179
  return false;
180
}
181
182
Item* reserved_keyword_function(Session *session, const std::string &name, List<Item> *item_list)
183
{
2198.6.15 by Brian Aker
Remove caller convert to std::string (ie we were going back and forth in
184
  const plugin::Function *udf= plugin::Function::get(name);
2096.1.14 by Brian Aker
Pull in more C code from parser.
185
186
  if (udf)
187
  {
2198.6.15 by Brian Aker
Remove caller convert to std::string (ie we were going back and forth in
188
    return Create_udf_func::s_singleton.create(session, udf, item_list);
2096.1.14 by Brian Aker
Pull in more C code from parser.
189
  }
190
2198.6.15 by Brian Aker
Remove caller convert to std::string (ie we were going back and forth in
191
  my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", name.c_str());
192
193
  return NULL;
2096.1.14 by Brian Aker
Pull in more C code from parser.
194
}
195
196
/**
197
  @brief Push an error message into MySQL error stack with line
198
  and position information.
199
200
  This function provides semantic action implementers with a way
201
  to push the famous "You have a syntax error near..." error
202
  message into the error stack, which is normally produced only if
203
  a parse error is discovered internally by the Bison generated
204
  parser.
205
*/
2104.3.5 by Brian Aker
Fixed case where parser error message might be null.
206
void my_parse_error(Lex_input_stream *lip)
2096.1.14 by Brian Aker
Pull in more C code from parser.
207
{
2104.3.5 by Brian Aker
Fixed case where parser error message might be null.
208
  assert(lip);
2096.1.14 by Brian Aker
Pull in more C code from parser.
209
210
  const char *yytext= lip->get_tok_start();
211
  /* Push an error into the error stack */
2104.3.5 by Brian Aker
Fixed case where parser error message might be null.
212
  my_printf_error(ER_PARSE_ERROR,  ER(ER_PARSE_ERROR), MYF(0), ER(ER_SYNTAX_ERROR),
2096.1.14 by Brian Aker
Pull in more C code from parser.
213
                  (yytext ? yytext : ""),
214
                  lip->yylineno);
215
}
216
2104.3.5 by Brian Aker
Fixed case where parser error message might be null.
217
void my_parse_error(const char *message)
218
{
219
  my_printf_error(ER_PARSE_ERROR_UNKNOWN, ER(ER_PARSE_ERROR_UNKNOWN), MYF(0), message);
220
}
221
2096.1.15 by Brian Aker
Additional parser cleanup.
222
bool check_reserved_words(LEX_STRING *name)
223
{
224
  if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") ||
225
      !my_strcasecmp(system_charset_info, name->str, "LOCAL") ||
226
      !my_strcasecmp(system_charset_info, name->str, "SESSION"))
227
    return true;
228
229
  return false;
230
}
231
232
2104.3.1 by Brian Aker
Merge in ulong typedef used.
233
/**
234
  @brief Bison callback to report a syntax/OOM error
235
236
  This function is invoked by the bison-generated parser
237
  when a syntax error, a parse error or an out-of-memory
238
  condition occurs. This function is not invoked when the
239
  parser is requested to abort by semantic action code
240
  by means of YYABORT or YYACCEPT macros. This is why these
241
  macros should not be used (use DRIZZLE_YYABORT/DRIZZLE_YYACCEPT
242
  instead).
243
244
  The parser will abort immediately after invoking this callback.
245
246
  This function is not for use in semantic actions and is internal to
247
  the parser, as it performs some pre-return cleanup.
248
  In semantic actions, please use parser::my_parse_error or my_error to
249
  push an error into the error stack and DRIZZLE_YYABORT
250
  to abort from the parser.
251
*/
2172.3.8 by Brian Aker
Modernize our call to the parser, no more casting required.
252
void errorOn(drizzled::Session *session, const char *s)
2104.3.1 by Brian Aker
Merge in ulong typedef used.
253
{
254
  /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */
255
  if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0)
2104.3.5 by Brian Aker
Fixed case where parser error message might be null.
256
  {
257
    parser::my_parse_error(session->m_lip);
258
  }
259
  else
260
  {
261
    parser::my_parse_error(s);
262
  }
2104.3.1 by Brian Aker
Merge in ulong typedef used.
263
}
264
2114.4.9 by Brian Aker
Try not to pass session quite as often
265
bool buildOrderBy(LEX *lex)
2104.3.4 by Brian Aker
Encapsulate from parser buildOrderBy()
266
{
2114.4.9 by Brian Aker
Try not to pass session quite as often
267
  Select_Lex *sel= lex->current_select;
2104.3.4 by Brian Aker
Encapsulate from parser buildOrderBy()
268
  Select_Lex_Unit *unit= sel-> master_unit();
269
270
  if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
271
      sel->olap != UNSPECIFIED_OLAP_TYPE &&
272
      (sel->linkage != UNION_TYPE || sel->braces))
273
  {
274
    my_error(ER_WRONG_USAGE, MYF(0),
275
             "CUBE/ROLLUP", "ORDER BY");
276
    return false;
277
  }
278
2114.4.9 by Brian Aker
Try not to pass session quite as often
279
  if (lex->sql_command != SQLCOM_ALTER_TABLE && !unit->fake_select_lex)
2104.3.4 by Brian Aker
Encapsulate from parser buildOrderBy()
280
  {
281
    /*
282
      A query of the of the form (SELECT ...) ORDER BY order_list is
283
      executed in the same way as the query
284
      SELECT ... ORDER BY order_list
285
      unless the SELECT construct contains ORDER BY or LIMIT clauses.
286
      Otherwise we create a fake Select_Lex if it has not been created
287
      yet.
288
    */
289
    Select_Lex *first_sl= unit->first_select();
290
    if (!unit->is_union() &&
291
        (first_sl->order_list.elements ||
292
         first_sl->select_limit) &&           
2114.4.9 by Brian Aker
Try not to pass session quite as often
293
        unit->add_fake_select_lex(lex->session))
2104.3.4 by Brian Aker
Encapsulate from parser buildOrderBy()
294
    {
295
      return false;
296
    }
297
  }
298
299
  return true;
300
}
2096.1.14 by Brian Aker
Pull in more C code from parser.
301
2114.4.9 by Brian Aker
Try not to pass session quite as often
302
void buildEngineOption(LEX *lex, const char *key, const LEX_STRING &value)
303
{
304
  message::Engine::Option *opt= lex->table()->mutable_engine()->add_options();
305
  opt->set_name(key);
306
  opt->set_state(value.str, value.length);
307
}
308
309
void buildEngineOption(LEX *lex, const char *key, uint64_t value)
310
{
311
  drizzled::message::Engine::Option *opt= lex->table()->mutable_engine()->add_options();
312
  opt->set_name(key);
313
  opt->set_state(boost::lexical_cast<std::string>(value));
314
}
315
316
void buildSchemaOption(LEX *lex, const char *key, const LEX_STRING &value)
317
{
318
  statement::CreateSchema *statement= (statement::CreateSchema *)lex->statement;
319
  message::Engine::Option *opt= statement->schema_message.mutable_engine()->add_options();
320
  opt->set_name(key);
321
  opt->set_state(value.str, value.length);
322
}
323
324
void buildSchemaOption(LEX *lex, const char *key, uint64_t value)
325
{
326
  statement::CreateSchema *statement= (statement::CreateSchema *)lex->statement;
327
  message::Engine::Option *opt= statement->schema_message.mutable_engine()->add_options();
328
  opt->set_name(key);
329
  opt->set_state(boost::lexical_cast<std::string>(value));
330
}
331
332
bool checkFieldIdent(LEX *lex, const LEX_STRING &schema_name, const LEX_STRING &table_name)
333
{
334
  TableList *table= reinterpret_cast<TableList*>(lex->current_select->table_list.first);
2114.4.4 by Brian Aker
Merge in field ident wrap from parser.
335
2114.4.6 by Brian Aker
Remove duplicate call by using null
336
  if (schema_name.length)
2114.4.4 by Brian Aker
Merge in field ident wrap from parser.
337
  {
2114.4.6 by Brian Aker
Remove duplicate call by using null
338
    if (my_strcasecmp(table_alias_charset, schema_name.str, table->getSchemaName()))
339
    {
340
      my_error(ER_WRONG_DB_NAME, MYF(0), schema_name.str);
341
      return false;
342
    }
2114.4.4 by Brian Aker
Merge in field ident wrap from parser.
343
  }
344
345
  if (my_strcasecmp(table_alias_charset, table_name.str,
346
                    table->getTableName()))
347
  {
348
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
349
    return false;
350
  }
351
352
  return true;
353
}
354
2114.4.9 by Brian Aker
Try not to pass session quite as often
355
Item *buildIdent(LEX *lex,
2114.4.5 by Brian Aker
Remove duplicate code around ident check.
356
                 const LEX_STRING &schema_name,
357
                 const LEX_STRING &table_name,
358
                 const LEX_STRING &field_name)
359
{
2114.4.9 by Brian Aker
Try not to pass session quite as often
360
  Select_Lex *sel= lex->current_select;
2114.4.5 by Brian Aker
Remove duplicate code around ident check.
361
2114.4.7 by Brian Aker
Pull simple_ident into method.
362
  if (table_name.length and sel->no_table_names_allowed)
2114.4.5 by Brian Aker
Remove duplicate code around ident check.
363
  {
364
    my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
2114.4.10 by Brian Aker
Remove current_session from a couple of locations, encapsulate where in
365
             MYF(0), table_name.str, lex->session->where());
2114.4.5 by Brian Aker
Remove duplicate code around ident check.
366
  }
367
368
  Item *item= (sel->parsing_place != IN_HAVING or
369
               sel->get_in_sum_expr() > 0) ?
2114.4.9 by Brian Aker
Try not to pass session quite as often
370
    (Item*) new Item_field(lex->current_context(), schema_name.str, table_name.str, field_name.str) :
371
    (Item*) new Item_ref(lex->current_context(), schema_name.str, table_name.str, field_name.str);
2114.4.5 by Brian Aker
Remove duplicate code around ident check.
372
373
  return item;
374
}
375
2114.4.9 by Brian Aker
Try not to pass session quite as often
376
Item *buildTableWild(LEX *lex, const LEX_STRING &schema_name, const LEX_STRING &table_name)
2114.4.8 by Brian Aker
Merge in additional parser encapsulation.
377
{
2114.4.9 by Brian Aker
Try not to pass session quite as often
378
  Select_Lex *sel= lex->current_select;
379
  Item *item= new Item_field(lex->current_context(), schema_name.str, table_name.str, "*");
2114.4.8 by Brian Aker
Merge in additional parser encapsulation.
380
  sel->with_wild++;
381
382
  return item;
383
}
384
2114.4.9 by Brian Aker
Try not to pass session quite as often
385
void buildCreateFieldIdent(LEX *lex)
386
{
387
  statement::CreateTable *statement= (statement::CreateTable *)lex->statement;
388
  lex->length= lex->dec=0;
389
  lex->type=0;
390
  statement->default_value= statement->on_update_value= 0;
391
  statement->comment= null_lex_str;
392
  lex->charset= NULL;
393
  statement->column_format= COLUMN_FORMAT_TYPE_DEFAULT;
394
395
  message::AlterTable &alter_proto= ((statement::CreateTable *)lex->statement)->alter_info.alter_proto;
396
  lex->setField(alter_proto.add_added_field());
397
}
398
2137.1.13 by Brian Aker
Fix bad error in warnings/errors.
399
void storeAlterColumnPosition(LEX *lex, const char *position)
400
{
401
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
402
403
  lex->last_field->after=const_cast<char*> (position);
404
  statement->alter_info.flags.set(ALTER_COLUMN_ORDER);
405
}
406
2148.5.4 by Brian Aker
Move over the collation test to a function outside of the parser.
407
bool buildCollation(LEX *lex, const CHARSET_INFO *arg)
408
{
409
  statement::CreateTable *statement= (statement::CreateTable *)lex->statement;
410
411
  HA_CREATE_INFO *cinfo= &statement->create_info();
412
  if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&
413
      cinfo->default_table_charset && arg &&
414
      !my_charset_same(cinfo->default_table_charset, arg))
415
  {
416
    my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
417
             arg->name, cinfo->default_table_charset->csname);
418
    return false;
419
  }
420
  statement->create_info().default_table_charset= arg;
421
  statement->create_info().used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
422
423
  return true;
424
}
425
2148.5.5 by Brian Aker
buildKey for parser.
426
void buildKey(LEX *lex, Key::Keytype type_par, const lex_string_t &name_arg)
427
{
428
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
429
  Key *key= new Key(type_par, name_arg, &statement->key_create_info, 0,
430
                    lex->col_list);
431
  statement->alter_info.key_list.push_back(key);
2179.2.1 by Olaf van der Spek
Rename List::empty to clear (std::list uses clear)
432
  lex->col_list.clear(); /* Alloced by memory::sql_alloc */
2148.5.5 by Brian Aker
buildKey for parser.
433
}
434
2148.5.6 by Brian Aker
Additional encapsulation.
435
void buildForeignKey(LEX *lex, const lex_string_t &name_arg, drizzled::Table_ident *table)
436
{
437
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
438
  Key *key= new Foreign_key(name_arg, lex->col_list,
439
                            table,
440
                            lex->ref_list,
441
                            statement->fk_delete_opt,
442
                            statement->fk_update_opt,
443
                            statement->fk_match_option);
444
445
  statement->alter_info.key_list.push_back(key);
446
  key= new Key(Key::MULTIPLE, name_arg,
447
               &default_key_create_info, 1,
448
               lex->col_list);
449
  statement->alter_info.key_list.push_back(key);
2179.2.1 by Olaf van der Spek
Rename List::empty to clear (std::list uses clear)
450
  lex->col_list.clear(); /* Alloced by memory::sql_alloc */
2148.5.6 by Brian Aker
Additional encapsulation.
451
  /* Only used for ALTER TABLE. Ignored otherwise. */
452
  statement->alter_info.flags.set(ALTER_FOREIGN_KEY);
453
}
454
2148.5.8 by Brian Aker
Move integer building into parser code file.
455
drizzled::enum_field_types buildIntegerColumn(LEX *lex, drizzled::enum_field_types final_type, const bool is_unsigned)
456
{ 
457
  lex->length=(char*) 0; /* use default length */
458
459
  if (is_unsigned)
460
  {
461
    final_type= DRIZZLE_TYPE_LONGLONG;
462
  }
463
464
  if (lex->field())
465
  {
466
    assert (final_type == DRIZZLE_TYPE_LONG or final_type == DRIZZLE_TYPE_LONGLONG);
467
    // We update the type for unsigned types
468
    if (is_unsigned)
469
    {
470
      lex->field()->set_type(message::Table::Field::BIGINT);
471
      lex->field()->mutable_constraints()->set_is_unsigned(true);
472
    }
473
    else if (final_type == DRIZZLE_TYPE_LONG)
474
    {
475
      lex->field()->set_type(message::Table::Field::INTEGER);
476
    }
477
    else if (final_type == DRIZZLE_TYPE_LONGLONG)
478
    {
479
      lex->field()->set_type(message::Table::Field::BIGINT);
480
    }
481
  }
482
483
  return final_type;
484
}
485
2148.5.9 by Brian Aker
Merge in column varchar build.
486
drizzled::enum_field_types buildSerialColumn(LEX *lex)
487
{
2148.5.15 by Brian Aker
Fix serial to be the same in the parser.
488
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
489
  statement->alter_info.flags.set(ALTER_ADD_INDEX);
490
2148.5.9 by Brian Aker
Merge in column varchar build.
491
  lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG | UNSIGNED_FLAG);
492
493
  if (lex->field())
494
  {
495
    lex->field()->mutable_constraints()->set_is_notnull(true);
496
    lex->field()->mutable_constraints()->set_is_unsigned(true);
497
498
    lex->field()->set_type(message::Table::Field::BIGINT);
499
  }
500
501
  return DRIZZLE_TYPE_LONGLONG;
502
}
503
504
drizzled::enum_field_types buildVarcharColumn(LEX *lex, const char *length)
505
{
506
  lex->length= const_cast<char *>(length);
507
508
  if (lex->field())
509
  {
510
    lex->field()->set_type(message::Table::Field::VARCHAR);
511
512
    message::Table::Field::StringFieldOptions *string_field_options;
513
514
    string_field_options= lex->field()->mutable_string_options();
515
516
    string_field_options->set_length(atoi(length));
517
  }
518
519
  return DRIZZLE_TYPE_VARCHAR;
520
}
521
2148.5.14 by Brian Aker
function for decimal to be pulled out of the parser.
522
drizzled::enum_field_types buildDecimalColumn(LEX *lex)
523
{
524
  if (lex->field())
525
    lex->field()->set_type(message::Table::Field::DECIMAL);
526
527
  return DRIZZLE_TYPE_DECIMAL;
528
}
529
2148.5.10 by Brian Aker
Merge in timestamp build parser function.
530
drizzled::enum_field_types buildVarbinaryColumn(LEX *lex, const char *length)
531
{
532
  lex->length= const_cast<char *>(length);
2148.5.11 by Brian Aker
Merge in varbinary build method.
533
  lex->charset= &my_charset_bin;
2148.5.10 by Brian Aker
Merge in timestamp build parser function.
534
535
  if (lex->field())
536
  {
537
    lex->field()->set_type(message::Table::Field::VARCHAR);
538
539
    message::Table::Field::StringFieldOptions *string_field_options;
540
541
    string_field_options= lex->field()->mutable_string_options();
542
543
    string_field_options->set_length(atoi(length));
544
    string_field_options->set_collation_id(my_charset_bin.number);
545
    string_field_options->set_collation(my_charset_bin.name);
546
  }
547
548
  return DRIZZLE_TYPE_VARCHAR;
549
}
550
551
drizzled::enum_field_types buildBlobColumn(LEX *lex)
552
{
553
  lex->charset=&my_charset_bin;
554
  lex->length=(char*) 0; /* use default length */
555
556
  if (lex->field())
557
  {
558
    lex->field()->set_type(message::Table::Field::BLOB);
559
    message::Table::Field::StringFieldOptions *string_field_options;
560
561
    string_field_options= lex->field()->mutable_string_options();
562
    string_field_options->set_collation_id(my_charset_bin.number);
563
    string_field_options->set_collation(my_charset_bin.name);
564
  }
565
566
  return DRIZZLE_TYPE_BLOB;
567
}
568
569
drizzled::enum_field_types buildBooleanColumn(LEX *lex)
570
{
571
  if (lex->field())
572
    lex->field()->set_type(message::Table::Field::BOOLEAN);
573
574
  return DRIZZLE_TYPE_BOOLEAN;
575
}
576
577
drizzled::enum_field_types buildUuidColumn(LEX *lex)
578
{
579
  if (lex->field())
580
    lex->field()->set_type(message::Table::Field::UUID);
581
582
  return DRIZZLE_TYPE_UUID;
583
}
584
585
drizzled::enum_field_types buildDoubleColumn(LEX *lex)
586
{
587
  if (lex->field())
588
  {
589
    lex->field()->set_type(message::Table::Field::DOUBLE);
590
  }
591
592
  return DRIZZLE_TYPE_DOUBLE;
593
}
594
595
drizzled::enum_field_types buildTimestampColumn(LEX *lex, const char *length)
596
{
597
  if (lex->field())
598
  {
599
    lex->field()->set_type(message::Table::Field::EPOCH);
600
  }
601
602
  if (length)
603
  {
604
    lex->length= const_cast<char *>(length);
605
    return DRIZZLE_TYPE_MICROTIME;
606
  }
607
608
  lex->length= NULL;
609
610
  return DRIZZLE_TYPE_TIMESTAMP;
611
}
612
2148.5.16 by Brian Aker
Adding build for unique column
613
void buildKeyOnColumn(LEX *lex)
614
{
615
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
616
617
  lex->type|= UNIQUE_KEY_FLAG;
618
  statement->alter_info.flags.set(ALTER_ADD_INDEX);
619
620
  if (lex->field())
621
  {
622
    lex->field()->mutable_constraints()->set_is_unique(true);
623
  }
624
}
625
2148.5.17 by Brian Aker
Merge up parser work for additional column builds.
626
void buildAutoOnColumn(LEX *lex)
627
{
628
  lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG;
629
630
  if (lex->field())
631
  {
632
    lex->field()->mutable_constraints()->set_is_notnull(true);
633
  }
634
}
635
636
void buildPrimaryOnColumn(LEX *lex)
637
{
638
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
639
640
  lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
641
  statement->alter_info.flags.set(ALTER_ADD_INDEX);
642
643
  if (lex->field())
644
  {
645
    lex->field()->mutable_constraints()->set_is_notnull(true);
646
  }
647
}
648
2172.3.3 by Brian Aker
Abstract out the replication set.
649
void buildReplicationOption(LEX *lex, bool arg)
650
{
651
  statement::CreateSchema *statement= (statement::CreateSchema *)lex->statement;
2187.7.6 by Brian Aker
This fixes the message such that the table inherits the no replication
652
  message::set_is_replicated(statement->schema_message, arg);
2172.3.3 by Brian Aker
Abstract out the replication set.
653
}
654
2172.3.4 by Brian Aker
Move out drop keys to parser method file.
655
void buildAddAlterDropIndex(LEX *lex, const char *name, bool is_foreign_key)
656
{
657
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
658
659
  statement->alter_info.flags.set(ALTER_DROP_INDEX);
660
  if (is_foreign_key)
661
  {
662
    statement->alter_info.flags.set(ALTER_FOREIGN_KEY);
2179.7.1 by Olaf van der Spek
x
663
    statement->alter_info.drop_list.push_back(AlterDrop(AlterDrop::FOREIGN_KEY, name));
2172.3.4 by Brian Aker
Move out drop keys to parser method file.
664
  }
665
  else
666
  {
2179.7.1 by Olaf van der Spek
x
667
    statement->alter_info.drop_list.push_back(AlterDrop(AlterDrop::KEY, name));
2172.3.4 by Brian Aker
Move out drop keys to parser method file.
668
  }
669
}
670
2096.1.14 by Brian Aker
Pull in more C code from parser.
671
} // namespace parser
672
} // namespace drizzled