diff --git a/changelogs/unreleased/fix-string-dequoting.md b/changelogs/unreleased/fix-string-dequoting.md new file mode 100644 index 0000000000000000000000000000000000000000..01f28ce41079edb19ff44fc93d15c26d07725e02 --- /dev/null +++ b/changelogs/unreleased/fix-string-dequoting.md @@ -0,0 +1,4 @@ +## bugfix/sql + +* SQL queries with sub-queries and quoted names now return correct column names +in projection (gh-7063). diff --git a/src/box/sql/util.c b/src/box/sql/util.c index c556b9815e71709782652c7228eb0c869f4dfd74..210cb5fb2dfba994fc2dd66a64844a7a23178e64 100644 --- a/src/box/sql/util.c +++ b/src/box/sql/util.c @@ -80,8 +80,8 @@ sqlStrlen30(const char *z) * input does not begin with a quote character, then this routine * is a no-op. * - * The input string must be zero-terminated. A new zero-terminator - * is added to the dequoted string. + * The input string must be zero-terminated. The resulting dequoted + * string will also be zero-terminated. * * The return value is -1 if no dequoting occurs or the length of the * dequoted string, exclusive of the zero terminator, if dequoting does @@ -102,19 +102,19 @@ sqlDequote(char *z) if (!sqlIsquote(quote)) return; for (i = 1, j = 0;; i++) { - assert(z[i]); if (z[i] == quote) { if (z[i + 1] == quote) { z[j++] = quote; i++; - } else { - break; } + } else if (z[i] == 0) { + z[j] = 0; + return; } else { z[j++] = z[i]; } + assert(z[i] != 0); } - z[j] = 0; } int diff --git a/test/sql-luatest/gh_7063_dequote_test.lua b/test/sql-luatest/gh_7063_dequote_test.lua new file mode 100644 index 0000000000000000000000000000000000000000..24750e9554e2b6362fefccf9b72e2e2f73564eed --- /dev/null +++ b/test/sql-luatest/gh_7063_dequote_test.lua @@ -0,0 +1,22 @@ +local server = require('test.luatest_helpers.server') +local t = require('luatest') +local g = t.group() + +g.before_all(function() + g.server = server:new({alias = 'dequote'}) + g.server:start() +end) + +g.after_all(function() + g.server:stop() +end) + +g.test_dequote = function() + g.server:exec(function() + local t = require('luatest') + box.execute([[CREATE TABLE "t"("a" INT PRIMARY KEY);]]) + local sql = [[SELECT "t1"."a" FROM (SELECT "a" FROM "t") AS "t1";]] + t.assert_equals(box.execute(sql).metadata[1].name, 't1.a') + box.execute([[DROP TABLE "t";]]) + end) +end