1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2010 Brian Aker
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.
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.
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
23
#include <drizzled/parser.h>
31
Helper to resolve the SQL:2003 Syntax exception 1) in <in predicate>.
32
See SQL:2003, Part 2, section 8.4 <in predicate>, Note 184, page 383.
33
This function returns the proper item for the SQL expression
34
<code>left [NOT] IN ( expr )</code>
35
@param session the current thread
36
@param left the in predicand
37
@param equal true for IN predicates, false for NOT IN predicates
38
@param expr first and only expression of the in value list
39
@return an expression representing the IN predicate.
42
Item* handle_sql2003_note184_exception(Session *session, Item* left, bool equal, Item *expr)
45
Relevant references for this issue:
46
- SQL:2003, Part 2, section 8.4 <in predicate>, page 383,
47
- SQL:2003, Part 2, section 7.2 <row value expression>, page 296,
48
- SQL:2003, Part 2, section 6.3 <value expression primary>, page 174,
49
- SQL:2003, Part 2, section 7.15 <subquery>, page 370,
50
- SQL:2003 Feature F561, "Full value expressions".
52
The exception in SQL:2003 Note 184 means:
53
Item_singlerow_subselect, which corresponds to a <scalar subquery>,
54
should be re-interpreted as an Item_in_subselect, which corresponds
55
to a <table subquery> when used inside an <in predicate>.
57
Our reading of Note 184 is reccursive, so that all:
59
- IN ((( <subquery> )))
60
- IN '('^N <subquery> ')'^N
62
should be interpreted as a <table subquery>, no matter how deep in the
63
expression the <subquery> is.
68
if (expr->type() == Item::SUBSELECT_ITEM)
70
Item_subselect *expr2 = (Item_subselect*) expr;
72
if (expr2->substype() == Item_subselect::SINGLEROW_SUBS)
74
Item_singlerow_subselect *expr3 = (Item_singlerow_subselect*) expr2;
75
Select_Lex *subselect;
78
Implement the mandated change, by altering the semantic tree:
79
left IN Item_singlerow_subselect(subselect)
82
which is represented as
83
Item_in_subselect(left, subselect)
85
subselect= expr3->invalidate_and_restore_select_lex();
86
result= new (session->mem_root) Item_in_subselect(left, subselect);
89
result = negate_expression(session, result);
96
result= new (session->mem_root) Item_func_eq(left, expr);
98
result= new (session->mem_root) Item_func_ne(left, expr);
104
@brief Creates a new Select_Lex for a UNION branch.
106
Sets up and initializes a Select_Lex structure for a query once the parser
107
discovers a UNION token. The current Select_Lex is pushed on the stack and
108
the new Select_Lex becomes the current one..=
110
@lex The parser state.
112
@is_union_distinct True if the union preceding the new select statement
115
@return <code>false</code> if successful, <code>true</code> if an error was
116
reported. In the latter case parsing should stop.
118
bool add_select_to_union_list(Session *session, LEX *lex, bool is_union_distinct)
122
/* Only the last SELECT can have INTO...... */
123
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
126
if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
128
my_parse_error(session->m_lip);
131
/* This counter shouldn't be incremented for UNION parts */
133
if (new_select(lex, 0))
136
lex->current_select->linkage=UNION_TYPE;
137
if (is_union_distinct) /* UNION DISTINCT - remember position */
138
lex->current_select->master_unit()->union_distinct=
144
@brief Initializes a Select_Lex for a query within parentheses (aka
147
@return false if successful, true if an error was reported. In the latter
148
case parsing should stop.
150
bool setup_select_in_parentheses(Session *session, LEX *lex)
152
Select_Lex * sel= lex->current_select;
153
if (sel->set_braces(1))
155
my_parse_error(session->m_lip);
158
if (sel->linkage == UNION_TYPE &&
159
!sel->master_unit()->first_select()->braces &&
160
sel->master_unit()->first_select()->linkage ==
163
my_parse_error(session->m_lip);
166
if (sel->linkage == UNION_TYPE &&
167
sel->olap != UNSPECIFIED_OLAP_TYPE &&
168
sel->master_unit()->fake_select_lex)
170
my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY");
173
/* select in braces, can't contain global parameters */
174
if (sel->master_unit()->fake_select_lex)
175
sel->master_unit()->global_parameters=
176
sel->master_unit()->fake_select_lex;
180
Item* reserved_keyword_function(Session *session, const std::string &name, List<Item> *item_list)
182
const plugin::Function *udf= plugin::Function::get(name.c_str(), name.length());
187
item= Create_udf_func::s_singleton.create(session, udf, item_list);
189
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", name.c_str());
196
@brief Push an error message into MySQL error stack with line
197
and position information.
199
This function provides semantic action implementers with a way
200
to push the famous "You have a syntax error near..." error
201
message into the error stack, which is normally produced only if
202
a parse error is discovered internally by the Bison generated
205
void my_parse_error(Lex_input_stream *lip)
209
const char *yytext= lip->get_tok_start();
210
/* Push an error into the error stack */
211
my_printf_error(ER_PARSE_ERROR, ER(ER_PARSE_ERROR), MYF(0), ER(ER_SYNTAX_ERROR),
212
(yytext ? yytext : ""),
216
void my_parse_error(const char *message)
218
my_printf_error(ER_PARSE_ERROR_UNKNOWN, ER(ER_PARSE_ERROR_UNKNOWN), MYF(0), message);
221
bool check_reserved_words(LEX_STRING *name)
223
if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") ||
224
!my_strcasecmp(system_charset_info, name->str, "LOCAL") ||
225
!my_strcasecmp(system_charset_info, name->str, "SESSION"))
233
@brief Bison callback to report a syntax/OOM error
235
This function is invoked by the bison-generated parser
236
when a syntax error, a parse error or an out-of-memory
237
condition occurs. This function is not invoked when the
238
parser is requested to abort by semantic action code
239
by means of YYABORT or YYACCEPT macros. This is why these
240
macros should not be used (use DRIZZLE_YYABORT/DRIZZLE_YYACCEPT
243
The parser will abort immediately after invoking this callback.
245
This function is not for use in semantic actions and is internal to
246
the parser, as it performs some pre-return cleanup.
247
In semantic actions, please use parser::my_parse_error or my_error to
248
push an error into the error stack and DRIZZLE_YYABORT
249
to abort from the parser.
251
void errorOn(const char *s)
253
Session *session= current_session;
255
/* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */
256
if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0)
258
parser::my_parse_error(session->m_lip);
262
parser::my_parse_error(s);
266
bool buildOrderBy(LEX *lex)
268
Select_Lex *sel= lex->current_select;
269
Select_Lex_Unit *unit= sel-> master_unit();
271
if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
272
sel->olap != UNSPECIFIED_OLAP_TYPE &&
273
(sel->linkage != UNION_TYPE || sel->braces))
275
my_error(ER_WRONG_USAGE, MYF(0),
276
"CUBE/ROLLUP", "ORDER BY");
280
if (lex->sql_command != SQLCOM_ALTER_TABLE && !unit->fake_select_lex)
283
A query of the of the form (SELECT ...) ORDER BY order_list is
284
executed in the same way as the query
285
SELECT ... ORDER BY order_list
286
unless the SELECT construct contains ORDER BY or LIMIT clauses.
287
Otherwise we create a fake Select_Lex if it has not been created
290
Select_Lex *first_sl= unit->first_select();
291
if (!unit->is_union() &&
292
(first_sl->order_list.elements ||
293
first_sl->select_limit) &&
294
unit->add_fake_select_lex(lex->session))
303
void buildEngineOption(LEX *lex, const char *key, const LEX_STRING &value)
305
message::Engine::Option *opt= lex->table()->mutable_engine()->add_options();
307
opt->set_state(value.str, value.length);
310
void buildEngineOption(LEX *lex, const char *key, uint64_t value)
312
drizzled::message::Engine::Option *opt= lex->table()->mutable_engine()->add_options();
314
opt->set_state(boost::lexical_cast<std::string>(value));
317
void buildSchemaOption(LEX *lex, const char *key, const LEX_STRING &value)
319
statement::CreateSchema *statement= (statement::CreateSchema *)lex->statement;
320
message::Engine::Option *opt= statement->schema_message.mutable_engine()->add_options();
322
opt->set_state(value.str, value.length);
325
void buildSchemaOption(LEX *lex, const char *key, uint64_t value)
327
statement::CreateSchema *statement= (statement::CreateSchema *)lex->statement;
328
message::Engine::Option *opt= statement->schema_message.mutable_engine()->add_options();
330
opt->set_state(boost::lexical_cast<std::string>(value));
333
bool checkFieldIdent(LEX *lex, const LEX_STRING &schema_name, const LEX_STRING &table_name)
335
TableList *table= reinterpret_cast<TableList*>(lex->current_select->table_list.first);
337
if (schema_name.length)
339
if (my_strcasecmp(table_alias_charset, schema_name.str, table->getSchemaName()))
341
my_error(ER_WRONG_DB_NAME, MYF(0), schema_name.str);
346
if (my_strcasecmp(table_alias_charset, table_name.str,
347
table->getTableName()))
349
my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
356
Item *buildIdent(LEX *lex,
357
const LEX_STRING &schema_name,
358
const LEX_STRING &table_name,
359
const LEX_STRING &field_name)
361
Select_Lex *sel= lex->current_select;
363
if (table_name.length and sel->no_table_names_allowed)
365
my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
366
MYF(0), table_name.str, lex->session->where());
369
Item *item= (sel->parsing_place != IN_HAVING or
370
sel->get_in_sum_expr() > 0) ?
371
(Item*) new Item_field(lex->current_context(), schema_name.str, table_name.str, field_name.str) :
372
(Item*) new Item_ref(lex->current_context(), schema_name.str, table_name.str, field_name.str);
377
Item *buildTableWild(LEX *lex, const LEX_STRING &schema_name, const LEX_STRING &table_name)
379
Select_Lex *sel= lex->current_select;
380
Item *item= new Item_field(lex->current_context(), schema_name.str, table_name.str, "*");
386
void buildCreateFieldIdent(LEX *lex)
388
statement::CreateTable *statement= (statement::CreateTable *)lex->statement;
389
lex->length= lex->dec=0;
391
statement->default_value= statement->on_update_value= 0;
392
statement->comment= null_lex_str;
394
statement->column_format= COLUMN_FORMAT_TYPE_DEFAULT;
396
message::AlterTable &alter_proto= ((statement::CreateTable *)lex->statement)->alter_info.alter_proto;
397
lex->setField(alter_proto.add_added_field());
400
void storeAlterColumnPosition(LEX *lex, const char *position)
402
statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
404
lex->last_field->after=const_cast<char*> (position);
405
statement->alter_info.flags.set(ALTER_COLUMN_ORDER);
408
bool buildCollation(LEX *lex, const CHARSET_INFO *arg)
410
statement::CreateTable *statement= (statement::CreateTable *)lex->statement;
412
HA_CREATE_INFO *cinfo= &statement->create_info();
413
if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&
414
cinfo->default_table_charset && arg &&
415
!my_charset_same(cinfo->default_table_charset, arg))
417
my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
418
arg->name, cinfo->default_table_charset->csname);
421
statement->create_info().default_table_charset= arg;
422
statement->create_info().used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
427
void buildKey(LEX *lex, Key::Keytype type_par, const lex_string_t &name_arg)
429
statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
430
Key *key= new Key(type_par, name_arg, &statement->key_create_info, 0,
432
statement->alter_info.key_list.push_back(key);
433
lex->col_list.empty(); /* Alloced by memory::sql_alloc */
436
void buildForeignKey(LEX *lex, const lex_string_t &name_arg, drizzled::Table_ident *table)
438
statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
439
Key *key= new Foreign_key(name_arg, lex->col_list,
442
statement->fk_delete_opt,
443
statement->fk_update_opt,
444
statement->fk_match_option);
446
statement->alter_info.key_list.push_back(key);
447
key= new Key(Key::MULTIPLE, name_arg,
448
&default_key_create_info, 1,
450
statement->alter_info.key_list.push_back(key);
451
lex->col_list.empty(); /* Alloced by memory::sql_alloc */
452
/* Only used for ALTER TABLE. Ignored otherwise. */
453
statement->alter_info.flags.set(ALTER_FOREIGN_KEY);
456
drizzled::enum_field_types buildIntegerColumn(LEX *lex, drizzled::enum_field_types final_type, const bool is_unsigned)
458
lex->length=(char*) 0; /* use default length */
462
final_type= DRIZZLE_TYPE_LONGLONG;
467
assert (final_type == DRIZZLE_TYPE_LONG or final_type == DRIZZLE_TYPE_LONGLONG);
468
// We update the type for unsigned types
471
lex->field()->set_type(message::Table::Field::BIGINT);
472
lex->field()->mutable_constraints()->set_is_unsigned(true);
474
else if (final_type == DRIZZLE_TYPE_LONG)
476
lex->field()->set_type(message::Table::Field::INTEGER);
478
else if (final_type == DRIZZLE_TYPE_LONGLONG)
480
lex->field()->set_type(message::Table::Field::BIGINT);
487
drizzled::enum_field_types buildSerialColumn(LEX *lex)
489
statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
490
statement->alter_info.flags.set(ALTER_ADD_INDEX);
492
lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG | UNSIGNED_FLAG);
496
lex->field()->mutable_constraints()->set_is_notnull(true);
497
lex->field()->mutable_constraints()->set_is_unsigned(true);
499
lex->field()->set_type(message::Table::Field::BIGINT);
502
return DRIZZLE_TYPE_LONGLONG;
505
drizzled::enum_field_types buildVarcharColumn(LEX *lex, const char *length)
507
lex->length= const_cast<char *>(length);
511
lex->field()->set_type(message::Table::Field::VARCHAR);
513
message::Table::Field::StringFieldOptions *string_field_options;
515
string_field_options= lex->field()->mutable_string_options();
517
string_field_options->set_length(atoi(length));
520
return DRIZZLE_TYPE_VARCHAR;
523
drizzled::enum_field_types buildDecimalColumn(LEX *lex)
526
lex->field()->set_type(message::Table::Field::DECIMAL);
528
return DRIZZLE_TYPE_DECIMAL;
531
drizzled::enum_field_types buildVarbinaryColumn(LEX *lex, const char *length)
533
lex->length= const_cast<char *>(length);
534
lex->charset= &my_charset_bin;
538
lex->field()->set_type(message::Table::Field::VARCHAR);
540
message::Table::Field::StringFieldOptions *string_field_options;
542
string_field_options= lex->field()->mutable_string_options();
544
string_field_options->set_length(atoi(length));
545
string_field_options->set_collation_id(my_charset_bin.number);
546
string_field_options->set_collation(my_charset_bin.name);
549
return DRIZZLE_TYPE_VARCHAR;
552
drizzled::enum_field_types buildBlobColumn(LEX *lex)
554
lex->charset=&my_charset_bin;
555
lex->length=(char*) 0; /* use default length */
559
lex->field()->set_type(message::Table::Field::BLOB);
560
message::Table::Field::StringFieldOptions *string_field_options;
562
string_field_options= lex->field()->mutable_string_options();
563
string_field_options->set_collation_id(my_charset_bin.number);
564
string_field_options->set_collation(my_charset_bin.name);
567
return DRIZZLE_TYPE_BLOB;
570
drizzled::enum_field_types buildBooleanColumn(LEX *lex)
573
lex->field()->set_type(message::Table::Field::BOOLEAN);
575
return DRIZZLE_TYPE_BOOLEAN;
578
drizzled::enum_field_types buildUuidColumn(LEX *lex)
581
lex->field()->set_type(message::Table::Field::UUID);
583
return DRIZZLE_TYPE_UUID;
586
drizzled::enum_field_types buildDoubleColumn(LEX *lex)
590
lex->field()->set_type(message::Table::Field::DOUBLE);
593
return DRIZZLE_TYPE_DOUBLE;
596
drizzled::enum_field_types buildTimestampColumn(LEX *lex, const char *length)
600
lex->field()->set_type(message::Table::Field::EPOCH);
605
lex->length= const_cast<char *>(length);
606
return DRIZZLE_TYPE_MICROTIME;
611
return DRIZZLE_TYPE_TIMESTAMP;
614
void buildKeyOnColumn(LEX *lex)
616
statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
618
lex->type|= UNIQUE_KEY_FLAG;
619
statement->alter_info.flags.set(ALTER_ADD_INDEX);
623
lex->field()->mutable_constraints()->set_is_unique(true);
627
void buildAutoOnColumn(LEX *lex)
629
lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG;
633
lex->field()->mutable_constraints()->set_is_notnull(true);
637
void buildPrimaryOnColumn(LEX *lex)
639
statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
641
lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
642
statement->alter_info.flags.set(ALTER_ADD_INDEX);
646
lex->field()->mutable_constraints()->set_is_notnull(true);
650
} // namespace parser
651
} // namespace drizzled