diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-04-03 15:40:45 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-04-15 09:39:28 +0400 |
commit | c2a2e72164d0056ca267f9f37ef1b061fa1520bf (patch) | |
tree | 39871096a466cde5ebc396b2b9be29e0d47fbc17 | |
parent | 3c352b59ebfca75ecb06105d98950e9804a413f6 (diff) | |
download | mariadb-git-c2a2e72164d0056ca267f9f37ef1b061fa1520bf.tar.gz |
MDEV-19142 sql_mode=MSSQL: Bracket identifiers
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 1 | ||||
-rw-r--r-- | mysql-test/suite/compat/mssql/parser.result | 87 | ||||
-rw-r--r-- | mysql-test/suite/compat/mssql/parser.test | 68 | ||||
-rw-r--r-- | sql/sql_lex.cc | 9 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 |
5 files changed, 163 insertions, 4 deletions
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 0df7f08db0a..24bf9b40109 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -174,6 +174,7 @@ my @DEFAULT_SUITES= qw( binlog_encryption- csv- compat/oracle- + compat/mssql- encryption- federated- funcs_1- diff --git a/mysql-test/suite/compat/mssql/parser.result b/mysql-test/suite/compat/mssql/parser.result new file mode 100644 index 00000000000..817439a826c --- /dev/null +++ b/mysql-test/suite/compat/mssql/parser.result @@ -0,0 +1,87 @@ +SET sql_mode=MSSQL; +# +# Start of 10.4 tests +# +# +# MDEV-19142 sql_mode=MSSQL: Bracket identifiers +# +SELECT 'test' AS [[]; +[ +test +SELECT 'test' AS []]]; +] +test +SELECT 'test' AS [[a]]]; +[a] +test +SELECT 'test' AS [\n]; +\n +test +CREATE TABLE [t 1] ([a b] INT); +SHOW CREATE TABLE [t 1]; +Table Create Table +t 1 CREATE TABLE "t 1" ( + "a b" int(11) DEFAULT NULL +) +INSERT INTO [t 1] VALUES (10); +SELECT [a b] FROM [t 1]; +a b +10 +SELECT [a b] [a b alias] FROM [t 1] [t 1 alias]; +a b alias +10 +SELECT [a b] FROM [test].[t 1]; +a b +10 +SELECT [a b], COUNT(*) FROM [t 1] GROUP BY [a b]; +a b COUNT(*) +10 1 +SELECT [a b], COUNT(*) FROM [t 1] GROUP BY [a b] HAVING [a b]>0; +a b COUNT(*) +10 1 +DROP TABLE [t 1]; +CREATE TABLE [t[1]]] (a INT); +SHOW CREATE TABLE [t[1]]]; +Table Create Table +t[1] CREATE TABLE "t[1]" ( + "a" int(11) DEFAULT NULL +) +DROP TABLE [t[1]]]; +CREATE TABLE [t 1] ([a b] INT); +CREATE VIEW [v 1] AS SELECT [a b] FROM [t 1]; +SHOW CREATE VIEW [v 1]; +View Create View character_set_client collation_connection +v 1 CREATE VIEW "v 1" AS select "t 1"."a b" AS "a b" from "t 1" latin1 latin1_swedish_ci +SELECT * FROM [v 1]; +a b +DROP VIEW [v 1]; +DROP TABLE [t 1]; +CREATE PROCEDURE [p 1]() +BEGIN +SELECT 'test' [a b]; +END; +$$ +SHOW CREATE PROCEDURE [p 1]; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +p 1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MSSQL,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS CREATE DEFINER="root"@"localhost" PROCEDURE "p 1"() +BEGIN +SELECT 'test' [a b]; +END latin1 latin1_swedish_ci latin1_swedish_ci +CALL [p 1]; +a b +test +DROP PROCEDURE [p 1]; +CREATE TABLE [t1] ([a] INT); +INSERT INTO t1 VALUES (10); +PREPARE [stmt] FROM 'SELECT [a] FROM [test].[t1]'; +EXECUTE [stmt]; +a +10 +DEALLOCATE PREPARE [stmt]; +EXECUTE IMMEDIATE 'SELECT [a] FROM [test].[t1]'; +a +10 +DROP TABLE [t1]; +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/compat/mssql/parser.test b/mysql-test/suite/compat/mssql/parser.test new file mode 100644 index 00000000000..59c6735c6c2 --- /dev/null +++ b/mysql-test/suite/compat/mssql/parser.test @@ -0,0 +1,68 @@ +SET sql_mode=MSSQL; + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-19142 sql_mode=MSSQL: Bracket identifiers +--echo # + +# Brackets inside bracket identifiers: +# - When we want a left bracket inside a bracket identifier, +# we just add a single left bracket: [ +# - When we want a right bracket inside a bracket identifier, +# we add two right brackets: ]] + + +SELECT 'test' AS [[]; +SELECT 'test' AS []]]; +SELECT 'test' AS [[a]]]; + +# Backslash has no special meaning +SELECT 'test' AS [\n]; + + +CREATE TABLE [t 1] ([a b] INT); +SHOW CREATE TABLE [t 1]; +INSERT INTO [t 1] VALUES (10); +SELECT [a b] FROM [t 1]; +SELECT [a b] [a b alias] FROM [t 1] [t 1 alias]; +SELECT [a b] FROM [test].[t 1]; +SELECT [a b], COUNT(*) FROM [t 1] GROUP BY [a b]; +SELECT [a b], COUNT(*) FROM [t 1] GROUP BY [a b] HAVING [a b]>0; +DROP TABLE [t 1]; + +CREATE TABLE [t[1]]] (a INT); +SHOW CREATE TABLE [t[1]]]; +DROP TABLE [t[1]]]; + +CREATE TABLE [t 1] ([a b] INT); +CREATE VIEW [v 1] AS SELECT [a b] FROM [t 1]; +SHOW CREATE VIEW [v 1]; +SELECT * FROM [v 1]; +DROP VIEW [v 1]; +DROP TABLE [t 1]; + +DELIMITER $$; +CREATE PROCEDURE [p 1]() +BEGIN + SELECT 'test' [a b]; +END; +$$ +DELIMITER ;$$ +SHOW CREATE PROCEDURE [p 1]; +CALL [p 1]; +DROP PROCEDURE [p 1]; + +CREATE TABLE [t1] ([a] INT); +INSERT INTO t1 VALUES (10); +PREPARE [stmt] FROM 'SELECT [a] FROM [test].[t1]'; +EXECUTE [stmt]; +DEALLOCATE PREPARE [stmt]; +EXECUTE IMMEDIATE 'SELECT [a] FROM [test].[t1]'; +DROP TABLE [t1]; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 3f28ab91b9a..f74541b34a4 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1504,6 +1504,8 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) next_state= MY_LEX_START; return PERCENT_ORACLE_SYM; } + if (c == '[' && (m_thd->variables.sql_mode & MODE_MSSQL)) + return scan_ident_delimited(thd, &yylval->ident_cli, ']'); /* Fall through */ case MY_LEX_SKIP: // This should not happen if (c != ')') @@ -1664,7 +1666,7 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) return scan_ident_start(thd, &yylval->ident_cli); case MY_LEX_USER_VARIABLE_DELIMITER: // Found quote char - return scan_ident_delimited(thd, &yylval->ident_cli); + return scan_ident_delimited(thd, &yylval->ident_cli, m_tok_start[0]); case MY_LEX_INT_OR_REAL: // Complete int or incomplete real if (c != '.' || yyPeek() == '.') @@ -2236,11 +2238,12 @@ int Lex_input_stream::scan_ident_middle(THD *thd, Lex_ident_cli_st *str, int Lex_input_stream::scan_ident_delimited(THD *thd, - Lex_ident_cli_st *str) + Lex_ident_cli_st *str, + uchar quote_char) { CHARSET_INFO *const cs= thd->charset(); uint double_quotes= 0; - uchar c, quote_char= m_tok_start[0]; + uchar c; DBUG_ASSERT(m_ptr == m_tok_start + 1); while ((c= yyGet())) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 3d314537822..4b23d87feb1 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2678,7 +2678,7 @@ private: int scan_ident_start(THD *thd, Lex_ident_cli_st *str); int scan_ident_middle(THD *thd, Lex_ident_cli_st *str, CHARSET_INFO **cs, my_lex_states *); - int scan_ident_delimited(THD *thd, Lex_ident_cli_st *str); + int scan_ident_delimited(THD *thd, Lex_ident_cli_st *str, uchar quote_char); bool get_7bit_or_8bit_ident(THD *thd, uchar *last_char); /** Current thread. */ |