From 15c990cb04ecb602ecb38a751f019fc8a191f5c7 Mon Sep 17 00:00:00 2001
From: Kirill Shcherbatov <kshcherbatov@tarantool.org>
Date: Thu, 25 Apr 2019 16:51:07 +0300
Subject: [PATCH] sql: fix boolean variables binding

The bindings mechanism was not updated in scope of BOOLEAN static
type patch. Fixed.
---
 src/box/bind.c          |  9 +++++----
 src/box/bind.h          |  1 +
 src/box/sql/sqlInt.h    | 11 +++++++++++
 src/box/sql/vdbeapi.c   | 12 ++++++++++++
 test/sql/bind.result    |  6 +++---
 test/sql/types.result   |  9 +++++++++
 test/sql/types.test.lua |  3 +++
 7 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/src/box/bind.c b/src/box/bind.c
index 5aa79751aa..f15915377f 100644
--- a/src/box/bind.c
+++ b/src/box/bind.c
@@ -98,9 +98,8 @@ sql_bind_decode(struct sql_bind *bind, int i, const char **packet)
 		bind->bytes = 1;
 		break;
 	case MP_BOOL:
-		/* sql doesn't support boolean. Use int instead. */
-		bind->i64 = mp_decode_bool(packet) ? 1 : 0;
-		bind->bytes = sizeof(bind->i64);
+		bind->b = mp_decode_bool(packet);
+		bind->bytes = sizeof(bind->b);
 		break;
 	case MP_BIN:
 		bind->s = mp_decode_bin(packet, &bind->bytes);
@@ -175,9 +174,11 @@ sql_bind_column(struct sql_stmt *stmt, const struct sql_bind *p,
 	switch (p->type) {
 	case MP_INT:
 	case MP_UINT:
-	case MP_BOOL:
 		rc = sql_bind_int64(stmt, pos, p->i64);
 		break;
+	case MP_BOOL:
+		rc = sql_bind_boolean(stmt, pos, p->b);
+		break;
 	case MP_DOUBLE:
 	case MP_FLOAT:
 		rc = sql_bind_double(stmt, pos, p->d);
diff --git a/src/box/bind.h b/src/box/bind.h
index a915381e44..d9823431e6 100644
--- a/src/box/bind.h
+++ b/src/box/bind.h
@@ -61,6 +61,7 @@ struct sql_bind {
 	enum mp_type type;
 	/** Bind value. */
 	union {
+		bool b;
 		double d;
 		int64_t i64;
 		/** For string or blob. */
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 76ea9fb177..997a465354 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -888,6 +888,17 @@ sql_bind_blob64(sql_stmt *, int, const void *,
 int
 sql_bind_double(sql_stmt *, int, double);
 
+/**
+ * Perform boolean parameter binding for the prepared sql
+ * statement.
+ * @param stmt Prepared statement.
+ * @param i Index of the variable to be binded.
+ * @param value Boolean value to use.
+ * @retval 0 On Success, not 0 otherwise.
+ */
+int
+sql_bind_boolean(struct sql_stmt *stmt, int i, bool value);
+
 int
 sql_bind_int(sql_stmt *, int, int);
 
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 4175f7e86d..d2868567be 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -1348,6 +1348,18 @@ sql_bind_double(sql_stmt * pStmt, int i, double rValue)
 	return rc;
 }
 
+int
+sql_bind_boolean(struct sql_stmt *stmt, int i, bool value)
+{
+	struct Vdbe *p = (struct Vdbe *) stmt;
+	int rc = vdbeUnbind(p, i);
+	if (rc == SQL_OK) {
+		rc = sql_bind_type(p, i, "BOOLEAN");
+		mem_set_bool(&p->aVar[i - 1], value);
+	}
+	return rc;
+}
+
 int
 sql_bind_int(sql_stmt * p, int i, int iValue)
 {
diff --git a/test/sql/bind.result b/test/sql/bind.result
index f1d3cd4d4c..076bf8319e 100644
--- a/test/sql/bind.result
+++ b/test/sql/bind.result
@@ -176,11 +176,11 @@ execute('SELECT ?, ?, ?, ?, ?', {'abc', -123.456, msgpack.NULL, true, false})
   - name: '?'
     type: BOOLEAN
   - name: '?'
-    type: INTEGER
+    type: BOOLEAN
   - name: '?'
-    type: INTEGER
+    type: BOOLEAN
   rows:
-  - ['abc', -123.456, null, 1, 0]
+  - ['abc', -123.456, null, true, false]
 ...
 -- Try to replace '?' in meta with something meaningful.
 execute('SELECT ? AS kek, ? AS kek2', {1, 2})
diff --git a/test/sql/types.result b/test/sql/types.result
index 8f442dc7d6..bc4518c010 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -888,3 +888,12 @@ box.execute('SELECT \'9223372036854\' + 1;')
   rows:
   - [9223372036855]
 ...
+-- Fix BOOLEAN bindings.
+box.execute('SELECT ?', {true})
+---
+- metadata:
+  - name: '?'
+    type: BOOLEAN
+  rows:
+  - [true]
+...
diff --git a/test/sql/types.test.lua b/test/sql/types.test.lua
index 48c9bde108..c51660cb9f 100644
--- a/test/sql/types.test.lua
+++ b/test/sql/types.test.lua
@@ -213,3 +213,6 @@ box.space.T1:drop()
 box.execute('SELECT 1 + 1;')
 box.execute('SELECT 1 + 1.1;')
 box.execute('SELECT \'9223372036854\' + 1;')
+
+-- Fix BOOLEAN bindings.
+box.execute('SELECT ?', {true})
-- 
GitLab