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