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