Skip to content

Commit 278a0fe

Browse files
authored
Fix float conversion (#65)
* fixing text to float convertion (ronen-fr #42) Signed-off-by: gal salomon <gal.salomon@gmail.com> * fix integer conversion; add compile-warning flag Signed-off-by: gal salomon <gal.salomon@gmail.com>
1 parent 465c6ff commit 278a0fe

File tree

3 files changed

+36
-26
lines changed

3 files changed

+36
-26
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
22

33
project(s3select)
44

5-
set(CMAKE_CXX_FLAGS "-std=gnu++17 -ggdb -Wnon-virtual-dtor -Wreorder -Wunused-variable")
5+
set(CMAKE_CXX_FLAGS "-std=gnu++17 -ggdb -Wnon-virtual-dtor -Wreorder -Wunused-variable -Wmaybe-uninitialized")
66
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
77
set(CMAKE_CXX_STANDARD_REQUIRED ON)
88

include/s3select_functions.h

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -556,42 +556,44 @@ struct _fn_max : public base_function
556556

557557
struct _fn_to_int : public base_function
558558
{
559-
560559
value var_result;
561-
value func_arg;
562560

563561
bool operator()(bs_stmt_vec_t* args, variable* result) override
564562
{
565-
char* perr;
566-
int64_t i=0;
567-
func_arg = (*args->begin())->eval();
563+
value v = (*args->begin())->eval();
568564

569-
if (func_arg.type == value::value_En_t::STRING)
565+
switch (v.type) {
566+
567+
case value::value_En_t::STRING:
570568
{
569+
char* pend;
571570
errno = 0;
572-
i = strtol(func_arg.str(), &perr, 10) ; //TODO check error before constructor
573-
if ((errno == ERANGE && (i == LONG_MAX || i == LONG_MIN)) || (errno != 0 && i == 0)) {
571+
int64_t i= strtol(v.str(), &pend, 10);
572+
if (errno == ERANGE) {
574573
throw base_s3select_exception("converted value would fall out of the range of the result type!");
575-
return false;
576-
}
577-
578-
if (*perr != '\0') {
579-
throw base_s3select_exception("characters after int!");
580-
return false;
581-
}
582-
}
583-
else if (func_arg.type == value::value_En_t::FLOAT)
584-
{
585-
i = func_arg.dbl();
586-
}
587-
else
588-
{
589-
i = func_arg.i64();
574+
}
575+
if (pend == v.str()) {
576+
// no number found
577+
throw base_s3select_exception("text cannot be converted to a number");
578+
}
579+
if (*pend) {
580+
throw base_s3select_exception("extra characters after the number");
581+
}
582+
583+
var_result = i;
590584
}
585+
break;
591586

592-
var_result = i ;
593-
*result = var_result;
587+
case value::value_En_t::FLOAT:
588+
var_result = static_cast<int64_t>(v.dbl());
589+
break;
594590

591+
default:
592+
var_result = v.i64();
593+
break;
594+
}
595+
596+
*result = var_result;
595597
return true;
596598
}
597599

test/s3select_test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3444,6 +3444,14 @@ TEST(TestS3selectFunctions, floatcast)
34443444
test_single_column_single_row("select cast('999e+999' as float) from s3object;","#failure#","converted value would fall out of the range of the result type!");
34453445
}
34463446

3447+
TEST(TestS3selectFunctions, intcast)
3448+
{
3449+
test_single_column_single_row("select cast('1234a' as int) from s3object;","#failure#","extra characters after the number");
3450+
test_single_column_single_row("select cast('a1234' as int) from s3object;","#failure#","text cannot be converted to a number");
3451+
test_single_column_single_row("select cast('9223372036854775808' as int) from s3object;","#failure#","converted value would fall out of the range of the result type!");
3452+
test_single_column_single_row("select cast('-9223372036854775809' as int) from s3object;","#failure#","converted value would fall out of the range of the result type!");
3453+
}
3454+
34473455
TEST(TestS3selectFunctions, predicate_as_projection_column)
34483456
{
34493457
std::string input;

0 commit comments

Comments
 (0)