[patches] [PATCH v2] sql: disallow id duplicate in insert & update

AKhatskevich avkhatskevich at tarantool.org
Tue Feb 6 17:00:02 MSK 2018


-----------
Changes:
  Add similar check for update statement.
  Minor fixes.
-----------

Before this patch one was able to exec query like this:
  `insert into t(col1, col1) values(1, 1)`
  `update t set col1 = 1, col1 = 2;`
which is nonsense.

New policy is to throw an error in case of duplicates in columns
description.

The fix for insert compares each identifier with the others and therefore
has O(n^2) complexity. However, it seems that to maintain faster data
structure just for this small check is redundant.

The fix for update takes O(n), because it is implemented on initialized
array.

Closes #2358
---
 src/box/sql/insert.c          |  9 +++++++++
 src/box/sql/update.c          |  7 +++++++
 test/sql-tap/insert1.test.lua | 30 +++++++++++++++++++++++++++++-
 test/sql-tap/update.test.lua  | 23 ++++++++++++++++++++++-
 4 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index f4efbe02c..ed31557c2 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -508,6 +508,15 @@ sqlite3Insert(Parse * pParse,	/* Parser context */
 					goto insert_cleanup;
 				}
 			}
+			for(j = 0; j < i; j++) {
+				if (pColumn->a[j].idx != pColumn->a[i].idx)
+					continue;
+				sqlite3ErrorMsg(pParse,
+						"table id list: duplicate "
+							"column name %s",
+						pColumn->a[i].zName);
+				goto insert_cleanup;
+			}
 		}
 	}
 
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index a1fe097d7..328213711 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -247,6 +247,13 @@ sqlite3Update(Parse * pParse,		/* The parser context */
 					   0) {
 					chngPk = 1;
 				}
+				if (aXRef[j] != -1){
+					sqlite3ErrorMsg(pParse,
+							"set id list: duplicate"
+							" column name %s",
+							pChanges->a[i].zName);
+					goto update_cleanup;
+				}
 				aXRef[j] = i;
 				break;
 			}
diff --git a/test/sql-tap/insert1.test.lua b/test/sql-tap/insert1.test.lua
index 533241f5c..2409e5d8d 100755
--- a/test/sql-tap/insert1.test.lua
+++ b/test/sql-tap/insert1.test.lua
@@ -1,7 +1,7 @@
 #!/usr/bin/env tarantool
 test = require("sqltester")
 yaml = require('yaml')
-test:plan(24)
+test:plan(28)
 
 --!./tcltestrunner.lua
 -- 2001 September 15
@@ -516,5 +516,33 @@ test:do_execsql_test("insert-4.7", [[
 --   SELECT * FROM t12c;
 -- } {one xyzzy two}
 -- integrity_check insert-99.0
+
+
+test:do_execsql_test(
+    "insert-13.0",
+    [[
+        create table test(a primary key, b)
+    ]])
+
+test:do_catchsql_test(
+    "insert-13.1",
+    [[
+        insert into test(a, a, b) values(1, 1, 1)
+    ]],
+    {1, "table id list: duplicate column name A"})
+
+test:do_catchsql_test(
+    "insert-13.2",
+    [[
+        insert into test(a, b, b) values(1, 1, 1)
+    ]],
+    {1, "table id list: duplicate column name B"})
+
+test:do_execsql_test(
+    "insert-13.3",
+    [[
+        drop table test;
+    ]])
+
 test:finish_test()
 
diff --git a/test/sql-tap/update.test.lua b/test/sql-tap/update.test.lua
index 55ea0dad2..c5fbbea58 100755
--- a/test/sql-tap/update.test.lua
+++ b/test/sql-tap/update.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 test = require("sqltester")
-test:plan(108)
+test:plan(111)
 
 --!./tcltestrunner.lua
 -- 2001 September 15
@@ -1109,5 +1109,26 @@ test:do_catchsql_test("update-10.10", [[
 --   UPDATE t15 SET c=printf("y%d",a) WHERE c IS NULL;
 --   SELECT a,b,c,'|' FROM t15 ORDER BY a;
 -- } {5 zyx y5 | 10 abc y10 | 15 wvu y15 | 20 def y20 | 25 tsr y25 | 30 ghi y30 | 35 qpo y35 |}
+
+test:do_execsql_test(
+    "insert-15.0",
+    [[
+        create table test(a primary key);
+        insert into test(a) values(1);
+    ]])
+
+test:do_catchsql_test(
+    "insert-15.1",
+    [[
+        update test set a = 2, a = 3;
+    ]],
+    {1, "set id list: duplicate column name A"})
+
+test:do_execsql_test(
+  "insert-15.2",
+  [[
+      drop table test;
+  ]])
+
 test:finish_test()
 
-- 
2.14.1




More information about the Tarantool-patches mailing list