From 69fc9e0bafd7c9c8c3faf5777635d86f8a134322 Mon Sep 17 00:00:00 2001 From: Mergen Imeev <imeevma@tarantool.org> Date: Tue, 10 Oct 2023 21:26:46 +0300 Subject: [PATCH] sql: second lookup for index names This patch add second lookup for index name in the following cases: - index in INDEXED BY clause; - index in DROP INDEX statement; - index in PRAGMA statement. Part of #4467 NO_DOC=will be added later NO_CHANGELOG=will be added later --- src/box/sql.c | 10 +++++++++- src/box/sql/build.c | 9 ++++++++- src/box/sql/expr.c | 2 ++ src/box/sql/sqlInt.h | 13 +++++++++---- ..._4467_sql_id_backwards_compatibility_test.lua | 16 ++++++++++++---- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/box/sql.c b/src/box/sql.c index 7918f8a05b..dc778a1c99 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -1663,6 +1663,11 @@ sql_index_id_by_token(const struct space *space, const struct Token *name) char *name_str = sql_name_from_token(name); uint32_t res = sql_space_index_id(space, name_str); sql_xfree(name_str); + if (res != UINT32_MAX || name->z[0] == '"') + return res; + char *old_name_str = sql_legacy_name_new(name->z, name->n); + res = sql_space_index_id(space, old_name_str); + sql_xfree(old_name_str); return res; } @@ -1670,7 +1675,10 @@ uint32_t sql_index_id_by_src(const struct SrcList_item *src) { assert(src->space != NULL && src->fg.isIndexedBy != 0); - return sql_space_index_id(src->space, src->u1.zIndexedBy); + uint32_t res = sql_space_index_id(src->space, src->u1.zIndexedBy); + if (res != UINT32_MAX || src->legacy_index_name == NULL) + return res; + return sql_space_index_id(src->space, src->legacy_index_name); } uint32_t diff --git a/src/box/sql/build.c b/src/box/sql/build.c index bd5de51a58..2b93b7bcc4 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -3055,8 +3055,10 @@ sqlSrcListDelete(struct SrcList *pList) sql_xfree(pItem->zName); sql_xfree(pItem->zAlias); sql_xfree(pItem->legacy_name); - if (pItem->fg.isIndexedBy) + if (pItem->fg.isIndexedBy) { sql_xfree(pItem->u1.zIndexedBy); + sql_xfree(pItem->legacy_index_name); + } if (pItem->fg.isTabFunc) sql_expr_list_delete(pItem->u1.pFuncArg); /* @@ -3132,6 +3134,11 @@ sqlSrcListIndexedBy(struct SrcList *p, struct Token *pIndexedBy) } else if (pIndexedBy->z != NULL) { pItem->u1.zIndexedBy = sql_name_from_token(pIndexedBy); pItem->fg.isIndexedBy = true; + if (pIndexedBy->z[0] != '"') { + pItem->legacy_index_name = + sql_legacy_name_new(pIndexedBy->z, + pIndexedBy->n); + } } } } diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index 604bf4a728..c174c70a60 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -1668,6 +1668,8 @@ sqlSrcListDup(struct SrcList *p, int flags) if (pNewItem->fg.isIndexedBy) { pNewItem->u1.zIndexedBy = sql_xstrdup(pOldItem->u1.zIndexedBy); + pNewItem->legacy_index_name = + sql_xstrdup(pOldItem->legacy_index_name); } pNewItem->pIBIndex = pOldItem->pIBIndex; if (pNewItem->fg.isTabFunc) { diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index 6def8ed319..babb716f81 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -1630,6 +1630,8 @@ struct SrcList { char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ ExprList *pFuncArg; /* Arguments to table-valued-function */ } u1; + /** Normalized index name for the second lookup. */ + char *legacy_index_name; struct index_def *pIBIndex; } a[1]; /* One entry for each identifier on the list */ }; @@ -3120,15 +3122,18 @@ uint32_t sql_space_fieldno(const struct space *space, const char *name); /** - * Return id of index with the name defined by the token. Return UINT32_MAX if - * the index was not found. + * Return id of index with the name defined by the token. A second lookup will + * be performed if the index is not found on the first try and token is not + * start with double quote. Return UINT32_MAX if the index was not found. */ uint32_t sql_index_id_by_token(const struct space *space, const struct Token *name); /** - * Return index with name defined by the element of struct SrcList. Return NULL - * if the index was not found. + * Return index with name defined by the element of struct SrcList. A second + * lookup will be performed if the index is not found on the first try and field + * legacy_index_name of the src is not NULL. Return NULL if the index was not + * found. */ uint32_t sql_index_id_by_src(const struct SrcList_item *src); diff --git a/test/sql-luatest/gh_4467_sql_id_backwards_compatibility_test.lua b/test/sql-luatest/gh_4467_sql_id_backwards_compatibility_test.lua index e2759e6462..e0135065c7 100644 --- a/test/sql-luatest/gh_4467_sql_id_backwards_compatibility_test.lua +++ b/test/sql-luatest/gh_4467_sql_id_backwards_compatibility_test.lua @@ -274,6 +274,13 @@ g.test_indexed_by = function() local _, err = box.execute([[SELECT * FROM Tab INDEXED BY Four;]]) t.assert(err == nil); box.space.Tab:drop() + + -- Make sure index name is looked up twice in INDEXED BY clause. + box.execute([[CREATE TABLE ASD(QWE INT PRIMARY KEY, ZXC INT, + CONSTRAINT RTY UNIQUE (qwe, zxc));]]) + _, err = box.execute([[SELECT * FROM asd INDEXED BY rty;]]) + t.assert(err == nil); + box.space.ASD:drop() end) end @@ -390,11 +397,12 @@ g.test_drop_index = function() t.assert(box.space.Tab.index.In1 == nil) box.space.Tab:drop() - -- Make sure table name is looked up twice in DROP INDEX. + -- Make sure table name and index name are looked up twice in + -- DROP INDEX. box.execute([[CREATE TABLE ASD(PK INT PRIMARY KEY, QWE INT, ZXC INT);]]) box.execute([[CREATE INDEX IND ON aSd(ZXC, QWE);]]) t.assert(box.space.ASD.index.IND ~= nil) - sql = [[DROP INDEX IND ON asD;]] + sql = [[DROP INDEX iNd ON asD;]] t.assert_equals(box.execute(sql), {row_count = 1}) t.assert(box.space.ASD.index.IND == nil) box.space.ASD:drop() @@ -411,12 +419,12 @@ g.test_pragma = function() t.assert_equals(box.execute([[PRAGMA index_info(Tab.In1);]]).rows, exp) box.space.Tab:drop() - -- Make sure table name is looked up twice in PRAGMA. + -- Make sure table name and index name are looked up twice in PRAGMA. box.execute([[CREATE TABLE ASD(PK INT PRIMARY KEY, QWE INT, ZXC INT);]]) box.execute([[CREATE INDEX IND ON asD(ZXC, QWE);]]) local exp = {{0, 2, 'ZXC', 0, 'BINARY', 'integer'}, {1, 1, 'QWE', 0, 'BINARY', 'integer'}} - t.assert_equals(box.execute([[PRAGMA index_info(aSD.IND);]]).rows, exp) + t.assert_equals(box.execute([[PRAGMA index_info(aSD.inD);]]).rows, exp) box.space.ASD:drop() end) end -- GitLab