diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result index 95ee8d6e99b39..0659bfa55ae22 100644 --- a/mysql-test/main/parser.result +++ b/mysql-test/main/parser.result @@ -2315,3 +2315,32 @@ nocopy # # End of 11.7 tests # +# +# MDEV-17677 : Keywords are parsed as identifiers when followed by a dot +# +: dot after SELECT +SELECT.1; +.1 +0.1 +SELECT .1; +.1 +0.1 +SELECT-.1; +-.1 +-0.1 +SELECT.abc; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT.abc' at line 1 +: expressions +SELECT.123+0; +.123+0 +0.123 +SELECT.5 * 2; +.5 * 2 +1.0 +: still work as identifier +CREATE TABLE `SELECT` (a INT); +INSERT INTO `SELECT` VALUES (5); +SELECT `SELECT`.a FROM `SELECT`; +a +5 +DROP TABLE `SELECT`; diff --git a/mysql-test/main/parser.test b/mysql-test/main/parser.test index 64df53342015d..6a47815059ccc 100644 --- a/mysql-test/main/parser.test +++ b/mysql-test/main/parser.test @@ -2114,3 +2114,24 @@ DELIMITER ;$$ --echo # --echo # End of 11.7 tests --echo # + +--echo # +--echo # MDEV-17677 : Keywords are parsed as identifiers when followed by a dot +--echo # + +--echo : dot after SELECT +SELECT.1; +SELECT .1; +SELECT-.1; +--error ER_PARSE_ERROR +SELECT.abc; + +--echo : expressions +SELECT.123+0; +SELECT.5 * 2; + +--echo : still work as identifier +CREATE TABLE `SELECT` (a INT); +INSERT INTO `SELECT` VALUES (5); +SELECT `SELECT`.a FROM `SELECT`; +DROP TABLE `SELECT`; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index b492dbe8411a2..95fb3c8ac3b30 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2899,16 +2899,26 @@ int Lex_input_stream::scan_ident_middle(THD *thd, Lex_ident_cli_st *str, yylineno++; } } + // here we check if the current token is a keyword followed by a dot and then digit + // if it's the case, we want to return it as keyword not identifier + int tokval= find_keyword(str, length, false); + if (tokval && c == '.' && my_isdigit(cs, yyPeek())) + { + yyUnget(); + return tokval; + } if (start == get_ptr() && c == '.' && ident_map[(uchar) yyPeek()]) + { next_state= MY_LEX_IDENT_SEP; + } else { // '(' must follow directly if function - int tokval; + int tokval2; yyUnget(); - if ((tokval= find_keyword(str, length, c == '('))) + if ((tokval2= find_keyword(str, length, c == '('))) { next_state= MY_LEX_START; // Allow signed numbers - return(tokval); // Was keyword + return(tokval2); // Was keyword } yySkip(); // next state does a unget }