Skip to content
This repository has been archived by the owner on Dec 1, 2022. It is now read-only.

Fix toInteger() #595

Merged
merged 4 commits into from
Jul 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/common/datatypes/Value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1595,7 +1595,7 @@ Value Value::toFloat() const {
}
case Value::Type::STRING: {
const auto& str = getStr();
char *pEnd;
char* pEnd;
double val = strtod(str.c_str(), &pEnd);
if (*pEnd != '\0') {
return Value::kNullValue;
Expand Down Expand Up @@ -1629,12 +1629,23 @@ Value Value::toInt() const {
}
case Value::Type::STRING: {
const auto& str = getStr();
char *pEnd;
double val = strtod(str.c_str(), &pEnd);
errno = 0;
char* pEnd;
auto it = std::find(str.begin(), str.end(), '.');
int64_t val =
(it == str.end())
? int64_t(strtoll(str.c_str(), &pEnd, 10)) // string representing int
: int64_t(strtod(str.c_str(), &pEnd)); // string representing double
if (*pEnd != '\0') {
return Value::kNullValue;
}
return static_cast<int64_t>(val);
// Check overflow
if ((val == std::numeric_limits<int64_t>::max() ||
val == std::numeric_limits<int64_t>::min()) &&
errno == ERANGE) {
return kNullOverflow;
}
return val;
}
default: {
return Value::kNullBadType;
Expand Down
166 changes: 116 additions & 50 deletions src/common/datatypes/test/ValueTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,76 +638,142 @@ TEST(Value, TypeCast) {
EXPECT_EQ(Value::Type::NULLVALUE, vb8.type());
}
{
auto vf1 = vInt.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf1.type());
EXPECT_EQ(vf1.getFloat(), 1.0);
auto vf = vInt.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), 1.0);

auto vf2 = vFloat.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf2.type());
EXPECT_EQ(vf2.getFloat(), 3.14);
vf = vFloat.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), 3.14);

auto vf3 = vStr1.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf3.type());
vf = vStr1.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf.type());

auto vf4 = vStr2.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf4.type());
EXPECT_EQ(vf4.getFloat(), 3.14);
vf = vStr2.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), 3.14);

auto vf5 = vBool1.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf5.type());
vf = vBool1.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf.type());

auto vf6 = vBool2.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf6.type());
vf = vBool2.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf.type());

auto vf7 = vDate.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf7.type());
vf = vDate.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf.type());

auto vf8 = vNull.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf8.type());
vf = vNull.toFloat();
EXPECT_EQ(Value::Type::NULLVALUE, vf.type());

auto vf9 = vIntMin.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf9.type());
EXPECT_EQ(vf9.getFloat(), std::numeric_limits<int64_t>::min());
vf = vIntMin.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), std::numeric_limits<int64_t>::min());

auto vf10 = vIntMax.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf10.type());
EXPECT_EQ(vf10.getFloat(), std::numeric_limits<int64_t>::max());
vf = vIntMax.toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), static_cast<double>(std::numeric_limits<int64_t>::max()));

// String of int
vf = Value("-9223372036854775807").toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), static_cast<double>(std::numeric_limits<int64_t>::min() + 1));

vf = Value("-9223372036854775808")
.toFloat(); // will be converted to -9223372036854776000.0
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), static_cast<double>(std::numeric_limits<int64_t>::min()));

vf = Value("9223372036854775807").toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), static_cast<double>(std::numeric_limits<int64_t>::max()));

// String of double
vf = Value("123.").toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), 123.0);

vf = Value(std::to_string(std::numeric_limits<double_t>::max())).toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), std::numeric_limits<double_t>::max());

vf = Value(std::to_string(std::numeric_limits<double_t>::max())).toFloat();
EXPECT_EQ(Value::Type::FLOAT, vf.type());
EXPECT_EQ(vf.getFloat(), std::numeric_limits<double_t>::max());

// Invlaid string
vf = Value("12abc").toFloat();
EXPECT_EQ(Value::kNullValue, vf);

vf = Value("1.2abc").toFloat();
EXPECT_EQ(Value::kNullValue, vf);
}
{
auto vi1 = vInt.toInt();
EXPECT_EQ(Value::Type::INT, vi1.type());
EXPECT_EQ(vi1.getInt(), 1);
auto vi = vInt.toInt();
EXPECT_EQ(Value::Type::INT, vi.type());
EXPECT_EQ(vi.getInt(), 1);

vi = vFloat.toInt();
EXPECT_EQ(Value::Type::INT, vi.type());
EXPECT_EQ(vi.getInt(), 3);

vi = vStr1.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi.type());

vi = vStr2.toInt();

EXPECT_EQ(Value::Type::INT, vi.type());
EXPECT_EQ(vi.getInt(), 3);

vi = vBool1.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi.type());

vi = vBool2.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi.type());

vi = vDate.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi.type());

vi = vNull.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi.type());

vi = vFloatMin.toInt();
EXPECT_EQ(Value::Type::INT, vi.type());
EXPECT_EQ(vi.getInt(), std::numeric_limits<int64_t>::min());

auto vi2 = vFloat.toInt();
EXPECT_EQ(Value::Type::INT, vi2.type());
EXPECT_EQ(vi2.getInt(), 3);
vi = vFloatMax.toInt();
EXPECT_EQ(Value::Type::INT, vi.type());
EXPECT_EQ(vi.getInt(), std::numeric_limits<int64_t>::max());

auto vi3 = vStr1.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi3.type());
// string of int
vi = Value("123.").toInt();
EXPECT_EQ(Value::Type::INT, vi.type());
EXPECT_EQ(vi.getInt(), 123);

auto vi4 = vStr2.toInt();
EXPECT_EQ(Value::Type::INT, vi4.type());
EXPECT_EQ(vi4.getInt(), 3);
vi = Value("-9223372036854775807").toInt();
EXPECT_EQ(Value::Type::INT, vi.type());
EXPECT_EQ(vi.getInt(), std::numeric_limits<int64_t>::min() + 1);

auto vi5 = vBool1.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi5.type());
vi = Value("-9223372036854775808").toInt();
EXPECT_EQ(Value::Type::INT, vi.type());
EXPECT_EQ(vi.getInt(), std::numeric_limits<int64_t>::min());

auto vi6 = vBool2.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi6.type());
vi = Value("9223372036854775807").toInt();
EXPECT_EQ(Value::Type::INT, vi.type());
EXPECT_EQ(vi.getInt(), std::numeric_limits<int64_t>::max());

auto vi7 = vDate.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi7.type());
// String to int Overflow
vi = Value("9223372036854775808").toInt();
EXPECT_EQ(Value::kNullOverflow, vi);

auto vi8 = vNull.toInt();
EXPECT_EQ(Value::Type::NULLVALUE, vi8.type());
vi = Value("-9223372036854775809").toInt();
EXPECT_EQ(Value::kNullOverflow, vi);

auto vi9 = vFloatMin.toInt();
EXPECT_EQ(Value::Type::INT, vi9.type());
EXPECT_EQ(vi9.getInt(), std::numeric_limits<int64_t>::min());
// Invlaid string
vi = Value("12abc").toInt();
EXPECT_EQ(Value::kNullValue, vi);

auto vi10 = vFloatMax.toInt();
EXPECT_EQ(Value::Type::INT, vi10.type());
EXPECT_EQ(vi10.getInt(), std::numeric_limits<int64_t>::max());
vi = Value("1.2abc").toInt();
EXPECT_EQ(Value::kNullValue, vi);
}
}

Expand Down