summaryrefslogtreecommitdiff
path: root/sql/sql_lex.cc
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-02-12 22:33:30 +0200
committerunknown <bell@sanja.is.com.ua>2004-02-12 22:33:30 +0200
commitd476dceb96c61d1ff7207e1cfe089437970536b8 (patch)
treef9dfe2c5f49075a28cb5a924d652f04d203f60b9 /sql/sql_lex.cc
parent94c03b7199e6bed1845f27217ddec0aaaaf93c5b (diff)
parent0655f9c633c3b8fe390a87b1497314494d9b1287 (diff)
downloadmariadb-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.cc173
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)