[tarantool-patches] [PATCH 1/9] sql: refactor mem_apply_numeric_type()

Nikita Pettik korablev at tarantool.org
Sun Apr 14 18:03:59 MSK 2019


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





More information about the Tarantool-patches mailing list