Skip to content

Commit

Permalink
Fix float conversion (#65)
Browse files Browse the repository at this point in the history
* fixing text to float convertion (ronen-fr #42)

Signed-off-by: gal salomon <[email protected]>

* fix integer conversion; add compile-warning flag

Signed-off-by: gal salomon <[email protected]>
  • Loading branch information
galsalomon66 authored Feb 22, 2021
1 parent 465c6ff commit 278a0fe
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 26 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)

project(s3select)

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

Expand Down
52 changes: 27 additions & 25 deletions include/s3select_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,42 +556,44 @@ struct _fn_max : public base_function

struct _fn_to_int : public base_function
{

value var_result;
value func_arg;

bool operator()(bs_stmt_vec_t* args, variable* result) override
{
char* perr;
int64_t i=0;
func_arg = (*args->begin())->eval();
value v = (*args->begin())->eval();

if (func_arg.type == value::value_En_t::STRING)
switch (v.type) {

case value::value_En_t::STRING:
{
char* pend;
errno = 0;
i = strtol(func_arg.str(), &perr, 10) ; //TODO check error before constructor
if ((errno == ERANGE && (i == LONG_MAX || i == LONG_MIN)) || (errno != 0 && i == 0)) {
int64_t i= strtol(v.str(), &pend, 10);
if (errno == ERANGE) {
throw base_s3select_exception("converted value would fall out of the range of the result type!");
return false;
}

if (*perr != '\0') {
throw base_s3select_exception("characters after int!");
return false;
}
}
else if (func_arg.type == value::value_En_t::FLOAT)
{
i = func_arg.dbl();
}
else
{
i = func_arg.i64();
}
if (pend == v.str()) {
// no number found
throw base_s3select_exception("text cannot be converted to a number");
}
if (*pend) {
throw base_s3select_exception("extra characters after the number");
}

var_result = i;
}
break;

var_result = i ;
*result = var_result;
case value::value_En_t::FLOAT:
var_result = static_cast<int64_t>(v.dbl());
break;

default:
var_result = v.i64();
break;
}

*result = var_result;
return true;
}

Expand Down
8 changes: 8 additions & 0 deletions test/s3select_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3444,6 +3444,14 @@ TEST(TestS3selectFunctions, floatcast)
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!");
}

TEST(TestS3selectFunctions, intcast)
{
test_single_column_single_row("select cast('1234a' as int) from s3object;","#failure#","extra characters after the number");
test_single_column_single_row("select cast('a1234' as int) from s3object;","#failure#","text cannot be converted to a number");
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!");
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!");
}

TEST(TestS3selectFunctions, predicate_as_projection_column)
{
std::string input;
Expand Down

0 comments on commit 278a0fe

Please sign in to comment.