mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-19142 sql_mode=MSSQL: Bracket identifiers
This commit is contained in:
@ -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-
|
||||||
|
87
mysql-test/suite/compat/mssql/parser.result
Normal file
87
mysql-test/suite/compat/mssql/parser.result
Normal file
@ -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
|
||||||
|
#
|
68
mysql-test/suite/compat/mssql/parser.test
Normal file
68
mysql-test/suite/compat/mssql/parser.test
Normal file
@ -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 #
|
@ -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)
|
|||||||
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,
|
|||||||
|
|
||||||
|
|
||||||
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 @@ private:
|
|||||||
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. */
|
||||||
|
Reference in New Issue
Block a user