From 1328a88d0bc5875971c7ca3f38d6db5bd41f3215 Mon Sep 17 00:00:00 2001
From: Mergen Imeev <imeevma@gmail.com>
Date: Thu, 13 Dec 2018 21:07:31 +0300
Subject: [PATCH] sql: get results of PRAGMA statement as result set

Currently box.sql.execute ('PRAGMA') returns nothing, but prints
list of pragmas and their statuses to stdout. Such strategy is
considered to be wrong since output of this command would be
unavailable for users who redirect stdout, use net box connection
etc. This patch makes the command to return result as the rest of
SQL commands. The result contains only FLAG-type pragmas and their
statuses.
---
 src/box/sql/pragma.c        | 56 +++++++++++--------------------------
 test/sql/sql-debug.result   | 22 +++++++++++++++
 test/sql/sql-debug.test.lua |  5 ++++
 3 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
index a731e81e1d..436931f15c 100644
--- a/src/box/sql/pragma.c
+++ b/src/box/sql/pragma.c
@@ -168,48 +168,26 @@ pragmaLocate(const char *zName)
 	return lwr > upr ? 0 : &aPragmaName[mid];
 }
 
-#ifdef PRINT_PRAGMA
-#undef PRINT_PRAGMA
-#endif
-#define PRINT_PRAGMA(pragma_name, pragma_flag) do {			       \
-	int nCoolSpaces = 30 - strlen(pragma_name);			       \
-	if (user_session->sql_flags & (pragma_flag)) {			       \
-		printf("%s %*c --  [true] \n", pragma_name, nCoolSpaces, ' '); \
-	} else {							       \
-		printf("%s %*c --  [false] \n", pragma_name, nCoolSpaces, ' ');\
-	}								       \
-} while (0)
-
-#define PRINT_STR_PRAGMA(pragma_name, str_value) do {			       \
-	int nCoolSpaces = 30 - strlen(pragma_name);			       \
-	printf("%s %*c --  '%s' \n", pragma_name, nCoolSpaces, ' ', str_value);\
-} while (0)
-
 static void
-printActivePragmas(struct session *user_session)
+vdbe_emit_pragma_status(struct Parse *parse)
 {
-	int i;
-	for (i = 0; i < ArraySize(aPragmaName); ++i) {
-		switch (aPragmaName[i].ePragTyp) {
-			case PragTyp_FLAG:
-				PRINT_PRAGMA(aPragmaName[i].zName, aPragmaName[i].iArg);
-				break;
-			case PragTyp_DEFAULT_ENGINE: {
-				const char *engine_name =
-					sql_storage_engine_strs[
-						current_session()->
-							sql_default_engine];
-				PRINT_STR_PRAGMA(aPragmaName[i].zName,
-						 engine_name);
-				break;
-			}
-		}
-	}
+	struct Vdbe *v = sqlGetVdbe(parse);
+	struct session *user_session = current_session();
+
+	sqlVdbeSetNumCols(v, 2);
+	sqlVdbeSetColName(v, 0, COLNAME_NAME, "pragma_name", SQL_STATIC);
+	sqlVdbeSetColName(v, 0, COLNAME_DECLTYPE, "TEXT", SQL_STATIC);
+	sqlVdbeSetColName(v, 1, COLNAME_NAME, "pragma_value", SQL_STATIC);
+	sqlVdbeSetColName(v, 1, COLNAME_DECLTYPE, "INTEGER", SQL_STATIC);
 
-	printf("Other available pragmas: \n");
-	for (i = 0; i < ArraySize(aPragmaName); ++i) {
+	parse->nMem = 2;
+	for (int i = 0; i < ArraySize(aPragmaName); ++i) {
 		if (aPragmaName[i].ePragTyp != PragTyp_FLAG)
-			printf("-- %s \n", aPragmaName[i].zName);
+			continue;
+		sqlVdbeAddOp4(v, OP_String8, 0, 1, 0, aPragmaName[i].zName, 0);
+		int val = (user_session->sql_flags & aPragmaName[i].iArg) != 0;
+		sqlVdbeAddOp2(v, OP_Integer, val, 2);
+		sqlVdbeAddOp2(v, OP_ResultRow, 1, 2);
 	}
 }
 
@@ -454,7 +432,7 @@ sqlPragma(Parse * pParse, Token * pId,	/* First part of [schema.]id field */
 
 	zLeft = sqlNameFromToken(db, pId);
 	if (!zLeft) {
-		printActivePragmas(user_session);
+		vdbe_emit_pragma_status(pParse);
 		return;
 	}
 
diff --git a/test/sql/sql-debug.result b/test/sql/sql-debug.result
index 9388578b43..a857392fd5 100644
--- a/test/sql/sql-debug.result
+++ b/test/sql/sql-debug.result
@@ -21,3 +21,25 @@ box.sql.execute('PRAGMA parser_trace')
 box.sql.execute('PRAGMA parser_trace = '.. result[1][1])
 ---
 ...
+--
+-- Make PRAGMA command return the result as a result set.
+--
+box.sql.execute('PRAGMA')
+---
+- - ['case_sensitive_like', 0]
+  - ['count_changes', 0]
+  - ['defer_foreign_keys', 0]
+  - ['full_column_names', 0]
+  - ['parser_trace', 0]
+  - ['recursive_triggers', 1]
+  - ['reverse_unordered_selects', 0]
+  - ['select_trace', 0]
+  - ['short_column_names', 1]
+  - ['sql_trace', 0]
+  - ['vdbe_addoptrace', 0]
+  - ['vdbe_debug', 0]
+  - ['vdbe_eqp', 0]
+  - ['vdbe_listing', 0]
+  - ['vdbe_trace', 0]
+  - ['where_trace', 0]
+...
diff --git a/test/sql/sql-debug.test.lua b/test/sql/sql-debug.test.lua
index 721ef19410..e429c38b34 100644
--- a/test/sql/sql-debug.test.lua
+++ b/test/sql/sql-debug.test.lua
@@ -10,3 +10,8 @@ result = box.sql.execute('PRAGMA parser_trace')
 box.sql.execute('PRAGMA parser_trace = 1')
 box.sql.execute('PRAGMA parser_trace')
 box.sql.execute('PRAGMA parser_trace = '.. result[1][1])
+
+--
+-- Make PRAGMA command return the result as a result set.
+--
+box.sql.execute('PRAGMA')
-- 
GitLab