Skip to content

Commit 051a52f

Browse files
committed
marking subtree as runnable; changes to execution flow to support correct execution of nested&complex aggregation queries
Signed-off-by: gal salomon <gal.salomon@gmail.com>
1 parent ba58b66 commit 051a52f

File tree

4 files changed

+65
-11
lines changed

4 files changed

+65
-11
lines changed

include/s3select.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,10 @@ struct s3select : public bsc::grammar<s3select>
400400

401401
if (aggregate_expr)
402402
{
403-
//per each column, subtree is mark to skip,
404-
//the second code-line marks the aggregation subtree not-to-skip.
403+
//per each column, subtree is mark to skip except for the aggregation function subtree.
405404
//for an example: substring( ... , sum() , count() ) :: the substring is mark to skip execution, while sum and count not.
406405
e->set_skip_non_aggregate(true);
407-
aggregate_expr->set_skip_non_aggregate(false);
406+
e->mark_aggreagtion_subtree_to_execute();
408407
}
409408
else
410409
{
@@ -1490,6 +1489,7 @@ class csv_object : public base_s3object
14901489
for (auto& i : m_projections)
14911490
{
14921491
i->set_last_call();
1492+
i->set_skip_non_aggregate(false);//projection column is set to be runnable
14931493
result.append( i->eval().to_string() );
14941494
result.append(",");
14951495
}

include/s3select_functions.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ class __function : public base_statement
216216
__function(const char* fname, s3select_functions* s3f) : name(fname), m_func_impl(nullptr), m_s3select_functions(s3f) {}
217217

218218
virtual value& eval()
219+
{
220+
return eval_internal();
221+
}
222+
223+
virtual value& eval_internal()
219224
{
220225

221226
_resolve_name();
@@ -1704,6 +1709,29 @@ bool base_statement::is_nested_aggregate(bool &aggr_flow)
17041709
return false;
17051710
}
17061711

1712+
bool base_statement::mark_aggreagtion_subtree_to_execute()
1713+
{//purpase:: set aggregation subtree as runnable.
1714+
//the function search for aggregation function, and mark its subtree {skip = false}
1715+
if (is_aggregate())
1716+
set_skip_non_aggregate(false);
1717+
1718+
if (left())
1719+
left()->mark_aggreagtion_subtree_to_execute();
1720+
1721+
if(right())
1722+
right()->mark_aggreagtion_subtree_to_execute();
1723+
1724+
if (is_function())
1725+
{
1726+
for (auto& i : dynamic_cast<__function*>(this)->get_arguments())
1727+
{
1728+
i->mark_aggreagtion_subtree_to_execute();
1729+
}
1730+
}
1731+
1732+
return true;
1733+
}
1734+
17071735
} //namespace s3selectEngine
17081736

17091737
#endif

include/s3select_oper.h

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -920,12 +920,37 @@ class base_statement
920920
base_statement* m_projection_alias;
921921
int m_eval_stack_depth;
922922
bool m_skip_non_aggregate_op;
923+
value value_na;
923924

924925
public:
925926
base_statement():m_scratch(nullptr), is_last_call(false), m_is_cache_result(false),
926927
m_projection_alias(nullptr), m_eval_stack_depth(0), m_skip_non_aggregate_op(false) {}
927928

928-
virtual value& eval() =0;
929+
virtual value& eval()
930+
{
931+
//purpose: on aggregation flow to run only the correct subtree(aggregation subtree)
932+
933+
if (m_skip_non_aggregate_op == false)
934+
return eval_internal();//not skipping this node.
935+
else
936+
{
937+
//skipping this node.
938+
//in case execution should skip a node, it will traverse (left and right)
939+
//and search for subtree to execute.
940+
//example: sum( ... ) - sum( ... ) ; the minus operand is skipped while sum() operand is not.
941+
if(left())
942+
left()->eval_internal();
943+
944+
if(right())
945+
right()->eval_internal();
946+
947+
}
948+
949+
return value_na;
950+
}
951+
952+
virtual value& eval_internal() = 0;
953+
929954
virtual base_statement* left()
930955
{
931956
return 0;
@@ -978,6 +1003,7 @@ class base_statement
9781003
base_statement* get_aggregate();
9791004
bool is_nested_aggregate(bool&);
9801005
bool is_column_reference();
1006+
bool mark_aggreagtion_subtree_to_execute();
9811007

9821008
virtual void set_last_call()
9831009
{
@@ -1211,7 +1237,7 @@ class variable : public base_statement
12111237
return var_value;
12121238
}
12131239

1214-
virtual value& eval()
1240+
virtual value& eval_internal()
12151241
{
12161242
if (m_var_type == var_t::COL_VALUE)
12171243
{
@@ -1326,7 +1352,7 @@ class arithmetic_operand : public base_statement
13261352
return std::string("#");//TBD
13271353
}
13281354

1329-
virtual value& eval()
1355+
virtual value& eval_internal()
13301356
{
13311357

13321358
switch (_cmp)
@@ -1425,7 +1451,7 @@ class logical_operand : public base_statement
14251451
//return out;
14261452
return std::string("#");//TBD
14271453
}
1428-
virtual value& eval()
1454+
virtual value& eval_internal()
14291455
{
14301456
bool res;
14311457
if (!l || !r)
@@ -1503,7 +1529,7 @@ class mulldiv_operation : public base_statement
15031529
return std::string("#");//TBD
15041530
}
15051531

1506-
virtual value& eval()
1532+
virtual value& eval_internal()
15071533
{
15081534
switch (_mulldiv)
15091535
{
@@ -1579,7 +1605,7 @@ class addsub_operation : public base_statement
15791605
return std::string("#");//TBD
15801606
}
15811607

1582-
virtual value& eval()
1608+
virtual value& eval_internal()
15831609
{
15841610
if (_op == addsub_op_t::NA) // -num , +num , unary-operation on number
15851611
{
@@ -1633,7 +1659,7 @@ class negate_function_operation : public base_statement
16331659
return function_to_negate;
16341660
}
16351661

1636-
virtual value& eval()
1662+
virtual value& eval_internal()
16371663
{
16381664
res = function_to_negate->eval();
16391665

test/s3select_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2352,7 +2352,7 @@ TEST(TestS3selectFunctions, nested_call_aggregate_with_non_aggregate)
23522352
//purpose: test projections with aggregation functions, in mix of nested calls.
23532353
s3select s3select_syntax;
23542354

2355-
const std::string input_query = "select substring('abcdefghijklm',(2-1)*3+sum(cast(_1 as int))*0+1,2*count(0)/count(0)) ,count(0),sum(cast(_1 as int))*0 from stdin;";
2355+
const std::string input_query = "select substring('abcdefghijklm',(2-1)*3+sum(cast(_1 as int))*0+1,(count() + count(0))/count(0)) ,count(0),(sum(cast(_1 as int))*min(cast(_2 as int)))*0 from stdin;";
23562356

23572357
auto status = s3select_syntax.parse_query(input_query.c_str());
23582358
ASSERT_EQ(status, 0);

0 commit comments

Comments
 (0)