From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id EECDA2BBBF for ; Sun, 14 Apr 2019 11:04:13 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DI7T-F4C6luh for ; Sun, 14 Apr 2019 11:04:13 -0400 (EDT) Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 221482BB6E for ; Sun, 14 Apr 2019 11:04:13 -0400 (EDT) From: Nikita Pettik Subject: [tarantool-patches] [PATCH 1/9] sql: refactor mem_apply_numeric_type() Date: Sun, 14 Apr 2019 18:03:59 +0300 Message-Id: In-Reply-To: References: In-Reply-To: References: Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Cc: v.shpilevoy@tarantool.org, kostja@tarantool.org, Nikita Pettik Fix codestyle according to Tarantool guideline; remove unused argument from signature; make function non-static - we are going to use it in aggregate function sum() (src/box/sql/func.c) to attempt at converting string values to numbers. --- src/box/sql/vdbe.c | 49 +++++++++++++++++-------------------------------- src/box/sql/vdbeInt.h | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index ed7bf8870..1b3e2a59d 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; @@ -2196,12 +2181,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), @@ -3550,7 +3535,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 c84f22caf..8cd00d43a 100644 --- a/src/box/sql/vdbeInt.h +++ b/src/box/sql/vdbeInt.h @@ -269,6 +269,21 @@ 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 only on memory cell containing string, + * i.e. memory->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. */ -- 2.15.1