[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