Commit c2a2e721 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-19142 sql_mode=MSSQL: Bracket identifiers

parent 3c352b59
...@@ -174,6 +174,7 @@ my @DEFAULT_SUITES= qw( ...@@ -174,6 +174,7 @@ my @DEFAULT_SUITES= qw(
binlog_encryption- binlog_encryption-
csv- csv-
compat/oracle- compat/oracle-
compat/mssql-
encryption- encryption-
federated- federated-
funcs_1- funcs_1-
......
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
#
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 #
...@@ -1504,6 +1504,8 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) ...@@ -1504,6 +1504,8 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
next_state= MY_LEX_START; next_state= MY_LEX_START;
return PERCENT_ORACLE_SYM; return PERCENT_ORACLE_SYM;
} }
if (c == '[' && (m_thd->variables.sql_mode & MODE_MSSQL))
return scan_ident_delimited(thd, &yylval->ident_cli, ']');
/* Fall through */ /* Fall through */
case MY_LEX_SKIP: // This should not happen case MY_LEX_SKIP: // This should not happen
if (c != ')') if (c != ')')
...@@ -1664,7 +1666,7 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) ...@@ -1664,7 +1666,7 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
return scan_ident_start(thd, &yylval->ident_cli); return scan_ident_start(thd, &yylval->ident_cli);
case MY_LEX_USER_VARIABLE_DELIMITER: // Found quote char 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 case MY_LEX_INT_OR_REAL: // Complete int or incomplete real
if (c != '.' || yyPeek() == '.') if (c != '.' || yyPeek() == '.')
...@@ -2236,11 +2238,12 @@ int Lex_input_stream::scan_ident_middle(THD *thd, Lex_ident_cli_st *str, ...@@ -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, 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(); CHARSET_INFO *const cs= thd->charset();
uint double_quotes= 0; uint double_quotes= 0;
uchar c, quote_char= m_tok_start[0]; uchar c;
DBUG_ASSERT(m_ptr == m_tok_start + 1); DBUG_ASSERT(m_ptr == m_tok_start + 1);
while ((c= yyGet())) while ((c= yyGet()))
......
...@@ -2678,7 +2678,7 @@ class Lex_input_stream ...@@ -2678,7 +2678,7 @@ class Lex_input_stream
int scan_ident_start(THD *thd, Lex_ident_cli_st *str); int scan_ident_start(THD *thd, Lex_ident_cli_st *str);
int scan_ident_middle(THD *thd, Lex_ident_cli_st *str, int scan_ident_middle(THD *thd, Lex_ident_cli_st *str,
CHARSET_INFO **cs, my_lex_states *); 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); bool get_7bit_or_8bit_ident(THD *thd, uchar *last_char);
/** Current thread. */ /** Current thread. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment