diff options
author | unknown <bell@sanja.is.com.ua> | 2004-02-12 22:33:30 +0200 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-02-12 22:33:30 +0200 |
commit | d476dceb96c61d1ff7207e1cfe089437970536b8 (patch) | |
tree | f9dfe2c5f49075a28cb5a924d652f04d203f60b9 /sql/sql_lex.cc | |
parent | 94c03b7199e6bed1845f27217ddec0aaaaf93c5b (diff) | |
parent | 0655f9c633c3b8fe390a87b1497314494d9b1287 (diff) | |
download | mariadb-git-d476dceb96c61d1ff7207e1cfe089437970536b8.tar.gz |
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/bk/work-limit-4.1
mysql-test/r/subselect.result:
Auto merged
mysql-test/t/subselect.test:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
sql/sql_lex.cc:
Auto merged
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r-- | sql/sql_lex.cc | 173 |
1 files changed, 129 insertions, 44 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index c6322b116ec..f10ddd89f35 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -181,6 +181,23 @@ static int find_keyword(LEX *lex, uint len, bool function) return 0; } +/* + Check if name is a keyword + + SYNOPSIS + is_keyword() + name checked name + len length of checked name + + RETURN VALUES + 0 name is a keyword + 1 name isn't a keyword +*/ + +bool is_keyword(const char *name, uint len) +{ + return get_hash_symbol(name,len,0)!=0; +} /* make a copy of token before ptr and set yytoklen */ @@ -193,6 +210,13 @@ static LEX_STRING get_token(LEX *lex,uint length) return tmp; } +/* + todo: + There are no dangerous charsets in mysql for function + get_quoted_token yet. But it should be fixed in the + future to operate multichar strings (like ucs2) +*/ + static LEX_STRING get_quoted_token(LEX *lex,uint length, char quote) { LEX_STRING tmp; @@ -420,7 +444,6 @@ inline static uint int_token(const char *str,uint length) return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger; } - /* yylex remember the following states from the following yylex() @@ -667,32 +690,17 @@ int yylex(void *arg, void *yythd) case MY_LEX_USER_VARIABLE_DELIMITER: { - char delim= c; // Used char + uint double_quotes= 0; + char quote_char= c; // Used char lex->tok_start=lex->ptr; // Skip first ` + while ((c=yyGet())) + { #ifdef USE_MB - if (use_mb(cs)) - { - while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR) - { - if (my_mbcharlen(cs, c) > 1) - { - int l; - if ((l = my_ismbchar(cs, - (const char *)lex->ptr-1, - (const char *)lex->end_of_query)) == 0) - break; - lex->ptr += l-1; - } - } - yylval->lex_str=get_token(lex,yyLength()); - } - else + if (my_mbcharlen(cs, c) == 1) #endif - { - uint double_quotes= 0; - char quote_char= c; - while ((c=yyGet())) { + if (c == (uchar) NAMES_SEP_CHAR) + break; /* Old .frm format can't handle this char */ if (c == quote_char) { if (yyPeek() != quote_char) @@ -701,16 +709,25 @@ int yylex(void *arg, void *yythd) double_quotes++; continue; } - if (c == (uchar) NAMES_SEP_CHAR) - break; } - if (double_quotes) - yylval->lex_str=get_quoted_token(lex,yyLength() - double_quotes, - quote_char); +#ifdef USE_MB else - yylval->lex_str=get_token(lex,yyLength()); + { + int l; + if ((l = my_ismbchar(cs, + (const char *)lex->ptr-1, + (const char *)lex->end_of_query)) == 0) + break; + lex->ptr += l-1; + } +#endif } - if (c == delim) + if (double_quotes) + yylval->lex_str=get_quoted_token(lex,yyLength() - double_quotes, + quote_char); + else + yylval->lex_str=get_token(lex,yyLength()); + if (c == quote_char) yySkip(); // Skip end ` lex->next_state= MY_LEX_START; return(IDENT_QUOTED); @@ -885,8 +902,13 @@ int yylex(void *arg, void *yythd) } /* fall true */ case MY_LEX_EOL: - lex->next_state=MY_LEX_END; // Mark for next loop - return(END_OF_INPUT); + if (lex->ptr >= lex->end_of_query) + { + lex->next_state=MY_LEX_END; // Mark for next loop + return(END_OF_INPUT); + } + state=MY_LEX_CHAR; + break; case MY_LEX_END: lex->next_state=MY_LEX_END; return(0); // We found end of input last time @@ -988,6 +1010,7 @@ void st_select_lex_unit::init_query() union_result= 0; table= 0; fake_select_lex= 0; + cleaned= 0; } void st_select_lex::init_query() @@ -1286,12 +1309,10 @@ bool st_select_lex::test_limit() !0 - error */ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex, - TABLE_LIST **result_arg, - bool check_derived) + TABLE_LIST **result_arg) { *result_arg= 0; - res= create_total_list_n_last_return(thd_arg, lex, &result_arg, - check_derived); + res= create_total_list_n_last_return(thd_arg, lex, &result_arg); return res; } @@ -1303,8 +1324,7 @@ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex, thd THD pointer lex pointer on LEX stricture result pointer on pointer on result list of tables pointer - check_derived force derived table chacking (used for creating - table list for derived query) + DESCRIPTION This is used for UNION & subselect to create a new table list of all used tables. @@ -1318,8 +1338,7 @@ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex, bool st_select_lex_unit:: create_total_list_n_last_return(THD *thd_arg, st_lex *lex, - TABLE_LIST ***result_arg, - bool check_derived) + TABLE_LIST ***result_arg) { TABLE_LIST *slave_list_first=0, **slave_list_last= &slave_list_first; TABLE_LIST **new_table_list= *result_arg, *aux; @@ -1345,15 +1364,12 @@ create_total_list_n_last_return(THD *thd_arg, return 1; } - if (sl->linkage == DERIVED_TABLE_TYPE && !check_derived) - goto end; - for (SELECT_LEX_UNIT *inner= sl->first_inner_unit(); inner; inner= inner->next_unit()) { if (inner->create_total_list_n_last_return(thd, lex, - &slave_list_last, 0)) + &slave_list_last)) return 1; } @@ -1400,63 +1416,75 @@ end: return 0; } + st_select_lex_unit* st_select_lex_unit::master_unit() { return this; } + st_select_lex* st_select_lex_unit::outer_select() { return (st_select_lex*) master; } + bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc) { return add_to_list(thd, order_list, item, asc); } + bool st_select_lex::add_item_to_list(THD *thd, Item *item) { return item_list.push_back(item); } + bool st_select_lex::add_group_to_list(THD *thd, Item *item, bool asc) { return add_to_list(thd, group_list, item, asc); } + bool st_select_lex::add_ftfunc_to_list(Item_func_match *func) { return !func || ftfunc_list->push_back(func); // end of memory? } + st_select_lex_unit* st_select_lex::master_unit() { return (st_select_lex_unit*) master; } + st_select_lex* st_select_lex::outer_select() { return (st_select_lex*) master->get_master(); } + bool st_select_lex::set_braces(bool value) { braces= value; return 0; } + bool st_select_lex::inc_in_sum_expr() { in_sum_expr++; return 0; } + uint st_select_lex::get_in_sum_expr() { return in_sum_expr; } + TABLE_LIST* st_select_lex::get_table_list() { return (TABLE_LIST*) table_list.first; @@ -1467,21 +1495,25 @@ List<Item>* st_select_lex::get_item_list() return &item_list; } + List<String>* st_select_lex::get_use_index() { return use_index_ptr; } + List<String>* st_select_lex::get_ignore_index() { return ignore_index_ptr; } + ulong st_select_lex::get_table_join_options() { return table_join_options; } + bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) { if (ref_pointer_array) @@ -1493,6 +1525,58 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) order_group_num)* 5)) == 0; } + +/* + Find db.table which will be updated in this unit + + SYNOPSIS + st_select_lex_unit::check_updateable() + db - data base name + table - real table name + + RETURN + 1 - found + 0 - OK (table did not found) +*/ +bool st_select_lex_unit::check_updateable(char *db, char *table) +{ + for(SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + if (sl->check_updateable(db, table)) + return 1; + return 0; +} + + +/* + Find db.table which will be updated in this select and + underlayed ones (except derived tables) + + SYNOPSIS + st_select_lex::check_updateable() + db - data base name + table - real table name + + RETURN + 1 - found + 0 - OK (table did not found) +*/ +bool st_select_lex::check_updateable(char *db, char *table) +{ + if (find_real_table_in_list(get_table_list(), db, table)) + return 1; + + for (SELECT_LEX_UNIT *un= first_inner_unit(); + un; + un= un->next_unit()) + { + if (un->first_select()->linkage != DERIVED_TABLE_TYPE && + un->check_updateable(db, table)) + return 1; + } + return 0; +} + + void st_select_lex_unit::print(String *str) { for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) @@ -1535,6 +1619,7 @@ void st_select_lex::print_order(String *str, ORDER *order) } } + void st_select_lex::print_limit(THD *thd, String *str) { if (!thd) |