From feca08c9f5c264b627e750f0c88c3ed97d1bf724 Mon Sep 17 00:00:00 2001
From: Nikita Pettik <korablev@tarantool.org>
Date: Mon, 21 Oct 2019 17:53:31 +0300
Subject: [PATCH] sql: fix off-by-one error in QP

In scope of 8fac697 it was fixed misbehavior while passing floating
point values to integer iterator. Unfortunately, that patch introduced
off-by-one error. Number of constraints (equalities and inequalities)
can not be greater than number of key parts (obviously, each constraint
can be tested against at most one index part). Inequality constraint can
involve only field representing last key part. To get it number of
constraints was used as index. However, since array is 0-based, the last
key part should be calculated as parts[eq_numb - 1]. Before this patch
it was parts[eq_numb].

Closes #4558

(cherry picked from commit bb905d1d1f50796f6090144d07dccfd385f02c5b)
---
 src/box/sql/wherecode.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index de51c0ba5e..5bc27f1348 100644
--- a/src/box/sql/wherecode.c
+++ b/src/box/sql/wherecode.c
@@ -1118,10 +1118,20 @@ sqlWhereCodeOneLoopStart(WhereInfo * pWInfo,	/* Complete information about the W
 			}
 		}
 		/* Inequality constraint comes always at the end of list. */
-		enum field_type ineq_type = idx_def->key_def->parts[nEq].type;
-		if (pRangeStart != NULL && (ineq_type == FIELD_TYPE_INTEGER ||
-					    ineq_type == FIELD_TYPE_UNSIGNED))
-			force_integer_reg = regBase + nEq;
+		part_count = idx_def->key_def->part_count;
+		if (pRangeStart != NULL) {
+			/*
+			 * nEq == 0 means that filter condition
+			 * contains only inequality.
+			 */
+			uint32_t ineq_idx = nEq == 0 ? 0 : nEq - 1;
+			assert(ineq_idx < part_count);
+			enum field_type ineq_type =
+				idx_def->key_def->parts[ineq_idx].type;
+			if (ineq_type == FIELD_TYPE_INTEGER ||
+			    ineq_type == FIELD_TYPE_UNSIGNED)
+				force_integer_reg = regBase + nEq;
+		}
 		emit_apply_type(pParse, regBase, nConstraint - bSeekPastNull,
 				start_types);
 		if (pLoop->nSkip > 0 && nConstraint == pLoop->nSkip) {
-- 
GitLab