[tarantool-patches] Re: [PATCH] sql: add check for <WITH> absence in <CREATE VIEW>
Roman Khabibov
roman.habibov at tarantool.org
Wed Aug 28 15:17:41 MSK 2019
> On Aug 20, 2019, at 22:41, n.pettik <korablev at tarantool.org> wrote:
> You slightly misunderstood me. I proposed to allow such queries
> gracefully handling WITH statement and avoiding references
> counter incrementation for CTEs.
commit 202677704c455208d6def08d373776cfae82fdbe
Author: Roman Khabibov <roman.habibov at tarantool.org>
Date: Mon Jul 29 18:00:34 2019 +0300
sql: allow to create view as <WITH> clause
Allow views to use CTEs in <WITH> clauses, which can be in any
(nested) select after <AS>.
Closes #4149
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 92f1d5b22..d3d6770cf 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -1721,6 +1721,8 @@ update_view_references(struct Select *select, int update_value,
const char *space_name = sql_src_list_entry_name(list, i);
if (space_name == NULL)
continue;
+ if (is_cte(select, space_name) == true)
+ continue;
struct space *space = space_by_name(space_name);
if (space == NULL) {
if (! suppress_error) {
diff --git a/src/box/sql.h b/src/box/sql.h
index 9ccecf28c..c180e40e1 100644
--- a/src/box/sql.h
+++ b/src/box/sql.h
@@ -323,6 +323,17 @@ sql_select_delete(struct sql *db, struct Select *select);
struct SrcList *
sql_select_expand_from_tables(struct Select *select);
+/**
+ * Check if @a name matches with at least one of CTE names typed
+ * in <WITH> clauses within @a select.
+ *
+ * @param select Select to be checked.
+ * @retval true Has CTE with @a name.
+ * @retval false Hasn't CTE with @a name.
+*/
+bool
+is_cte(struct Select *select, const char *name);
+
/**
* Temporary getter in order to avoid including sqlInt.h
* in alter.cc.
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index c312f61f1..0ee840b89 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -332,6 +332,25 @@ sql_select_expand_from_tables(struct Select *select)
return walker.u.pSrcList;
}
+bool
+is_cte(struct Select *select, const char *name)
+{
+ assert(select != NULL && name != NULL);
+ struct With *with = select->pWith;
+ if (with != NULL) {
+ if (memcmp(name, with->a->zName, strlen(name)) == 0)
+ return true;
+ }
+ struct SrcList *list = select->pSrc;
+ int item_count = sql_src_list_entry_count(list);
+ for (int i = 0; i < item_count; ++i) {
+ if (list->a[i].pSelect != NULL)
+ if (is_cte(list->a[i].pSelect, name) == true)
+ return true;
+ }
+ return false;
+}
+
/*
* Given 1 to 3 identifiers preceding the JOIN keyword, determine the
* type of join. Return an integer constant that expresses that type
diff --git a/test/sql-tap/view.test.lua b/test/sql-tap/view.test.lua
index 101f4c3e7..4b695fa6a 100755
--- a/test/sql-tap/view.test.lua
+++ b/test/sql-tap/view.test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env tarantool
test = require("sqltester")
-test:plan(73)
+test:plan(80)
--!./tcltestrunner.lua
-- 2002 February 26
@@ -1233,4 +1233,99 @@ test:do_catchsql_test(
-- </view-23.8>
})
+-- gh-4149: Check error message for view creation with (nested)
+-- select with <WITH> clause.
+test:do_execsql_test(
+ "view-24.1",
+ [[
+ CREATE TABLE ts (s1 INT PRIMARY KEY);
+ INSERT INTO ts VALUES (1);
+ ]], {
+ -- <view-24.1>
+ -- </view-24.1>
+ })
+
+test:do_execsql_test(
+ "view-24.2",
+ [[
+ CREATE VIEW v AS WITH w(id) AS (
+ SELECT 1)
+ SELECT * FROM ts;
+ ]], {
+ -- <view-24.2>
+ -- </view-24.2>
+ })
+
+test:do_execsql_test(
+ "view-24.3",
+ [[
+ DROP VIEW v;
+ CREATE VIEW v AS WITH RECURSIVE w AS (
+ SELECT s1 FROM ts
+ UNION ALL
+ SELECT s1+1 FROM w WHERE s1 < 4)
+ SELECT * FROM w;
+ ]], {
+ -- <view-24.3>
+ -- </view-24.3>
+ })
+
+test:do_execsql_test(
+ "view-24.4",
+ [[
+ DROP VIEW v;
+ CREATE VIEW v AS SELECT * FROM (
+ WITH RECURSIVE w AS (
+ SELECT s1 FROM ts
+ UNION ALL
+ SELECT s1+1 FROM w WHERE s1 < 4)
+ SELECT * FROM w);
+ ]], {
+ -- <view-24.4>
+ -- </view-24.4>
+ })
+
+test:do_execsql_test(
+ "view-24.5",
+ [[
+ DROP VIEW v;
+ CREATE VIEW v AS SELECT * FROM (
+ SELECT * FROM (
+ WITH RECURSIVE w AS (
+ SELECT s1 FROM ts
+ UNION ALL
+ SELECT s1+1 FROM w WHERE s1 < 4)
+ SELECT * FROM w));
+ ]], {
+ -- <view-24.5>
+ -- </view-24.5>
+ })
+
+test:do_execsql_test(
+ "view-24.6",
+ [[
+ DROP VIEW v;
+ CREATE VIEW v AS SELECT * FROM
+ (SELECT 1),
+ (SELECT 2) JOIN
+ (WITH RECURSIVE w AS (
+ SELECT s1 FROM ts
+ UNION ALL
+ SELECT s1+1 FROM w WHERE s1 < 4)
+ SELECT * FROM w);
+ ]], {
+ -- <view-24.6>
+ -- </view-24.6>
+ })
+
+test:do_execsql_test(
+ "view-24.7",
+ [[
+ DROP VIEW v;
+ DROP TABLE ts;
+ ]], {
+ -- <view-24.7>
+ -- </view-24.7>
+ })
+
test:finish_test()
More information about the Tarantool-patches
mailing list