[Tarantool-patches] [PATCH 6/6] sql: extend result set with alias

Nikita Pettik korablev at tarantool.org
Wed Nov 27 15:15:46 MSK 2019


Each column of result set can feature its name alias. For instance:

SELECT x + 1 AS add FROM ...;

In this case real name of resulting set column is "x + 1" meanwhile
"add" is its alias. This patch extends metadata with optional metadata
member which corresponds to column's alias.

Closes #4407
---
 src/box/execute.c              | 18 +++++++++++++----
 src/box/iproto_constants.h     |  1 +
 src/box/lua/execute.c          |  5 +++++
 src/box/lua/net_box.c          |  6 +++++-
 src/box/sql/select.c           |  9 +++++++--
 src/box/sql/sqlInt.h           |  3 +++
 src/box/sql/vdbe.h             |  3 +++
 src/box/sql/vdbeInt.h          |  1 +
 src/box/sql/vdbeapi.c          |  8 ++++++++
 src/box/sql/vdbeaux.c          | 15 ++++++++++++++
 test/sql-tap/badutf1.test.lua  | 46 +++++++++++++++++++++---------------------
 test/sql-tap/colname.test.lua  | 16 +++++++--------
 test/sql-tap/lua/sqltester.lua | 29 ++++++++++++++++++++++++++
 test/sql-tap/select1.test.lua  | 18 ++++++++---------
 test/sql-tap/select4.test.lua  |  4 ++--
 test/sql-tap/view.test.lua     |  2 +-
 test/sql/bind.result           | 15 ++++++++------
 test/sql/boolean.result        |  6 ++++--
 test/sql/collation.result      | 16 +++++++++------
 test/sql/iproto.result         |  5 +++--
 20 files changed, 160 insertions(+), 66 deletions(-)

diff --git a/src/box/execute.c b/src/box/execute.c
index 8305f6f3b..967a7a0bf 100644
--- a/src/box/execute.c
+++ b/src/box/execute.c
@@ -270,7 +270,7 @@ error:
 
 static size_t
 metadata_map_sizeof(const char *name, const char *type, const char *coll,
-		    int nullable, bool is_autoincrement)
+		    const char *alias, int nullable, bool is_autoincrement)
 {
 	uint32_t members_count = 2;
 	size_t map_size = 0;
@@ -279,6 +279,11 @@ metadata_map_sizeof(const char *name, const char *type, const char *coll,
 		map_size += mp_sizeof_uint(IPROTO_FIELD_COLL);
 		map_size += mp_sizeof_str(strlen(coll));
 	}
+	if (alias != NULL) {
+		members_count++;
+		map_size += mp_sizeof_uint(IPROTO_FIELD_ALIAS);
+		map_size += mp_sizeof_str(strlen(alias));
+	}
 	if (nullable != -1) {
 		members_count++;
 		map_size += mp_sizeof_uint(IPROTO_FIELD_NULLABLE);
@@ -323,6 +328,7 @@ sql_get_metadata(struct sql_stmt *stmt, struct obuf *out, int column_count)
 		const char *coll = sql_column_coll(stmt, i);
 		const char *name = sql_column_name(stmt, i);
 		const char *type = sql_column_datatype(stmt, i);
+		const char *alias = sql_column_alias(stmt, i);
 		int nullable = sql_column_is_nullable(stmt, i);
 		bool is_autoincrement = sql_column_is_autoincrement(stmt, i);
 		/*
@@ -332,15 +338,15 @@ sql_get_metadata(struct sql_stmt *stmt, struct obuf *out, int column_count)
 		 */
 		assert(name != NULL);
 		assert(type != NULL);
-		size = metadata_map_sizeof(name, type, coll, nullable,
+		size = metadata_map_sizeof(name, type, coll, alias, nullable,
 					   is_autoincrement);
 		char *pos = (char *) obuf_alloc(out, size);
 		if (pos == NULL) {
 			diag_set(OutOfMemory, size, "obuf_alloc", "pos");
 			return -1;
 		}
-		uint32_t map_sz = 2 + (coll != NULL) + (nullable != -1) +
-				  is_autoincrement;
+		uint32_t map_sz = 2 + (coll != NULL) + (alias != NULL) +
+				  (nullable != -1) + is_autoincrement;
 		pos = mp_encode_map(pos, map_sz);
 		pos = mp_encode_uint(pos, IPROTO_FIELD_NAME);
 		pos = mp_encode_str(pos, name, strlen(name));
@@ -350,6 +356,10 @@ sql_get_metadata(struct sql_stmt *stmt, struct obuf *out, int column_count)
 			pos = mp_encode_uint(pos, IPROTO_FIELD_COLL);
 			pos = mp_encode_str(pos, coll, strlen(coll));
 		}
+		if (alias != NULL) {
+			pos = mp_encode_uint(pos, IPROTO_FIELD_ALIAS);
+			pos = mp_encode_str(pos, alias, strlen(alias));
+		}
 		if (nullable != -1) {
 			pos = mp_encode_uint(pos, IPROTO_FIELD_NULLABLE);
 			pos = mp_encode_bool(pos, nullable);
diff --git a/src/box/iproto_constants.h b/src/box/iproto_constants.h
index 4d43583b0..c5d053dc4 100644
--- a/src/box/iproto_constants.h
+++ b/src/box/iproto_constants.h
@@ -134,6 +134,7 @@ enum iproto_metadata_key {
 	IPROTO_FIELD_COLL = 2,
 	IPROTO_FIELD_NULLABLE = 3,
 	IPROTO_FIELD_AUTOINCREMENT = 4,
+	IPROTO_FIELD_ALIAS = 5,
 };
 
 enum iproto_ballot_key {
diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c
index d7dd9432f..099d3855a 100644
--- a/src/box/lua/execute.c
+++ b/src/box/lua/execute.c
@@ -24,6 +24,7 @@ lua_sql_get_metadata(struct sql_stmt *stmt, struct lua_State *L,
 		lua_createtable(L, 0, coll != NULL ? 3 : 2);
 		const char *name = sql_column_name(stmt, i);
 		const char *type = sql_column_datatype(stmt, i);
+		const char *alias = sql_column_alias(stmt, i);
 		int nullable = sql_column_is_nullable(stmt, i);
 		bool is_autoincrement = sql_column_is_autoincrement(stmt, i);
 		/*
@@ -41,6 +42,10 @@ lua_sql_get_metadata(struct sql_stmt *stmt, struct lua_State *L,
 			lua_pushstring(L, coll);
 			lua_setfield(L, -2, "collation");
 		}
+		if (alias != NULL) {
+			lua_pushstring(L, alias);
+			lua_setfield(L, -2, "alias");
+		}
 		if (nullable != -1) {
 			lua_pushboolean(L, nullable);
 			lua_setfield(L, -2, "is_nullable");
diff --git a/src/box/lua/net_box.c b/src/box/lua/net_box.c
index 3be644785..dce956932 100644
--- a/src/box/lua/net_box.c
+++ b/src/box/lua/net_box.c
@@ -655,6 +655,10 @@ decode_metadata_optional(struct lua_State *L, const char **data,
 			bool is_nullable = mp_decode_bool(data);
 			lua_pushboolean(L, is_nullable);
 			lua_setfield(L, -2, "is_nullable");
+		} else if (key == IPROTO_FIELD_ALIAS) {
+			const char *alias = mp_decode_str(data, &len);
+			lua_pushlstring(L, alias, len);
+			lua_setfield(L, -2, "alias");
 		} else {
 			assert(key == IPROTO_FIELD_AUTOINCREMENT);
 			bool autoincrement = mp_decode_bool(data);
@@ -676,7 +680,7 @@ netbox_decode_metadata(struct lua_State *L, const char **data)
 	lua_createtable(L, count, 0);
 	for (uint32_t i = 0; i < count; ++i) {
 		uint32_t map_size = mp_decode_map(data);
-		assert(map_size >= 2 && map_size <= 5);
+		assert(map_size >= 2 && map_size <= 6);
 		(void) map_size;
 		uint32_t key = mp_decode_uint(data);
 		assert(key == IPROTO_FIELD_NAME);
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index f40178194..5f01ef515 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -1812,8 +1812,13 @@ generate_column_metadata(struct Parse *pParse, struct SrcList *pTabList,
 		}
 		vdbe_set_metadata_col_nullability(v, i, -1);
 		if (pEList->a[i].zName) {
-			char *zName = pEList->a[i].zName;
-			vdbe_set_metadata_col_name(v, i, zName);
+			char *name = pEList->a[i].zSpan != NULL ?
+				     pEList->a[i].zSpan : pEList->a[i].zName;
+			vdbe_set_metadata_col_name(v, i, name);
+			if (pEList->a[i].zSpan != NULL) {
+				vdbe_set_metadata_col_alias(v, i,
+							    pEList->a[i].zName);
+			}
 		} else if (p->op == TK_COLUMN || p->op == TK_AGG_COLUMN) {
 			char *zCol;
 			int iCol = p->iColumn;
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 590791648..d34e7bc52 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -585,6 +585,9 @@ sql_column_is_nullable(sql_stmt *stmt, int n);
 bool
 sql_column_is_autoincrement(sql_stmt *stmt, int n);
 
+const char *
+sql_column_alias(sql_stmt *stmt, int n);
+
 int
 sql_initialize(void);
 
diff --git a/src/box/sql/vdbe.h b/src/box/sql/vdbe.h
index 4e1a67416..e4fecba6d 100644
--- a/src/box/sql/vdbe.h
+++ b/src/box/sql/vdbe.h
@@ -263,6 +263,9 @@ vdbe_set_metadata_col_nullability(struct Vdbe *p, int idx, int nullable);
 void
 vdbe_set_metadata_col_autoincrement(struct Vdbe *p, int idx);
 
+int
+vdbe_set_metadata_col_alias(struct Vdbe *p, int idx, const char *alias);
+
 void sqlVdbeCountChanges(Vdbe *);
 sql *sqlVdbeDb(Vdbe *);
 void sqlVdbeSetSql(Vdbe *, const char *z, int n, int);
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index 63afb8777..f97662673 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -350,6 +350,7 @@ struct sql_column_metadata {
 	const char *name;
 	const char *type;
 	const char *collation;
+	const char *alias;
 	/**
 	 * -1 is for any member of result set except for pure
 	 * columns: all other expressions are nullable by default.
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index ece803262..097e13405 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -769,6 +769,14 @@ sql_column_is_autoincrement(sql_stmt *stmt, int n)
 	return p->metadata[n].actoincrement;
 }
 
+const char *
+sql_column_alias(sql_stmt *stmt, int n)
+{
+	struct Vdbe *p = (struct Vdbe *) stmt;
+	assert(n < sql_column_count(stmt) && n >= 0);
+	return p->metadata[n].alias;
+}
+
 /******************************* sql_bind_  **************************
  *
  * Routines used to attach values to wildcards in a compiled SQL statement.
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 34a0c1267..28f4669e6 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1835,6 +1835,7 @@ vdbe_metadata_delete(struct Vdbe *v)
 			free((void *)v->metadata[i].name);
 			free((void *)v->metadata[i].type);
 			free((void *)v->metadata[i].collation);
+			free((void *)v->metadata[i].alias);
 		}
 		free(v->metadata);
 	}
@@ -1918,6 +1919,20 @@ vdbe_set_metadata_col_autoincrement(struct Vdbe *p, int idx)
 	p->metadata[idx].actoincrement = 1;
 }
 
+int
+vdbe_set_metadata_col_alias(struct Vdbe *p, int idx, const char *alias)
+{
+	assert(idx < p->nResColumn);
+	if (p->metadata[idx].alias != NULL)
+		free((void *)p->metadata[idx].alias);
+	p->metadata[idx].alias = strdup(alias);
+	if (p->metadata[idx].alias == NULL) {
+		diag_set(OutOfMemory, strlen(alias), "strdup", "alias");
+		return -1;
+	}
+	return 0;
+}
+
 /*
  * This routine checks that the sql.nVdbeActive count variable
  * matches the number of vdbe's in the list sql.pVdbe that are
diff --git a/test/sql-tap/badutf1.test.lua b/test/sql-tap/badutf1.test.lua
index 9079dfe25..6623999d0 100755
--- a/test/sql-tap/badutf1.test.lua
+++ b/test/sql-tap/badutf1.test.lua
@@ -25,7 +25,7 @@ test:do_test(
     "badutf-1.1",
     function()
         --test:execsql "PRAGMA encoding='UTF8'"
-        return test:execsql2("SELECT hex('\x80') AS x")
+        return test:execsql_aliases("SELECT hex('\x80') AS x")
     end, {
         -- <badutf-1.1>
         "X", "80"
@@ -35,7 +35,7 @@ test:do_test(
 test:do_test(
     "badutf-1.2",
     function()
-        return test:execsql2("SELECT hex('\x81') AS x")
+        return test:execsql_aliases("SELECT hex('\x81') AS x")
     end, {
         -- <badutf-1.2>
         "X", "81"
@@ -45,7 +45,7 @@ test:do_test(
 test:do_test(
     "badutf-1.3",
     function()
-        return test:execsql2("SELECT hex('\xbf') AS x")
+        return test:execsql_aliases("SELECT hex('\xbf') AS x")
     end, {
         -- <badutf-1.3>
         "X", "BF"
@@ -55,7 +55,7 @@ test:do_test(
 test:do_test(
     "badutf-1.4",
     function()
-        return test:execsql2("SELECT hex('\xc0') AS x")
+        return test:execsql_aliases("SELECT hex('\xc0') AS x")
     end, {
         -- <badutf-1.4>
         "X", "C0"
@@ -65,7 +65,7 @@ test:do_test(
 test:do_test(
     "badutf-1.5",
     function()
-        return test:execsql2("SELECT hex('\xe0') AS x")
+        return test:execsql_aliases("SELECT hex('\xe0') AS x")
     end, {
         -- <badutf-1.5>
         "X", "E0"
@@ -75,7 +75,7 @@ test:do_test(
 test:do_test(
     "badutf-1.6",
     function()
-        return test:execsql2("SELECT hex('\xf0') AS x")
+        return test:execsql_aliases("SELECT hex('\xf0') AS x")
     end, {
         -- <badutf-1.6>
         "X", "F0"
@@ -85,7 +85,7 @@ test:do_test(
 test:do_test(
     "badutf-1.7",
     function()
-        return test:execsql2("SELECT hex('\xff') AS x")
+        return test:execsql_aliases("SELECT hex('\xff') AS x")
     end, {
         -- <badutf-1.7>
         "X", "FF"
@@ -212,7 +212,7 @@ end
 test:do_test(
     "badutf-3.1",
     function()
-        return test:execsql2("SELECT length('\x80') AS x")
+        return test:execsql_aliases("SELECT length('\x80') AS x")
     end, {
         -- <badutf-3.1>
         "X", 1
@@ -222,7 +222,7 @@ test:do_test(
 test:do_test(
     "badutf-3.2",
     function()
-        return test:execsql2("SELECT length('\x61\x62\x63') AS x")
+        return test:execsql_aliases("SELECT length('\x61\x62\x63') AS x")
     end, {
         -- <badutf-3.2>
         "X", 3
@@ -232,7 +232,7 @@ test:do_test(
 test:do_test(
     "badutf-3.3",
     function()
-        return test:execsql2("SELECT length('\x7f\x80\x81') AS x")
+        return test:execsql_aliases("SELECT length('\x7f\x80\x81') AS x")
     end, {
         -- <badutf-3.3>
         "X", 3
@@ -242,7 +242,7 @@ test:do_test(
 test:do_test(
     "badutf-3.4",
     function()
-        return test:execsql2("SELECT length('\x61\xc0') AS x")
+        return test:execsql_aliases("SELECT length('\x61\xc0') AS x")
     end, {
         -- <badutf-3.4>
         "X", 2
@@ -252,7 +252,7 @@ test:do_test(
 test:do_test(
     "badutf-3.5",
     function()
-        return test:execsql2("SELECT length('\x61\xc0\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80') AS x")
+        return test:execsql_aliases("SELECT length('\x61\xc0\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80') AS x")
     end, {
         -- <badutf-3.5>
         "X", 12
@@ -262,7 +262,7 @@ test:do_test(
 test:do_test(
     "badutf-3.6",
     function()
-        return test:execsql2("SELECT length('\xc0\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80') AS x")
+        return test:execsql_aliases("SELECT length('\xc0\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80') AS x")
     end, {
         -- <badutf-3.6>
         "X", 11
@@ -272,7 +272,7 @@ test:do_test(
 test:do_test(
     "badutf-3.7",
     function()
-        return test:execsql2("SELECT length('\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80') AS x")
+        return test:execsql_aliases("SELECT length('\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80') AS x")
     end, {
         -- <badutf-3.7>
         "X", 10
@@ -282,7 +282,7 @@ test:do_test(
 test:do_test(
     "badutf-3.8",
     function()
-        return test:execsql2("SELECT length('\x80\x80\x80\x80\x80\xf0\x80\x80\x80\x80') AS x")
+        return test:execsql_aliases("SELECT length('\x80\x80\x80\x80\x80\xf0\x80\x80\x80\x80') AS x")
     end, {
         -- <badutf-3.8>
         "X", 7
@@ -292,7 +292,7 @@ test:do_test(
 test:do_test(
     "badutf-3.9",
     function()
-        return test:execsql2("SELECT length('\x80\x80\x80\x80\x80\xf0\x80\x80\x80\xff') AS x")
+        return test:execsql_aliases("SELECT length('\x80\x80\x80\x80\x80\xf0\x80\x80\x80\xff') AS x")
     end, {
         -- <badutf-3.9>
         "X", 7
@@ -302,7 +302,7 @@ test:do_test(
 test:do_test(
     "badutf-4.1",
     function()
-        return test:execsql2("SELECT hex(TRIM('\x80\xff' FROM '\x80\x80\x80\xf0\x80\x80\x80\xff')) AS x")
+        return test:execsql_aliases("SELECT hex(TRIM('\x80\xff' FROM '\x80\x80\x80\xf0\x80\x80\x80\xff')) AS x")
     end, {
         -- <badutf-4.1>
         "X", "F0"
@@ -312,7 +312,7 @@ test:do_test(
 test:do_test(
     "badutf-4.2",
     function()
-        return test:execsql2("SELECT hex(TRIM(LEADING '\x80\xff' FROM '\x80\x80\x80\xf0\x80\x80\x80\xff')) AS x")
+        return test:execsql_aliases("SELECT hex(TRIM(LEADING '\x80\xff' FROM '\x80\x80\x80\xf0\x80\x80\x80\xff')) AS x")
     end, {
         -- <badutf-4.2>
         "X", "F0808080FF"
@@ -322,7 +322,7 @@ test:do_test(
 test:do_test(
     "badutf-4.3",
     function()
-        return test:execsql2("SELECT hex(TRIM(TRAILING '\x80\xff' FROM '\x80\x80\x80\xf0\x80\x80\x80\xff')) AS x")
+        return test:execsql_aliases("SELECT hex(TRIM(TRAILING '\x80\xff' FROM '\x80\x80\x80\xf0\x80\x80\x80\xff')) AS x")
     end, {
         -- <badutf-4.3>
         "X", "808080F0"
@@ -332,7 +332,7 @@ test:do_test(
 test:do_test(
     "badutf-4.4",
     function()
-        return test:execsql2("SELECT hex(TRIM('\xff\x80' FROM '\x80\x80\x80\xf0\x80\x80\x80\xff')) AS x")
+        return test:execsql_aliases("SELECT hex(TRIM('\xff\x80' FROM '\x80\x80\x80\xf0\x80\x80\x80\xff')) AS x")
     end, {
         -- <badutf-4.4>
         "X", "808080F0808080FF"
@@ -342,7 +342,7 @@ test:do_test(
 test:do_test(
     "badutf-4.5",
     function()
-        return test:execsql2("SELECT hex(TRIM('\xff\x80' FROM '\xff\x80\x80\xf0\x80\x80\x80\xff')) AS x")
+        return test:execsql_aliases("SELECT hex(TRIM('\xff\x80' FROM '\xff\x80\x80\xf0\x80\x80\x80\xff')) AS x")
     end, {
         -- <badutf-4.5>
         "X", "80F0808080FF"
@@ -352,7 +352,7 @@ test:do_test(
 test:do_test(
     "badutf-4.6",
     function()
-        return test:execsql2("SELECT hex(TRIM('\xff\x80' FROM '\xff\x80\xf0\x80\x80\x80\xff')) AS x")
+        return test:execsql_aliases("SELECT hex(TRIM('\xff\x80' FROM '\xff\x80\xf0\x80\x80\x80\xff')) AS x")
     end, {
         -- <badutf-4.6>
         "X", "F0808080FF"
@@ -362,7 +362,7 @@ test:do_test(
 test:do_test(
     "badutf-4.7",
     function()
-        return test:execsql2("SELECT hex(TRIM('\xff\x80\x80' FROM '\xff\x80\xf0\x80\x80\x80\xff')) AS x")
+        return test:execsql_aliases("SELECT hex(TRIM('\xff\x80\x80' FROM '\xff\x80\xf0\x80\x80\x80\xff')) AS x")
     end, {
         -- <badutf-4.7>
         "X", "FF80F0808080FF"
diff --git a/test/sql-tap/colname.test.lua b/test/sql-tap/colname.test.lua
index 253497cf3..260c4c761 100755
--- a/test/sql-tap/colname.test.lua
+++ b/test/sql-tap/colname.test.lua
@@ -112,7 +112,7 @@ test:do_execsql2_test(
         -- </colname-2.3>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "colname-2.4",
     [[
         SELECT +tabc.a AS AAA, -tabc.b AS BBB, tabc.c CCC, * FROM tabc
@@ -213,7 +213,7 @@ test:do_execsql2_test(
         -- </colname-3.3>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "colname-3.4",
     [[
         SELECT +tabc.a AS AAA, -tabc.b AS BBB, tabc.c CCC FROM tabc
@@ -334,7 +334,7 @@ test:do_execsql2_test(
         -- </colname-4.3>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "colname-4.4",
     [[
         SELECT +tabc.a AS AAA, -tabc.b AS BBB, tabc.c CCC FROM tabc
@@ -480,7 +480,7 @@ test:do_execsql2_test(
         -- </colname-6.3>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "colname-6.11",
     [[
         SELECT a, max(a) AS m FROM t6
@@ -490,7 +490,7 @@ test:do_execsql2_test(
         -- </colname-6.11>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "colname-6.13",
     [[
         SELECT a, max(a) AS m FROM t6
@@ -500,7 +500,7 @@ test:do_execsql2_test(
         -- </colname-6.13>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "colname-6.15",
     [[
         SELECT t6.a, max(a) AS m FROM t6
@@ -510,7 +510,7 @@ test:do_execsql2_test(
         -- </colname-6.15>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "colname-6.18",
     [=[
         SELECT "[a]", max("[a]") AS m FROM t6
@@ -520,7 +520,7 @@ test:do_execsql2_test(
         -- </colname-6.18>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "colname-6.19",
     [=[
         SELECT "`a`", max("`a`") AS m FROM t6
diff --git a/test/sql-tap/lua/sqltester.lua b/test/sql-tap/lua/sqltester.lua
index 0f3411419..12cb3462e 100644
--- a/test/sql-tap/lua/sqltester.lua
+++ b/test/sql-tap/lua/sqltester.lua
@@ -210,6 +210,11 @@ local function do_execsql2_test(self, label, sql, expect)
 end
 test.do_execsql2_test = do_execsql2_test
 
+local function do_execsql_aliases(self, label, sql, expect)
+    return do_test(self, label, function() return test.execsql_aliases(self, sql) end, expect)
+end
+test.do_execsql_aliases_test = do_execsql_aliases
+
 local function flattern_with_column_names(result, metadata)
     local ret = {}
     for i = 1, #result, 1 do
@@ -221,6 +226,22 @@ local function flattern_with_column_names(result, metadata)
     return ret
 end
 
+local function flattern_with_column_aliases(result, metadata)
+    local ret = {}
+    for i = 1, #result, 1 do
+        for j = 1, #metadata, 1 do
+            if metadata[j].alias ~= nil then
+                table.insert(ret, metadata[j].alias)
+            else
+                table.insert(ret, metadata[j].name)
+            end
+            table.insert(ret, result[i][j])
+        end
+    end
+    return ret
+end
+
+
 function test.do_catchsql_set_test(self, testcases, prefix)
     -- testcases structure:
     -- {
@@ -248,6 +269,14 @@ local function execsql2(self, sql)
 end
 test.execsql2 = execsql2
 
+local function execsql_aliases(self, sql)
+    local result, metadata = execsql_one_by_one(sql)
+    if type(result) ~= 'table' then return end
+    result = flattern_with_column_aliases(result, metadata)
+    return result
+end
+test.execsql_aliases = execsql_aliases
+
 local function sortsql(self, sql)
     local result = execsql(self, sql)
     table.sort(result, function(a,b) return a[2] < b[2] end)
diff --git a/test/sql-tap/select1.test.lua b/test/sql-tap/select1.test.lua
index 4bbfbd67b..9a5f814c9 100755
--- a/test/sql-tap/select1.test.lua
+++ b/test/sql-tap/select1.test.lua
@@ -980,43 +980,43 @@ test:do_catchsql2_test(
         -- </select1-6.1.6>
     })
 
-test:do_catchsql2_test(
+test:do_execsql_aliases_test(
     "select1-6.2",
     [[
         SELECT f1 as xyzzy FROM test1 ORDER BY f2
     ]], {
         -- <select1-6.2>
-        0, {"XYZZY", 11, "XYZZY", 33}
+        "XYZZY", 11, "XYZZY", 33
         -- </select1-6.2>
     })
 
-test:do_catchsql2_test(
+test:do_execsql_aliases_test(
     "select1-6.3",
     [[
         SELECT f1 as "xyzzy" FROM test1 ORDER BY f2
     ]], {
         -- <select1-6.3>
-        0, {"xyzzy", 11, "xyzzy", 33}
+        "xyzzy", 11, "xyzzy", 33
         -- </select1-6.3>
     })
 
-test:do_catchsql2_test(
+test:do_execsql_aliases_test(
     "select1-6.3.1",
     [[
         SELECT f1 as "xyzzy " FROM test1 ORDER BY f2
     ]], {
         -- <select1-6.3.1>
-        0, {"xyzzy ", 11, "xyzzy ", 33}
+        "xyzzy ", 11, "xyzzy ", 33
         -- </select1-6.3.1>
     })
 
-test:do_catchsql2_test(
+test:do_execsql_aliases_test(
     "select1-6.4",
     [[
         SELECT f1+F2 as xyzzy FROM test1 ORDER BY f2
     ]], {
         -- <select1-6.4>
-        0, {"XYZZY", 33, "XYZZY", 77}
+        "XYZZY", 33, "XYZZY", 77
         -- </select1-6.4>
     })
 
@@ -1879,7 +1879,7 @@ test:do_execsql2_test(
         -- </select1-12.2>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "select1-12.3",
     [[
         SELECT 1 as "a",'hello' as "b",2 as "c"
diff --git a/test/sql-tap/select4.test.lua b/test/sql-tap/select4.test.lua
index 23cf1bf1b..e2fafd41d 100755
--- a/test/sql-tap/select4.test.lua
+++ b/test/sql-tap/select4.test.lua
@@ -831,7 +831,7 @@ test:do_execsql2_test(
         -- </select4-9.4>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "select4-9.5",
     [[
         SELECT 0 AS x, 1 AS y
@@ -894,7 +894,7 @@ test:do_execsql_test(
         -- </select4-9.8>
     })
 
-test:do_execsql2_test(
+test:do_execsql_aliases_test(
     "select4-9.9.1",
     [[
         SELECT 1 AS a, 2 AS b UNION ALL SELECT 3 AS b, 4 AS a
diff --git a/test/sql-tap/view.test.lua b/test/sql-tap/view.test.lua
index 6234f863e..657910006 100755
--- a/test/sql-tap/view.test.lua
+++ b/test/sql-tap/view.test.lua
@@ -912,7 +912,7 @@ test:do_execsql2_test(
         SELECT x, y FROM v15 LIMIT 1
     ]], {
         -- <view-15.2>
-        "X", 2, "Y", 3
+        "x", 2, "y", 3
         -- </view-15.2>
     })
 
diff --git a/test/sql/bind.result b/test/sql/bind.result
index b24094052..d9e917925 100644
--- a/test/sql/bind.result
+++ b/test/sql/bind.result
@@ -192,10 +192,12 @@ execute('SELECT ?, ?, ?, ?, ?', {'abc', -123.456, msgpack.NULL, true, false})
 execute('SELECT ? AS kek, ? AS kek2', {1, 2})
 ---
 - metadata:
-  - name: KEK
-    type: integer
-  - name: KEK2
-    type: integer
+  - type: integer
+    name: '?'
+    alias: KEK
+  - type: integer
+    name: '?'
+    alias: KEK2
   rows:
   - [1, 2]
 ...
@@ -243,8 +245,9 @@ execute(sql, parameters)
 execute('SELECT ? AS big_uint', {0xefffffffffffffff})
 ---
 - metadata:
-  - name: BIG_UINT
-    type: integer
+  - type: integer
+    name: '?'
+    alias: BIG_UINT
   rows:
   - [17293822569102704640]
 ...
diff --git a/test/sql/boolean.result b/test/sql/boolean.result
index 339e7d9d0..6889edc56 100644
--- a/test/sql/boolean.result
+++ b/test/sql/boolean.result
@@ -862,8 +862,10 @@ FROM t4;
  |   - type: integer
  |     name: I
  |     is_nullable: false
- |   - name: A0
- |     type: boolean
+ |   - type: boolean
+ |     name: "CASE  \tWHEN a == true AND i % 2 == 1 THEN false  \tWHEN a == true and
+ |       i % 2 == 0 THEN true  \tWHEN a != true then false  END"
+ |     alias: A0
  |   rows:
  |   - [100, true]
  |   - [111, false]
diff --git a/test/sql/collation.result b/test/sql/collation.result
index 750e9c509..f863784da 100644
--- a/test/sql/collation.result
+++ b/test/sql/collation.result
@@ -70,10 +70,12 @@ box.execute([[SELECT descriptor, upper(letter) AS upper,lower(letter) AS lower F
   - type: string
     name: DESCRIPTOR
     is_nullable: false
-  - name: UPPER
-    type: string
-  - name: LOWER
-    type: string
+  - type: string
+    name: upper(letter)
+    alias: UPPER
+  - type: string
+    name: lower(letter)
+    alias: LOWER
   rows:
   - ['Latin Capital Letter I U+0049', 'I', 'i']
   - ['Latin Capital Letter I With Dot Above U+0130', 'İ', 'i̇']
@@ -88,11 +90,13 @@ box.execute([[SELECT descriptor, upper(letter COLLATE "TURKISH") AS upper,lower(
     name: DESCRIPTOR
     is_nullable: false
   - type: string
-    name: UPPER
     collation: TURKISH
+    name: upper(letter COLLATE "TURKISH")
+    alias: UPPER
   - type: string
-    name: LOWER
     collation: TURKISH
+    name: lower(letter COLLATE "TURKISH")
+    alias: LOWER
   rows:
   - ['Latin Capital Letter I U+0049', 'I', 'ı']
   - ['Latin Capital Letter I With Dot Above U+0130', 'İ', 'i']
diff --git a/test/sql/iproto.result b/test/sql/iproto.result
index 05c59318c..58c0bb4d8 100644
--- a/test/sql/iproto.result
+++ b/test/sql/iproto.result
@@ -112,8 +112,9 @@ cn:execute('insert qwerty gjsdjq  q  qwd qmq;; q;qwd;')
 cn:execute('select id as identifier from test where a = 5;')
 ---
 - metadata:
-  - name: IDENTIFIER
-    type: integer
+  - type: integer
+    name: id
+    alias: IDENTIFIER
   rows: []
 ...
 -- netbox API errors.
-- 
2.15.1



More information about the Tarantool-patches mailing list