summaryrefslogtreecommitdiff
path: root/sql/sql_lex.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r--sql/sql_lex.cc125
1 files changed, 96 insertions, 29 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index b0381ae1d30..58dc334b86e 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -130,6 +130,8 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->select_lex.expr_list.empty();
lex->select_lex.ftfunc_list_alloc.empty();
lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
+ lex->select_lex.group_list.empty();
+ lex->select_lex.order_list.empty();
lex->current_select= &lex->select_lex;
lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
@@ -687,13 +689,24 @@ 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 `
#ifdef USE_MB
if (use_mb(cs))
{
- while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR)
+ while ((c= yyGet()))
{
+ if (c == quote_char)
+ {
+ if (yyPeek() != quote_char)
+ break;
+ c= yyGet();
+ double_quotes++;
+ continue;
+ }
+ if (c == (uchar) NAMES_SEP_CHAR)
+ break;
if (my_mbcharlen(cs, c) > 1)
{
int l;
@@ -704,13 +717,10 @@ int yylex(void *arg, void *yythd)
lex->ptr += l-1;
}
}
- yylval->lex_str=get_token(lex,yyLength());
}
else
#endif
{
- uint double_quotes= 0;
- char quote_char= c;
while ((c=yyGet()))
{
if (c == quote_char)
@@ -724,13 +734,13 @@ int yylex(void *arg, void *yythd)
if (c == (uchar) NAMES_SEP_CHAR)
break;
}
- 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 == 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);
@@ -1008,6 +1018,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()
@@ -1197,7 +1208,6 @@ void st_select_lex_unit::exclude_level()
*/
void st_select_lex_unit::exclude_tree()
{
- SELECT_LEX_UNIT *units= 0;
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
{
// unlink current level from global SELECTs list
@@ -1244,11 +1254,6 @@ void st_select_lex::mark_as_dependent(SELECT_LEX *last)
s->uncacheable|= UNCACHEABLE_DEPENDENT;
SELECT_LEX_UNIT *munit= s->master_unit();
munit->uncacheable|= UNCACHEABLE_DEPENDENT;
- //Tables will be reopened many times
- for (TABLE_LIST *tbl= s->get_table_list();
- tbl;
- tbl= tbl->next)
- tbl->shared= 1;
}
}
@@ -1312,12 +1317,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;
}
@@ -1329,8 +1332,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.
@@ -1344,8 +1346,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;
@@ -1371,15 +1372,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;
}
@@ -1426,63 +1424,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;
@@ -1493,21 +1503,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)
@@ -1519,6 +1533,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())
@@ -1561,6 +1627,7 @@ void st_select_lex::print_order(String *str, ORDER *order)
}
}
+
void st_select_lex::print_limit(THD *thd, String *str)
{
if (!thd)