Skip to content

Commit

Permalink
fixing text to float convertion (ronen-fr #42) (#64)
Browse files Browse the repository at this point in the history
Signed-off-by: gal salomon <[email protected]>
  • Loading branch information
galsalomon66 authored Feb 21, 2021
1 parent 73100a3 commit 465c6ff
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 25 deletions.
49 changes: 25 additions & 24 deletions include/s3select_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -599,42 +599,43 @@ struct _fn_to_int : public base_function

struct _fn_to_float : public base_function
{

value var_result;
value v_from;

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

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

case value::value_En_t::STRING:
{
errno = 0;
d = strtod(v.str(), &perr) ; //TODO check error before constructor
if ((errno == ERANGE && (d == LONG_MAX || d == LONG_MIN)) || (errno != 0 && d == 0)) {
char* pend;
double d = strtod(v.str(), &pend);
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 float!");
return false;
}
}
else if (v.type == value::value_En_t::FLOAT)
{
d = v.dbl();
}
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 = d;
}
else
{
d = v.i64();
break;

case value::value_En_t::FLOAT:
var_result = v.dbl();
break;

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

var_result = d;
*result = var_result;

return true;
}

Expand Down
20 changes: 19 additions & 1 deletion test/s3select_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ int count_string(std::string in,std::string substr)
}


void test_single_column_single_row(const char* input_query,const char* expected_result)
void test_single_column_single_row(const char* input_query,const char* expected_result,const char * error_description = 0)
{
s3select s3select_syntax;
auto status = s3select_syntax.parse_query(input_query);
Expand All @@ -704,6 +704,17 @@ void test_single_column_single_row(const char* input_query,const char* expected_
false, // dont skip last line
true // aggregate call
);

if(strcmp(expected_result,"#failure#") == 0)
{
if (status==0 && s3select_result.compare("#failure#")==0)
{
ASSERT_TRUE(0);
}
ASSERT_EQ(s3_csv_object.get_error_description(),error_description);
return;
}

ASSERT_EQ(status, 0);
ASSERT_EQ(s3select_result, std::string(expected_result));
}
Expand Down Expand Up @@ -3426,6 +3437,13 @@ TEST(TestS3selectFunctions, boolcast)
test_single_column_single_row("select cast('a' as bool) from s3object;","false,\n");
}

TEST(TestS3selectFunctions, floatcast)
{
test_single_column_single_row("select cast('1234a' as float) from s3object;","#failure#","extra characters after the number");
test_single_column_single_row("select cast('a1234' as float) from s3object;","#failure#","text cannot be converted to a number");
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, predicate_as_projection_column)
{
std::string input;
Expand Down

0 comments on commit 465c6ff

Please sign in to comment.