diff --git a/src/box/field_def.h b/src/box/field_def.h
index bd3f9ba4559520924c454aec0a58fe62f4cb5298..93e38ea552c3b27ecb87aa88cf7e5dce3b334059 100644
--- a/src/box/field_def.h
+++ b/src/box/field_def.h
@@ -77,7 +77,6 @@ enum affinity_type {
     AFFINITY_UNDEFINED = 0,
     AFFINITY_BLOB = 'A',
     AFFINITY_TEXT = 'B',
-    AFFINITY_NUMERIC = 'C',
     AFFINITY_INTEGER = 'D',
     AFFINITY_REAL = 'E',
 };
diff --git a/src/box/lua/lua_sql.c b/src/box/lua/lua_sql.c
index 5c77b80367cbfd330d9fa862b545aca5ea292ee4..ab0b7f37cb232ae5507fc0dc8a1d3181949e7818 100644
--- a/src/box/lua/lua_sql.c
+++ b/src/box/lua/lua_sql.c
@@ -158,7 +158,7 @@ lbox_sql_create_function(struct lua_State *L)
 	else if (strcmp(type_arg, "FLOAT") == 0)
 		type = AFFINITY_REAL;
 	else if (strcmp(type_arg, "NUM") == 0)
-		type = AFFINITY_NUMERIC;
+		type = AFFINITY_REAL;
 	else if (strcmp(type_arg, "BLOB") == 0)
 		type = AFFINITY_BLOB;
 	else
diff --git a/src/box/sql.c b/src/box/sql.c
index 45d15bb4659cc73a7d79528d136aeb0d72b80e7e..baa67da397853707b565cc0d97f870f81802352a 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -382,15 +382,18 @@ sql_ephemeral_space_create(uint32_t field_count, struct sql_key_info *key_info)
 	for (uint32_t i = 0; i < field_count; ++i) {
 		struct key_part_def *part = &ephemer_key_parts[i];
 		part->fieldno = i;
-		part->type = FIELD_TYPE_SCALAR;
 		part->nullable_action = ON_CONFLICT_ACTION_NONE;
 		part->is_nullable = true;
 		part->sort_order = SORT_ORDER_ASC;
 		part->path = NULL;
-		if (def != NULL && i < def->part_count)
+		if (def != NULL && i < def->part_count) {
+			assert(def->parts[i].type < field_type_MAX);
+			part->type = def->parts[i].type;
 			part->coll_id = def->parts[i].coll_id;
-		else
+		} else {
 			part->coll_id = COLL_NONE;
+			part->type = FIELD_TYPE_SCALAR;
+		}
 	}
 	struct key_def *ephemer_key_def = key_def_new(ephemer_key_parts,
 						      field_count);
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index b8b91657db2e8d324b9f192ead0387b25206c09f..63d3727893024e48778ca7d93bd735faf4bac190 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -492,7 +492,6 @@ sql_affinity_to_field_type(enum affinity_type affinity)
 		case AFFINITY_INTEGER:
 			return FIELD_TYPE_INTEGER;
 		case AFFINITY_REAL:
-		case AFFINITY_NUMERIC:
 			return FIELD_TYPE_NUMBER;
 		case AFFINITY_TEXT:
 			return FIELD_TYPE_STRING;
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index d83be51015f7e49ce53456e3b3ba3cdae5dd6cdf..a6cf7bdb13a4d7522ddd873b1d223d2371d0e3ab 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -261,7 +261,7 @@ sql_affinity_result(enum affinity_type aff1, enum affinity_type aff2)
 		 */
 		if (sqlite3IsNumericAffinity(aff1)
 		    || sqlite3IsNumericAffinity(aff2)) {
-			return AFFINITY_NUMERIC;
+			return AFFINITY_REAL;
 		} else {
 			return AFFINITY_BLOB;
 		}
@@ -2164,12 +2164,10 @@ sqlite3ExprNeedsNoAffinityChange(const Expr * p, char aff)
 		op = p->op2;
 	switch (op) {
 	case TK_INTEGER:{
-			return aff == AFFINITY_INTEGER
-			    || aff == AFFINITY_NUMERIC;
+			return aff == AFFINITY_INTEGER;
 		}
 	case TK_FLOAT:{
-			return aff == AFFINITY_REAL
-			    || aff == AFFINITY_NUMERIC;
+			return aff == AFFINITY_REAL;
 		}
 	case TK_STRING:{
 			return aff == AFFINITY_TEXT;
@@ -2181,7 +2179,7 @@ sqlite3ExprNeedsNoAffinityChange(const Expr * p, char aff)
 			assert(p->iTable >= 0);	/* p cannot be part of a CHECK constraint */
 			return p->iColumn < 0
 			    && (aff == AFFINITY_INTEGER
-				|| aff == AFFINITY_NUMERIC);
+				|| aff == AFFINITY_REAL);
 		}
 	default:{
 			return 0;
@@ -3696,6 +3694,11 @@ sqlite3ExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 				sqlite3VdbeAddOp3(v, OP_Column,
 						  pAggInfo->sortingIdxPTab,
 						  pCol->iSorterColumn, target);
+				if (pCol->space_def->fields[pExpr->iAgg].type ==
+				    FIELD_TYPE_NUMBER) {
+					sqlite3VdbeAddOp1(v, OP_RealAffinity,
+							  target);
+				}
 				return target;
 			}
 			/* Otherwise, fall thru into the TK_COLUMN case */
@@ -3881,14 +3884,14 @@ sqlite3ExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 			testcase(regFree1 == 0);
 			testcase(regFree2 == 0);
 			if (op != TK_CONCAT)
-				pExpr->affinity = AFFINITY_NUMERIC;
+				pExpr->affinity = AFFINITY_REAL;
 			else
 				pExpr->affinity = AFFINITY_TEXT;
 			break;
 		}
 	case TK_UMINUS:{
 			Expr *pLeft = pExpr->pLeft;
-			pExpr->affinity = AFFINITY_NUMERIC;
+			pExpr->affinity = AFFINITY_REAL;
 			assert(pLeft);
 			if (pLeft->op == TK_INTEGER) {
 				expr_code_int(pParse, pLeft, true, target);
@@ -4180,7 +4183,7 @@ sqlite3ExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
 						     target);
 		}
 	case TK_UPLUS:{
-			pExpr->affinity = AFFINITY_NUMERIC;
+			pExpr->affinity = AFFINITY_REAL;
 			return sqlite3ExprCodeTarget(pParse, pExpr->pLeft,
 						     target);
 		}
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index dfe9a83bcaddf832986b4ccc7c671254577e3cd2..e063e989093d0222c9c2d55350b5a7aa1ef7a65a 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -1428,6 +1428,8 @@ sql_expr_list_to_key_info(struct Parse *parse, struct ExprList *list, int start)
 		sql_expr_coll(parse, item->pExpr, &unused, &id);
 		part->coll_id = id;
 		part->sort_order = item->sort_order;
+		enum affinity_type aff = sqlite3ExprAffinity(item->pExpr);
+		part->type = sql_affinity_to_field_type(aff);
 	}
 	return key_info;
 }
@@ -1724,7 +1726,6 @@ generateColumnNames(Parse * pParse,	/* Parser context */
 					      SQLITE_TRANSIENT);
 			break;
 		case AFFINITY_REAL:
-		case AFFINITY_NUMERIC:
 			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, "NUMERIC",
 					      SQLITE_TRANSIENT);
 			break;
@@ -5817,8 +5818,11 @@ sqlite3Select(Parse * pParse,		/* The parser context */
 	/* If the output is destined for a temporary table, open that table.
 	 */
 	if (pDest->eDest == SRT_EphemTab) {
-		sqlite3VdbeAddOp2(v, OP_OpenTEphemeral, pDest->reg_eph,
-				  pEList->nExpr + 1);
+		struct sql_key_info *key_info =
+			sql_expr_list_to_key_info(pParse, pEList, 0);
+		sqlite3VdbeAddOp4(v, OP_OpenTEphemeral, pDest->reg_eph,
+				  pEList->nExpr + 1, 0, (char *)key_info,
+				  P4_KEYINFO);
 		sqlite3VdbeAddOp3(v, OP_IteratorOpen, pDest->iSDParm, 0,
 				  pDest->reg_eph);
 
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index de12769698bdde33c0bab287c6769f385c2faa78..29e1657aeaf26095ed492cd22dda349df1961b82 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -1788,7 +1788,7 @@ struct Savepoint {
 #define SAVEPOINT_RELEASE    1
 #define SAVEPOINT_ROLLBACK   2
 
-#define sqlite3IsNumericAffinity(X)  ((X)>=AFFINITY_NUMERIC)
+#define sqlite3IsNumericAffinity(X)  ((X)>=AFFINITY_INTEGER)
 
 /*
  * The AFFINITY_MASK values masks off the significant bits of an
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 9fc362f0a3658582c36659840bc701be5397e96b..15c3305e388d4db76c12920a87dc7e0e5fe3667f 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -311,7 +311,6 @@ applyNumericAffinity(Mem *pRec, int bTryForInt)
  *
  * AFFINITY_INTEGER:
  * AFFINITY_REAL:
- * AFFINITY_NUMERIC:
  *    Try to convert mem to an integer representation or a
  *    floating-point representation if an integer representation
  *    is not possible.  Note that the integer representation is
@@ -346,13 +345,9 @@ mem_apply_affinity(struct Mem *record, enum affinity_type affinity)
 		}
 		return sqlite3VdbeMemIntegerify(record, false);
 	case AFFINITY_REAL:
-		if ((record->flags & MEM_Real) == MEM_Real)
-			return 0;
-		return sqlite3VdbeMemRealify(record);
-	case AFFINITY_NUMERIC:
 		if ((record->flags & (MEM_Real | MEM_Int)) != 0)
 			return 0;
-		return sqlite3VdbeMemNumerify(record);
+		return sqlite3VdbeMemRealify(record);
 	case AFFINITY_TEXT:
 		/*
 		 * Only attempt the conversion to TEXT if there is
@@ -2006,7 +2001,6 @@ case OP_Cast: {                  /* in1 */
 	assert(pOp->p2>=AFFINITY_BLOB && pOp->p2<=AFFINITY_REAL);
 	testcase( pOp->p2==AFFINITY_TEXT);
 	testcase( pOp->p2==AFFINITY_BLOB);
-	testcase( pOp->p2==AFFINITY_NUMERIC);
 	testcase( pOp->p2==AFFINITY_INTEGER);
 	testcase( pOp->p2==AFFINITY_REAL);
 	pIn1 = &aMem[pOp->p1];
@@ -2174,7 +2168,7 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
 	} else {
 		/* Neither operand is NULL.  Do a comparison. */
 		affinity = pOp->p5 & AFFINITY_MASK;
-		if (affinity>=AFFINITY_NUMERIC) {
+		if (affinity>=AFFINITY_INTEGER) {
 			if ((flags1 | flags3)&MEM_Str) {
 				if ((flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str) {
 					applyNumericAffinity(pIn1,0);
@@ -2769,6 +2763,22 @@ case OP_Column: {
 		pDest->flags = MEM_Blob|MEM_Ephem|MEM_Subtype;
 		pDest->subtype = SQL_SUBTYPE_MSGPACK;
 	}
+	if ((pDest->flags & MEM_Int) != 0 &&
+	    pC->eCurType == CURTYPE_TARANTOOL) {
+		enum field_type f = FIELD_TYPE_ANY;
+		/*
+		 * Ephemeral spaces feature only one index
+		 * covering all fields, but ephemeral spaces
+		 * lack format. So, we can fetch type from
+		 * key parts.
+		 */
+		if (pC->uc.pCursor->curFlags & BTCF_TEphemCursor)
+			f = pC->uc.pCursor->index->def->key_def->parts[p2].type;
+		else if (pC->uc.pCursor->curFlags & BTCF_TaCursor)
+			f = pC->uc.pCursor->space->def->fields[p2].type;
+		if (f == FIELD_TYPE_NUMBER)
+			sqlite3VdbeMemSetDouble(pDest, pDest->u.i);
+	}
 	/*
 	 * Add 0 termination (at most for strings)
 	 * Not sure why do we check MEM_Ephem
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index 7b21f2aaa487d228e29a24a9bc076f36e11228a5..754dc207bc2f13fdbe0a05538e8421706a33d6bc 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -604,8 +604,7 @@ sqlite3VdbeMemCast(Mem * pMem, u8 aff)
 {
 	if (pMem->flags & MEM_Null)
 		return SQLITE_OK;
-	if ((pMem->flags & MEM_Blob) != 0 &&
-	    (aff == AFFINITY_REAL || aff == AFFINITY_NUMERIC)) {
+	if ((pMem->flags & MEM_Blob) != 0 && aff == AFFINITY_REAL) {
 		if (sql_atoi64(pMem->z, (int64_t *) &pMem->u.i, pMem->n) == 0) {
 			MemSetTypeFlag(pMem, MEM_Real);
 			pMem->u.r = pMem->u.i;
@@ -628,8 +627,6 @@ sqlite3VdbeMemCast(Mem * pMem, u8 aff)
 			return 0;
 		}
 		return SQLITE_ERROR;
-	case AFFINITY_NUMERIC:
-		return sqlite3VdbeMemNumerify(pMem);
 	case AFFINITY_INTEGER:
 		if ((pMem->flags & MEM_Blob) != 0) {
 			if (sql_atoi64(pMem->z, (int64_t *) &pMem->u.i,
@@ -1321,7 +1318,7 @@ valueFromExpr(sqlite3 * db,	/* The database connection */
 		}
 		if ((op == TK_INTEGER || op == TK_FLOAT)
 		    && affinity == AFFINITY_BLOB) {
-			sqlite3ValueApplyAffinity(pVal, AFFINITY_NUMERIC);
+			sqlite3ValueApplyAffinity(pVal, AFFINITY_REAL);
 		} else {
 			sqlite3ValueApplyAffinity(pVal, affinity);
 		}
@@ -1721,15 +1718,28 @@ void
 mpstream_encode_vdbe_mem(struct mpstream *stream, struct Mem *var)
 {
 	assert(memIsValid(var));
+	int64_t i;
 	if (var->flags & MEM_Null) {
 		mpstream_encode_nil(stream);
 	} else if (var->flags & MEM_Real) {
+		/*
+		 * We can't pass to INT iterator float
+		 * value. Hence, if floating point value
+		 * lacks fractional component, we can
+		 * encode it as INT and successfully
+		 * pass to INT iterator.
+		 */
+		i = var->u.r;
+		if (i == var->u.r)
+			goto encode_int;
 		mpstream_encode_double(stream, var->u.r);
 	} else if (var->flags & MEM_Int) {
+		i = var->u.i;
+encode_int:
 		if (var->u.i >= 0)
-			mpstream_encode_uint(stream, var->u.i);
+			mpstream_encode_uint(stream, i);
 		else
-			mpstream_encode_int(stream, var->u.i);
+			mpstream_encode_int(stream, i);
 	} else if (var->flags & MEM_Str) {
 		mpstream_encode_strn(stream, var->z, var->n);
 	} else if (var->flags & MEM_Bool) {
diff --git a/test/sql-tap/tkt-80e031a00f.test.lua b/test/sql-tap/tkt-80e031a00f.test.lua
index 0cbdb47a2bf9705075bd79823d67894a26d87de3..2d4f81798c485c9ef994ec9e17017c961f4091fc 100755
--- a/test/sql-tap/tkt-80e031a00f.test.lua
+++ b/test/sql-tap/tkt-80e031a00f.test.lua
@@ -346,7 +346,7 @@ test:do_catchsql_test(
         SELECT 'hello' IN t1
     ]], {
         -- <tkt-80e031a00f.27>
-        1, 'Type mismatch: can not convert hello to numeric'
+        1, 'Type mismatch: can not convert hello to real'
         -- </tkt-80e031a00f.27>
     })
 
@@ -356,7 +356,7 @@ test:do_catchsql_test(
         SELECT 'hello' NOT IN t1
     ]], {
         -- <tkt-80e031a00f.28>
-        1, 'Type mismatch: can not convert hello to numeric'
+        1, 'Type mismatch: can not convert hello to real'
         -- </tkt-80e031a00f.28>
     })
 
@@ -380,23 +380,23 @@ test:do_execsql_test(
         -- </tkt-80e031a00f.30>
     })
 
-test:do_execsql_test(
+test:do_catchsql_test(
     "tkt-80e031a00f.31",
     [[
         SELECT x'303132' IN t1
     ]], {
         -- <tkt-80e031a00f.31>
-        0
+        1, 'Type mismatch: can not convert 012 to real'
         -- </tkt-80e031a00f.31>
     })
 
-test:do_execsql_test(
+test:do_catchsql_test(
     "tkt-80e031a00f.32",
     [[
         SELECT x'303132' NOT IN t1
     ]], {
         -- <tkt-80e031a00f.32>
-        1
+        1, 'Type mismatch: can not convert 012 to real'
         -- </tkt-80e031a00f.32>
     })