diff options
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r-- | sql/sql_lex.cc | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 9ae5cdeeb15..dc9019de2c8 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -147,10 +147,11 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->select->in_sum_expr=0; lex->select->expr_list.empty(); lex->select->ftfunc_list.empty(); - lex->convert_set=(lex->thd=thd)->convert_set; + lex->convert_set=(lex->thd=thd)->variables.convert_set; lex->yacc_yyss=lex->yacc_yyvs=0; lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE); lex->slave_thd_opt=0; + lex->sql_command=SQLCOM_END; bzero(&lex->mi,sizeof(lex->mi)); return lex; } @@ -507,7 +508,7 @@ int yylex(void *arg) length= (uint) (lex->ptr - lex->tok_start)-1; if (lex->ignore_space) { - for ( ; state_map[c] == STATE_SKIP ; c= yyGet()); + for (; state_map[c] == STATE_SKIP ; c= yyGet()); } if (c == '.' && (state_map[yyPeek()] == STATE_IDENT || state_map[yyPeek()] == STATE_NUMBER_IDENT)) @@ -524,7 +525,7 @@ int yylex(void *arg) } yylval->lex_str=get_token(lex,length); if (lex->convert_set) - lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen); + lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen); /* Note: "SELECT _bla AS 'alias'" @@ -866,14 +867,12 @@ int yylex(void *arg) } break; case STATE_USER_END: // end '@' of user@hostname - switch (state_map[yyPeek()]) - { + switch (state_map[yyPeek()]) { case STATE_STRING: case STATE_USER_VARIABLE_DELIMITER: break; case STATE_USER_END: - lex->next_state=STATE_USER_END; - yySkip(); + lex->next_state=STATE_SYSTEM_VAR; break; default: lex->next_state=STATE_HOSTNAME; @@ -888,6 +887,33 @@ int yylex(void *arg) c= yyGet()) ; yylval->lex_str=get_token(lex,yyLength()); return(LEX_HOSTNAME); + case STATE_SYSTEM_VAR: + yylval->lex_str.str=(char*) lex->ptr; + yylval->lex_str.length=1; + lex->next_state=STATE_IDENT_OR_KEYWORD; + yySkip(); // Skip '@' + return((int) '@'); + case STATE_IDENT_OR_KEYWORD: + /* + We come here when we have found two '@' in a row. + We should now be able to handle: + [(global | local | session) .]variable_name + */ + + while (state_map[c=yyGet()] == STATE_IDENT || + state_map[c] == STATE_NUMBER_IDENT) ; + if (c == '.') + lex->next_state=STATE_IDENT_SEP; + length= (uint) (lex->ptr - lex->tok_start)-1; + if ((tokval= find_keyword(lex,length,0))) + { + yyUnget(); // Put back 'c' + return(tokval); // Was keyword + } + yylval->lex_str=get_token(lex,length); + if (lex->convert_set) + lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen); + return(IDENT); } } } |