diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index d45289235faf7e4d13b13ead2771c909c896e837..620247bee7c4ab707958f0de379b797bd0e44444 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -273,36 +273,21 @@ allocateCursor(
 	return pCx;
 }
 
-/*
- * Try to convert a value into a numeric representation if we can
- * do so without loss of information.  In other words, if the string
- * looks like a number, convert it into a number.  If it does not
- * look like a number, leave it alone.
- *
- * If the bTryForInt flag is true, then extra effort is made to give
- * an integer representation.  Strings that look like floating point
- * values but which have no fractional component (example: '48.00')
- * will have a MEM_Int representation when bTryForInt is true.
- *
- * If bTryForInt is false, then if the input string contains a decimal
- * point or exponential notation, the result is only MEM_Real, even
- * if there is an exact integer representation of the quantity.
- */
-static int
-mem_apply_numeric_type(Mem *pRec, int bTryForInt)
+int
+mem_apply_numeric_type(struct Mem *record)
 {
-	double rValue;
-	i64 iValue;
-	assert((pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str);
-	if (sqlAtoF(pRec->z, &rValue, pRec->n) == 0) return -1;
-	if (0 == sql_atoi64(pRec->z, (int64_t *)&iValue, pRec->n)) {
-		pRec->u.i = iValue;
-		pRec->flags |= MEM_Int;
-	} else {
-		pRec->u.r = rValue;
-		pRec->flags |= MEM_Real;
-		if (bTryForInt) mem_apply_integer_type(pRec);
+	assert((record->flags & (MEM_Str | MEM_Int | MEM_Real)) == MEM_Str);
+	int64_t integer_value;
+	if (sql_atoi64(record->z, &integer_value, record->n) == 0) {
+		record->u.i = integer_value;
+		MemSetTypeFlag(record, MEM_Int);
+		return 0;
 	}
+	double float_value;
+	if (sqlAtoF(record->z, &float_value, record->n) == 0)
+		return -1;
+	record->u.r = float_value;
+	MemSetTypeFlag(record, MEM_Real);
 	return 0;
 }
 
@@ -380,7 +365,7 @@ int sql_value_numeric_type(sql_value *pVal) {
 	int eType = sql_value_type(pVal);
 	if (eType==SQL_TEXT) {
 		Mem *pMem = (Mem*)pVal;
-		mem_apply_numeric_type(pMem, 0);
+		mem_apply_numeric_type(pMem);
 		eType = sql_value_type(pVal);
 	}
 	return eType;
@@ -2172,12 +2157,12 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
 		if (sql_type_is_numeric(type)) {
 			if ((flags1 | flags3)&MEM_Str) {
 				if ((flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str) {
-					mem_apply_numeric_type(pIn1, 0);
+					mem_apply_numeric_type(pIn1);
 					testcase( flags3!=pIn3->flags); /* Possible if pIn1==pIn3 */
 					flags3 = pIn3->flags;
 				}
 				if ((flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str) {
-					if (mem_apply_numeric_type(pIn3, 0) != 0) {
+					if (mem_apply_numeric_type(pIn3) != 0) {
 						diag_set(ClientError,
 							 ER_SQL_TYPE_MISMATCH,
 							 sql_value_text(pIn3),
@@ -3526,7 +3511,7 @@ case OP_SeekGT: {       /* jump, in3 */
 		 */
 		pIn3 = &aMem[reg_ipk];
 		if ((pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str) {
-			mem_apply_numeric_type(pIn3, 0);
+			mem_apply_numeric_type(pIn3);
 		}
 		int64_t i;
 		if ((pIn3->flags & MEM_Int) == MEM_Int) {
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index 577b022197c1df29d319b7b8f310d6f8c9217104..c97aae6289af6eedd3ba4f1f5e6d5746b63b91cc 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -269,6 +269,20 @@ enum {
 char *
 mem_type_to_str(const struct Mem *p);
 
+/**
+ * Try to convert a string value into a numeric representation
+ * if we can do so without loss of information. Firstly, value
+ * is attempted to be converted to integer, and in case of fail -
+ * to floating point number. Note that function is assumed to be
+ * called on memory cell containing string, i.e. mem->type == MEM_Str.
+ *
+ * @param record Memory cell containing value to be converted.
+ * @retval 0 If value can be converted to integer or number.
+ * @retval -1 Otherwise.
+ */
+int
+mem_apply_numeric_type(struct Mem *record);
+
 /* Return TRUE if Mem X contains dynamically allocated content - anything
  * that needs to be deallocated to avoid a leak.
  */