summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-04-03 15:40:45 +0400
committerAlexander Barkov <bar@mariadb.com>2019-04-15 09:39:28 +0400
commitc2a2e72164d0056ca267f9f37ef1b061fa1520bf (patch)
tree39871096a466cde5ebc396b2b9be29e0d47fbc17
parent3c352b59ebfca75ecb06105d98950e9804a413f6 (diff)
downloadmariadb-git-c2a2e72164d0056ca267f9f37ef1b061fa1520bf.tar.gz
MDEV-19142 sql_mode=MSSQL: Bracket identifiers
-rwxr-xr-xmysql-test/mysql-test-run.pl1
-rw-r--r--mysql-test/suite/compat/mssql/parser.result87
-rw-r--r--mysql-test/suite/compat/mssql/parser.test68
-rw-r--r--sql/sql_lex.cc9
-rw-r--r--sql/sql_lex.h2
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. */