From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp41.i.mail.ru (smtp41.i.mail.ru [94.100.177.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 1D10E4696C4 for ; Wed, 5 Feb 2020 19:19:16 +0300 (MSK) From: Nikita Pettik Date: Wed, 5 Feb 2020 19:19:10 +0300 Message-Id: <0a6143594e0279d19d3b760a75f0139dbd42dae8.1580841722.git.korablev@tarantool.org> In-Reply-To: References: In-Reply-To: References: Subject: [Tarantool-patches] [PATCH 2/4] sql: refactor sqlVdbeMemNumerify() List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org Cc: v.shpilevoy@tarantool.org Fix codestyle and comment; allow conversion from boolean to number (since it is legal to convert boolean to integer, and in turn number type completely includes integer type). Part of #4233 --- src/box/sql/vdbeInt.h | 12 +++++++++++- src/box/sql/vdbemem.c | 46 +++++++++++++++++++--------------------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h index 1393f3fd2..a80a691e1 100644 --- a/src/box/sql/vdbeInt.h +++ b/src/box/sql/vdbeInt.h @@ -533,7 +533,17 @@ mem_value_bool(const struct Mem *mem, bool *b); int mem_apply_integer_type(Mem *); int sqlVdbeMemRealify(Mem *); -int sqlVdbeMemNumerify(Mem *); + +/** + * Convert @mem to NUMBER type, so that after conversion it has one + * of types MEM_Real, MEM_Int or MEM_UInt. If conversion is not possible, + * function returns -1. + * + * Beware - this function changes value and type of @mem argument + */ +int +vdbe_mem_numerify(struct Mem *mem); + int sqlVdbeMemCast(Mem *, enum field_type type); int sqlVdbeMemFromBtree(BtCursor *, u32, u32, Mem *); void sqlVdbeMemRelease(Mem * p); diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c index df3f0d8b1..a533a2fe7 100644 --- a/src/box/sql/vdbemem.c +++ b/src/box/sql/vdbemem.c @@ -596,34 +596,26 @@ sqlVdbeMemRealify(Mem * pMem) return 0; } -/* - * Convert pMem so that it has types MEM_Real or MEM_Int or both. - * Invalidate any prior representations. - * - * Every effort is made to force the conversion, even if the input - * is a string that does not look completely like a number. Convert - * as much of the string as we can and ignore the rest. - */ int -sqlVdbeMemNumerify(Mem * pMem) +vdbe_mem_numerify(struct Mem *mem) { - if ((pMem->flags & (MEM_Int | MEM_UInt | MEM_Real | MEM_Null)) == 0) { - assert((pMem->flags & (MEM_Blob | MEM_Str)) != 0); - bool is_neg; - int64_t i; - if (sql_atoi64(pMem->z, &i, &is_neg, pMem->n) == 0) { - mem_set_int(pMem, i, is_neg); - } else { - double v; - if (sqlVdbeRealValue(pMem, &v)) - return -1; - pMem->u.r = v; - MemSetTypeFlag(pMem, MEM_Real); - mem_apply_integer_type(pMem); - } + if ((mem->flags & (MEM_Int | MEM_UInt | MEM_Real | MEM_Null)) != 0) + return 0; + if ((mem->flags & MEM_Bool) != 0) { + mem->u.u = mem->u.b; + MemSetTypeFlag(mem, MEM_UInt); + return 0; + } + assert((mem->flags & (MEM_Blob | MEM_Str)) != 0); + bool is_neg; + int64_t i; + if (sql_atoi64(mem->z, &i, &is_neg, mem->n) == 0) { + mem_set_int(mem, i, is_neg); + } else { + if (sqlAtoF(mem->z, &mem->u.r, mem->n) == 0) + return -1; + MemSetTypeFlag(mem, MEM_Real); } - assert((pMem->flags & (MEM_Int | MEM_UInt | MEM_Real | MEM_Null)) != 0); - pMem->flags &= ~(MEM_Str | MEM_Blob | MEM_Zero); return 0; } @@ -1472,7 +1464,7 @@ valueFromExpr(sql * db, /* The database connection */ if (0 == sqlValueFromExpr(db, pExpr->pLeft, type, &pVal) && pVal != 0) { - if ((rc = sqlVdbeMemNumerify(pVal)) != 0) + if ((rc = vdbe_mem_numerify(pVal)) != 0) return rc; if (pVal->flags & MEM_Real) { pVal->u.r = -pVal->u.r; @@ -1499,7 +1491,7 @@ valueFromExpr(sql * db, /* The database connection */ pVal = valueNew(db, pCtx); if (pVal == 0) goto no_mem; - if ((rc = sqlVdbeMemNumerify(pVal)) != 0) + if ((rc = vdbe_mem_numerify(pVal)) != 0) return rc; } #ifndef SQL_OMIT_BLOB_LITERAL -- 2.15.1