From c08f4bc0aabaaaadef40ffe2b2b36708d65d103b Mon Sep 17 00:00:00 2001
From: khatskevich <avkhatskevich@tarantool.org>
Date: Thu, 23 Nov 2017 16:32:59 +0300
Subject: [PATCH] sql: Apply identifier constraints to collations

  Make collation tokens obey ANSI ISO standard rules for identifiers.

Related to #2818
---
 src/box/sql/expr.c                    |  2 +-
 test/sql-tap/identifier_case.test.lua | 59 ++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index e4ffa65e16..f2bde12b69 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -134,7 +134,7 @@ sqlite3ExprAddCollateString(Parse * pParse, Expr * pExpr, const char *zC)
 	Token s;
 	assert(zC != 0);
 	sqlite3TokenInit(&s, (char *)zC);
-	return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 1);
+	return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
 }
 
 /*
diff --git a/test/sql-tap/identifier_case.test.lua b/test/sql-tap/identifier_case.test.lua
index 85b11d0c16..3f6dc07253 100755
--- a/test/sql-tap/identifier_case.test.lua
+++ b/test/sql-tap/identifier_case.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 test = require("sqltester")
-test:plan(51)
+test:plan(67)
 
 local test_prefix = "identifier_case-"
 
@@ -164,7 +164,7 @@ test:do_execsql_test(
 
 test:do_execsql_test(
     test_prefix.."4.1",
-    string.format([[select * from table1 order by a collate NOCASE]]),
+    string.format([[select * from table1 order by a collate "unicode_ci"]]),
     {}
 )
 
@@ -198,4 +198,59 @@ for _, row in ipairs(data) do
         row[3])
 end
 
+
+-- Check that collaiton names work as identifiers
+data = {
+    { 1,  [[ binary ]], {0}},
+    { 2,  [[ BINARY ]], {0}},
+    { 3,  [["binary"]], {0}},
+    { 4,  [["bInaRy"]], {0}},
+    { 5,  [["unicode"]], {0}},
+    { 6,  [[ unicode ]], {1,"no such collation sequence: UNICODE"}},
+    { 7,  [["UNICODE"]], {1,"no such collation sequence: UNICODE"}}
+}
+
+test:do_catchsql_test(
+    test_prefix.."6.0.",
+    [[
+        CREATE TABLE T1 (a primary key, b);
+    ]],
+    {0})
+
+for _, row in ipairs(data) do
+    test:do_catchsql_test(
+        test_prefix.."6.1."..row[1],
+        string.format( [[
+                CREATE INDEX I%s ON T1 (b COLLATE %s);
+                ]], row[1], row[2]),
+        row[3])
+end
+
+test:do_catchsql_test(
+    test_prefix.."6.2",
+    [[
+        DROP TABLE T1;
+    ]],
+    {0})
+
+data = {
+    { 1,  [[ 'a' < 'b' collate binary ]], {0, {1}}},
+    { 2,  [[ 'a' < 'b' collate "binary" ]], {0, {1}}},
+    { 3,  [[ 'a' < 'b' collate 'binary' ]], {1, [[near "'binary'": syntax error]]}},
+    { 4,  [[ 'a' < 'b' collate "unicode" ]], {0, {1}}},
+    { 5,  [[ 5 < 'b' collate "unicode" ]], {0, {1}}},
+    { 6,  [[ 5 < 'b' collate unicode ]], {1,"no such collation sequence: UNICODE"}},
+    { 7,  [[ 5 < 'b' collate "unicode_ci" ]], {0, {1}}},
+}
+
+for _, row in ipairs(data) do
+    test:do_catchsql_test(
+        test_prefix.."6.3."..row[1],
+        string.format( [[
+                SELECT %s;
+                ]], row[2]),
+        row[3])
+end
+
+
 test:finish_test()
-- 
GitLab