00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022 #include <drizzled/session.h>
00023 #include <drizzled/parser.h>
00024 #include <drizzled/alter_info.h>
00025 #include <drizzled/alter_drop.h>
00026 #include <drizzled/item/subselect.h>
00027 #include <drizzled/sql_lex.h>
00028
00029 namespace drizzled {
00030 namespace parser {
00031
00044 Item* handle_sql2003_note184_exception(Session *session, Item* left, bool equal, Item *expr)
00045 {
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 Item *result;
00069
00070 if (expr->type() == Item::SUBSELECT_ITEM)
00071 {
00072 Item_subselect *expr2 = (Item_subselect*) expr;
00073
00074 if (expr2->substype() == Item_subselect::SINGLEROW_SUBS)
00075 {
00076 Item_singlerow_subselect *expr3 = (Item_singlerow_subselect*) expr2;
00077 Select_Lex *subselect;
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 subselect= expr3->invalidate_and_restore_select_lex();
00088 result= new (session->mem_root) Item_in_subselect(left, subselect);
00089
00090 if (! equal)
00091 result = negate_expression(session, result);
00092
00093 return(result);
00094 }
00095 }
00096
00097 if (equal)
00098 result= new (session->mem_root) Item_func_eq(left, expr);
00099 else
00100 result= new (session->mem_root) Item_func_ne(left, expr);
00101
00102 return(result);
00103 }
00104
00120 bool add_select_to_union_list(Session *session, LEX *lex, bool is_union_distinct)
00121 {
00122 if (lex->result)
00123 {
00124
00125 my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
00126 return true;
00127 }
00128 if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
00129 {
00130 my_parse_error(session->m_lip);
00131 return true;
00132 }
00133
00134 lex->nest_level--;
00135 if (new_select(lex, 0))
00136 return true;
00137 init_select(lex);
00138 lex->current_select->linkage=UNION_TYPE;
00139 if (is_union_distinct)
00140 lex->current_select->master_unit()->union_distinct=
00141 lex->current_select;
00142 return false;
00143 }
00144
00152 bool setup_select_in_parentheses(Session *session, LEX *lex)
00153 {
00154 Select_Lex * sel= lex->current_select;
00155 if (sel->set_braces(1))
00156 {
00157 my_parse_error(session->m_lip);
00158 return true;
00159 }
00160 if (sel->linkage == UNION_TYPE &&
00161 !sel->master_unit()->first_select()->braces &&
00162 sel->master_unit()->first_select()->linkage ==
00163 UNION_TYPE)
00164 {
00165 my_parse_error(session->m_lip);
00166 return true;
00167 }
00168 if (sel->linkage == UNION_TYPE &&
00169 sel->olap != UNSPECIFIED_OLAP_TYPE &&
00170 sel->master_unit()->fake_select_lex)
00171 {
00172 my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY");
00173 return true;
00174 }
00175
00176 if (sel->master_unit()->fake_select_lex)
00177 sel->master_unit()->global_parameters=
00178 sel->master_unit()->fake_select_lex;
00179 return false;
00180 }
00181
00182 Item* reserved_keyword_function(Session *session, const std::string &name, List<Item> *item_list)
00183 {
00184 const plugin::Function *udf= plugin::Function::get(name);
00185
00186 if (udf)
00187 {
00188 return Create_udf_func::s_singleton.create(session, udf, item_list);
00189 }
00190
00191 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", name.c_str());
00192
00193 return NULL;
00194 }
00195
00206 void my_parse_error(Lex_input_stream *lip)
00207 {
00208 assert(lip);
00209
00210 const char *yytext= lip->get_tok_start();
00211
00212 my_printf_error(ER_PARSE_ERROR, ER(ER_PARSE_ERROR), MYF(0), ER(ER_SYNTAX_ERROR),
00213 (yytext ? yytext : ""),
00214 lip->yylineno);
00215 }
00216
00217 void my_parse_error(const char *message)
00218 {
00219 my_printf_error(ER_PARSE_ERROR_UNKNOWN, ER(ER_PARSE_ERROR_UNKNOWN), MYF(0), message);
00220 }
00221
00222 bool check_reserved_words(LEX_STRING *name)
00223 {
00224 if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") ||
00225 !my_strcasecmp(system_charset_info, name->str, "LOCAL") ||
00226 !my_strcasecmp(system_charset_info, name->str, "SESSION"))
00227 return true;
00228
00229 return false;
00230 }
00231
00232
00252 void errorOn(drizzled::Session *session, const char *s)
00253 {
00254
00255 if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0)
00256 {
00257 parser::my_parse_error(session->m_lip);
00258 }
00259 else
00260 {
00261 parser::my_parse_error(s);
00262 }
00263 }
00264
00265 bool buildOrderBy(LEX *lex)
00266 {
00267 Select_Lex *sel= lex->current_select;
00268 Select_Lex_Unit *unit= sel-> master_unit();
00269
00270 if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
00271 sel->olap != UNSPECIFIED_OLAP_TYPE &&
00272 (sel->linkage != UNION_TYPE || sel->braces))
00273 {
00274 my_error(ER_WRONG_USAGE, MYF(0),
00275 "CUBE/ROLLUP", "ORDER BY");
00276 return false;
00277 }
00278
00279 if (lex->sql_command != SQLCOM_ALTER_TABLE && !unit->fake_select_lex)
00280 {
00281
00282
00283
00284
00285
00286
00287
00288
00289 Select_Lex *first_sl= unit->first_select();
00290 if (!unit->is_union() &&
00291 (first_sl->order_list.elements ||
00292 first_sl->select_limit) &&
00293 unit->add_fake_select_lex(lex->session))
00294 {
00295 return false;
00296 }
00297 }
00298
00299 return true;
00300 }
00301
00302 void buildEngineOption(LEX *lex, const char *key, const LEX_STRING &value)
00303 {
00304 message::Engine::Option *opt= lex->table()->mutable_engine()->add_options();
00305 opt->set_name(key);
00306 opt->set_state(value.str, value.length);
00307 }
00308
00309 void buildEngineOption(LEX *lex, const char *key, uint64_t value)
00310 {
00311 drizzled::message::Engine::Option *opt= lex->table()->mutable_engine()->add_options();
00312 opt->set_name(key);
00313 opt->set_state(boost::lexical_cast<std::string>(value));
00314 }
00315
00316 void buildSchemaOption(LEX *lex, const char *key, const LEX_STRING &value)
00317 {
00318 statement::CreateSchema *statement= (statement::CreateSchema *)lex->statement;
00319 message::Engine::Option *opt= statement->schema_message.mutable_engine()->add_options();
00320 opt->set_name(key);
00321 opt->set_state(value.str, value.length);
00322 }
00323
00324 void buildSchemaOption(LEX *lex, const char *key, uint64_t value)
00325 {
00326 statement::CreateSchema *statement= (statement::CreateSchema *)lex->statement;
00327 message::Engine::Option *opt= statement->schema_message.mutable_engine()->add_options();
00328 opt->set_name(key);
00329 opt->set_state(boost::lexical_cast<std::string>(value));
00330 }
00331
00332 bool checkFieldIdent(LEX *lex, const LEX_STRING &schema_name, const LEX_STRING &table_name)
00333 {
00334 TableList *table= reinterpret_cast<TableList*>(lex->current_select->table_list.first);
00335
00336 if (schema_name.length)
00337 {
00338 if (my_strcasecmp(table_alias_charset, schema_name.str, table->getSchemaName()))
00339 {
00340 my_error(ER_WRONG_DB_NAME, MYF(0), schema_name.str);
00341 return false;
00342 }
00343 }
00344
00345 if (my_strcasecmp(table_alias_charset, table_name.str,
00346 table->getTableName()))
00347 {
00348 my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
00349 return false;
00350 }
00351
00352 return true;
00353 }
00354
00355 Item *buildIdent(LEX *lex,
00356 const LEX_STRING &schema_name,
00357 const LEX_STRING &table_name,
00358 const LEX_STRING &field_name)
00359 {
00360 Select_Lex *sel= lex->current_select;
00361
00362 if (table_name.length and sel->no_table_names_allowed)
00363 {
00364 my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
00365 MYF(0), table_name.str, lex->session->where());
00366 }
00367
00368 Item *item= (sel->parsing_place != IN_HAVING or
00369 sel->get_in_sum_expr() > 0) ?
00370 (Item*) new Item_field(lex->current_context(), schema_name.str, table_name.str, field_name.str) :
00371 (Item*) new Item_ref(lex->current_context(), schema_name.str, table_name.str, field_name.str);
00372
00373 return item;
00374 }
00375
00376 Item *buildTableWild(LEX *lex, const LEX_STRING &schema_name, const LEX_STRING &table_name)
00377 {
00378 Select_Lex *sel= lex->current_select;
00379 Item *item= new Item_field(lex->current_context(), schema_name.str, table_name.str, "*");
00380 sel->with_wild++;
00381
00382 return item;
00383 }
00384
00385 void buildCreateFieldIdent(LEX *lex)
00386 {
00387 statement::CreateTable *statement= (statement::CreateTable *)lex->statement;
00388 lex->length= lex->dec=0;
00389 lex->type=0;
00390 statement->default_value= statement->on_update_value= 0;
00391 statement->comment= null_lex_str;
00392 lex->charset= NULL;
00393 statement->column_format= COLUMN_FORMAT_TYPE_DEFAULT;
00394
00395 message::AlterTable &alter_proto= ((statement::CreateTable *)lex->statement)->alter_info.alter_proto;
00396 lex->setField(alter_proto.add_added_field());
00397 }
00398
00399 void storeAlterColumnPosition(LEX *lex, const char *position)
00400 {
00401 statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
00402
00403 lex->last_field->after=const_cast<char*> (position);
00404 statement->alter_info.flags.set(ALTER_COLUMN_ORDER);
00405 }
00406
00407 bool buildCollation(LEX *lex, const CHARSET_INFO *arg)
00408 {
00409 statement::CreateTable *statement= (statement::CreateTable *)lex->statement;
00410
00411 HA_CREATE_INFO *cinfo= &statement->create_info();
00412 if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&
00413 cinfo->default_table_charset && arg &&
00414 !my_charset_same(cinfo->default_table_charset, arg))
00415 {
00416 my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
00417 arg->name, cinfo->default_table_charset->csname);
00418 return false;
00419 }
00420 statement->create_info().default_table_charset= arg;
00421 statement->create_info().used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
00422
00423 return true;
00424 }
00425
00426 void buildKey(LEX *lex, Key::Keytype type_par, const lex_string_t &name_arg)
00427 {
00428 statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
00429 Key *key= new Key(type_par, name_arg, &statement->key_create_info, 0,
00430 lex->col_list);
00431 statement->alter_info.key_list.push_back(key);
00432 lex->col_list.clear();
00433 }
00434
00435 void buildForeignKey(LEX *lex, const lex_string_t &name_arg, drizzled::Table_ident *table)
00436 {
00437 statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
00438 Key *key= new Foreign_key(name_arg, lex->col_list,
00439 table,
00440 lex->ref_list,
00441 statement->fk_delete_opt,
00442 statement->fk_update_opt,
00443 statement->fk_match_option);
00444
00445 statement->alter_info.key_list.push_back(key);
00446 key= new Key(Key::MULTIPLE, name_arg,
00447 &default_key_create_info, 1,
00448 lex->col_list);
00449 statement->alter_info.key_list.push_back(key);
00450 lex->col_list.clear();
00451
00452 statement->alter_info.flags.set(ALTER_FOREIGN_KEY);
00453 }
00454
00455 drizzled::enum_field_types buildIntegerColumn(LEX *lex, drizzled::enum_field_types final_type, const bool is_unsigned)
00456 {
00457 lex->length=(char*) 0;
00458
00459 if (is_unsigned)
00460 {
00461 final_type= DRIZZLE_TYPE_LONGLONG;
00462 }
00463
00464 if (lex->field())
00465 {
00466 assert (final_type == DRIZZLE_TYPE_LONG or final_type == DRIZZLE_TYPE_LONGLONG);
00467
00468 if (is_unsigned)
00469 {
00470 lex->field()->set_type(message::Table::Field::BIGINT);
00471 lex->field()->mutable_constraints()->set_is_unsigned(true);
00472 }
00473 else if (final_type == DRIZZLE_TYPE_LONG)
00474 {
00475 lex->field()->set_type(message::Table::Field::INTEGER);
00476 }
00477 else if (final_type == DRIZZLE_TYPE_LONGLONG)
00478 {
00479 lex->field()->set_type(message::Table::Field::BIGINT);
00480 }
00481 }
00482
00483 return final_type;
00484 }
00485
00486 drizzled::enum_field_types buildSerialColumn(LEX *lex)
00487 {
00488 statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
00489 statement->alter_info.flags.set(ALTER_ADD_INDEX);
00490
00491 lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG | UNSIGNED_FLAG);
00492
00493 if (lex->field())
00494 {
00495 lex->field()->mutable_constraints()->set_is_notnull(true);
00496 lex->field()->mutable_constraints()->set_is_unsigned(true);
00497
00498 lex->field()->set_type(message::Table::Field::BIGINT);
00499 }
00500
00501 return DRIZZLE_TYPE_LONGLONG;
00502 }
00503
00504 drizzled::enum_field_types buildVarcharColumn(LEX *lex, const char *length)
00505 {
00506 lex->length= const_cast<char *>(length);
00507
00508 if (lex->field())
00509 {
00510 lex->field()->set_type(message::Table::Field::VARCHAR);
00511
00512 message::Table::Field::StringFieldOptions *string_field_options;
00513
00514 string_field_options= lex->field()->mutable_string_options();
00515
00516 string_field_options->set_length(atoi(length));
00517 }
00518
00519 return DRIZZLE_TYPE_VARCHAR;
00520 }
00521
00522 drizzled::enum_field_types buildDecimalColumn(LEX *lex)
00523 {
00524 if (lex->field())
00525 lex->field()->set_type(message::Table::Field::DECIMAL);
00526
00527 return DRIZZLE_TYPE_DECIMAL;
00528 }
00529
00530 drizzled::enum_field_types buildVarbinaryColumn(LEX *lex, const char *length)
00531 {
00532 lex->length= const_cast<char *>(length);
00533 lex->charset= &my_charset_bin;
00534
00535 if (lex->field())
00536 {
00537 lex->field()->set_type(message::Table::Field::VARCHAR);
00538
00539 message::Table::Field::StringFieldOptions *string_field_options;
00540
00541 string_field_options= lex->field()->mutable_string_options();
00542
00543 string_field_options->set_length(atoi(length));
00544 string_field_options->set_collation_id(my_charset_bin.number);
00545 string_field_options->set_collation(my_charset_bin.name);
00546 }
00547
00548 return DRIZZLE_TYPE_VARCHAR;
00549 }
00550
00551 drizzled::enum_field_types buildBlobColumn(LEX *lex)
00552 {
00553 lex->charset=&my_charset_bin;
00554 lex->length=(char*) 0;
00555
00556 if (lex->field())
00557 {
00558 lex->field()->set_type(message::Table::Field::BLOB);
00559 message::Table::Field::StringFieldOptions *string_field_options;
00560
00561 string_field_options= lex->field()->mutable_string_options();
00562 string_field_options->set_collation_id(my_charset_bin.number);
00563 string_field_options->set_collation(my_charset_bin.name);
00564 }
00565
00566 return DRIZZLE_TYPE_BLOB;
00567 }
00568
00569 drizzled::enum_field_types buildBooleanColumn(LEX *lex)
00570 {
00571 if (lex->field())
00572 lex->field()->set_type(message::Table::Field::BOOLEAN);
00573
00574 return DRIZZLE_TYPE_BOOLEAN;
00575 }
00576
00577 drizzled::enum_field_types buildUuidColumn(LEX *lex)
00578 {
00579 if (lex->field())
00580 lex->field()->set_type(message::Table::Field::UUID);
00581
00582 return DRIZZLE_TYPE_UUID;
00583 }
00584
00585 drizzled::enum_field_types buildDoubleColumn(LEX *lex)
00586 {
00587 if (lex->field())
00588 {
00589 lex->field()->set_type(message::Table::Field::DOUBLE);
00590 }
00591
00592 return DRIZZLE_TYPE_DOUBLE;
00593 }
00594
00595 drizzled::enum_field_types buildTimestampColumn(LEX *lex, const char *length)
00596 {
00597 if (lex->field())
00598 {
00599 lex->field()->set_type(message::Table::Field::EPOCH);
00600 }
00601
00602 if (length)
00603 {
00604 lex->length= const_cast<char *>(length);
00605 return DRIZZLE_TYPE_MICROTIME;
00606 }
00607
00608 lex->length= NULL;
00609
00610 return DRIZZLE_TYPE_TIMESTAMP;
00611 }
00612
00613 void buildKeyOnColumn(LEX *lex)
00614 {
00615 statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
00616
00617 lex->type|= UNIQUE_KEY_FLAG;
00618 statement->alter_info.flags.set(ALTER_ADD_INDEX);
00619
00620 if (lex->field())
00621 {
00622 lex->field()->mutable_constraints()->set_is_unique(true);
00623 }
00624 }
00625
00626 void buildAutoOnColumn(LEX *lex)
00627 {
00628 lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG;
00629
00630 if (lex->field())
00631 {
00632 lex->field()->mutable_constraints()->set_is_notnull(true);
00633 }
00634 }
00635
00636 void buildPrimaryOnColumn(LEX *lex)
00637 {
00638 statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
00639
00640 lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
00641 statement->alter_info.flags.set(ALTER_ADD_INDEX);
00642
00643 if (lex->field())
00644 {
00645 lex->field()->mutable_constraints()->set_is_notnull(true);
00646 }
00647 }
00648
00649 void buildReplicationOption(LEX *lex, bool arg)
00650 {
00651 statement::CreateSchema *statement= (statement::CreateSchema *)lex->statement;
00652 message::set_is_replicated(statement->schema_message, arg);
00653 }
00654
00655 void buildAddAlterDropIndex(LEX *lex, const char *name, bool is_foreign_key)
00656 {
00657 statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
00658
00659 statement->alter_info.flags.set(ALTER_DROP_INDEX);
00660 if (is_foreign_key)
00661 {
00662 statement->alter_info.flags.set(ALTER_FOREIGN_KEY);
00663 statement->alter_info.drop_list.push_back(AlterDrop(AlterDrop::FOREIGN_KEY, name));
00664 }
00665 else
00666 {
00667 statement->alter_info.drop_list.push_back(AlterDrop(AlterDrop::KEY, name));
00668 }
00669 }
00670
00671 }
00672 }