Skip to content

Commit 3f74ba3

Browse files
vvellankipraveenbingo
authored andcommitted
GDV-87: Add support to print expressions (apache#63)
1 parent 9107a4b commit 3f74ba3

File tree

7 files changed

+162
-0
lines changed

7 files changed

+162
-0
lines changed

cpp/src/gandiva/codegen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ set(SRC_FILES annotator.cc
3333
llvm_types.cc
3434
projector.cc
3535
status.cc
36+
expression.cc
3637
tree_expr_builder.cc
3738
${BC_FILE_PATH_CC})
3839

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (C) 2017-2018 Dremio Corporation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "gandiva/expression.h"
16+
#include "codegen/node.h"
17+
18+
namespace gandiva {
19+
20+
std::string Expression::ToString() { return root()->ToString(); }
21+
22+
} // namespace gandiva

cpp/src/gandiva/codegen/expression.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class Expression {
3030

3131
const FieldPtr &result() const { return result_; }
3232

33+
std::string ToString();
34+
3335
private:
3436
const NodePtr root_;
3537
const FieldPtr result_;

cpp/src/gandiva/codegen/node.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class Node {
3838
/// Derived classes should simply invoke the Visit api of the visitor.
3939
virtual Status Accept(NodeVisitor &visitor) const = 0;
4040

41+
virtual std::string ToString() = 0;
42+
4143
protected:
4244
DataTypePtr return_type_;
4345
};
@@ -54,6 +56,16 @@ class LiteralNode : public Node {
5456

5557
bool is_null() const { return is_null_; }
5658

59+
std::string ToString() override {
60+
if (is_null()) {
61+
return std::string("null");
62+
}
63+
64+
std::stringstream ss;
65+
ss << holder();
66+
return ss.str();
67+
}
68+
5769
private:
5870
LiteralHolder holder_;
5971
bool is_null_;
@@ -68,6 +80,8 @@ class FieldNode : public Node {
6880

6981
const FieldPtr &field() const { return field_; }
7082

83+
std::string ToString() override { return field()->type()->name(); }
84+
7185
private:
7286
FieldPtr field_;
7387
};
@@ -84,6 +98,22 @@ class FunctionNode : public Node {
8498
const FuncDescriptorPtr &descriptor() const { return descriptor_; }
8599
const NodeVector &children() const { return children_; }
86100

101+
std::string ToString() override {
102+
std::stringstream ss;
103+
ss << descriptor()->return_type()->name() << " " << descriptor()->name() << "(";
104+
bool skip_comma = true;
105+
for (auto child : children()) {
106+
if (skip_comma) {
107+
ss << child->ToString();
108+
skip_comma = false;
109+
} else {
110+
ss << ", " << child->ToString();
111+
}
112+
}
113+
ss << ")";
114+
return ss.str();
115+
}
116+
87117
/// Make a function node with params types specified by 'children', and
88118
/// having return type ret_type.
89119
static NodePtr MakeFunction(const std::string &name, const NodeVector &children,
@@ -121,6 +151,14 @@ class IfNode : public Node {
121151
const NodePtr &then_node() const { return then_node_; }
122152
const NodePtr &else_node() const { return else_node_; }
123153

154+
std::string ToString() override {
155+
std::stringstream ss;
156+
ss << "if (" << condition()->ToString() << ") { ";
157+
ss << then_node()->ToString() << " } else { ";
158+
ss << else_node()->ToString() << " }";
159+
return ss.str();
160+
}
161+
124162
private:
125163
NodePtr condition_;
126164
NodePtr then_node_;
@@ -141,6 +179,18 @@ class BooleanNode : public Node {
141179

142180
const NodeVector &children() const { return children_; }
143181

182+
std::string ToString() override {
183+
std::stringstream ss;
184+
ss << children_.at(0)->ToString();
185+
if (expr_type() == BooleanNode::AND) {
186+
ss << " && ";
187+
} else {
188+
ss << " || ";
189+
}
190+
ss << children_.at(1)->ToString();
191+
return ss.str();
192+
}
193+
144194
private:
145195
ExprType expr_type_;
146196
NodeVector children_;

cpp/src/gandiva/codegen/tree_expr_builder.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,16 @@ NodePtr TreeExprBuilder::MakeOr(const NodeVector &children) {
112112
return std::make_shared<BooleanNode>(BooleanNode::OR, children);
113113
}
114114

115+
// set this to true to print expressions for debugging purposes
116+
static bool print_expr = false;
117+
115118
ExpressionPtr TreeExprBuilder::MakeExpression(NodePtr root_node, FieldPtr result_field) {
116119
if (result_field == nullptr) {
117120
return nullptr;
118121
}
122+
if (print_expr) {
123+
std::cout << "Expression: " << root_node->ToString() << "\n";
124+
}
119125
return ExpressionPtr(new Expression(root_node, result_field));
120126
}
121127

cpp/src/gandiva/integ/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ foreach(lib_type "shared" "static")
2424
add_gandiva_integ_test(binary_test.cc gandiva_${lib_type})
2525
add_gandiva_integ_test(date_time_test.cc gandiva_${lib_type})
2626
add_gandiva_integ_test(micro_benchmarks.cc gandiva_${lib_type})
27+
add_gandiva_integ_test(to_string_test.cc gandiva_${lib_type})
2728
endforeach(lib_type)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright (C) 2017-2018 Dremio Corporation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <gtest/gtest.h>
16+
#include <math.h>
17+
#include <time.h>
18+
#include "arrow/memory_pool.h"
19+
#include "gandiva/projector.h"
20+
#include "gandiva/tree_expr_builder.h"
21+
#include "integ/test_util.h"
22+
23+
namespace gandiva {
24+
25+
using arrow::boolean;
26+
using arrow::float64;
27+
using arrow::int32;
28+
using arrow::int64;
29+
30+
class TestToString : public ::testing::Test {
31+
public:
32+
void SetUp() { pool_ = arrow::default_memory_pool(); }
33+
34+
protected:
35+
arrow::MemoryPool* pool_;
36+
};
37+
38+
#define CHECK_EXPR_TO_STRING(e, str) EXPECT_STREQ(e->ToString().c_str(), str)
39+
40+
TEST_F(TestToString, TestAll) {
41+
auto literal_node = TreeExprBuilder::MakeLiteral((uint64_t)100);
42+
auto literal_expr =
43+
TreeExprBuilder::MakeExpression(literal_node, arrow::field("r", int64()));
44+
CHECK_EXPR_TO_STRING(literal_expr, "100");
45+
46+
auto f0 = arrow::field("f0", float64());
47+
auto f0_node = TreeExprBuilder::MakeField(f0);
48+
auto f0_expr = TreeExprBuilder::MakeExpression(f0_node, f0);
49+
CHECK_EXPR_TO_STRING(f0_expr, "double");
50+
51+
auto f1 = arrow::field("f1", int64());
52+
auto f2 = arrow::field("f2", int64());
53+
auto f1_node = TreeExprBuilder::MakeField(f1);
54+
auto f2_node = TreeExprBuilder::MakeField(f2);
55+
auto add_node = TreeExprBuilder::MakeFunction("add", {f1_node, f2_node}, int64());
56+
auto add_expr = TreeExprBuilder::MakeExpression(add_node, f1);
57+
CHECK_EXPR_TO_STRING(add_expr, "int64 add(int64, int64)");
58+
59+
auto cond_node = TreeExprBuilder::MakeFunction(
60+
"lesser_than", {f0_node, TreeExprBuilder::MakeLiteral((float)0)}, boolean());
61+
auto then_node = TreeExprBuilder::MakeField(f1);
62+
auto else_node = TreeExprBuilder::MakeField(f2);
63+
64+
auto if_node = TreeExprBuilder::MakeIf(cond_node, then_node, else_node, int64());
65+
auto if_expr = TreeExprBuilder::MakeExpression(if_node, f1);
66+
CHECK_EXPR_TO_STRING(if_expr,
67+
"if (bool lesser_than(double, 0)) { int64 } else { int64 }");
68+
69+
auto f1_gt_100 =
70+
TreeExprBuilder::MakeFunction("greater_than", {f1_node, literal_node}, boolean());
71+
auto f2_equals_100 =
72+
TreeExprBuilder::MakeFunction("equals", {f2_node, literal_node}, boolean());
73+
auto and_node = TreeExprBuilder::MakeAnd({f1_gt_100, f2_equals_100});
74+
auto and_expr =
75+
TreeExprBuilder::MakeExpression(and_node, arrow::field("f0", boolean()));
76+
CHECK_EXPR_TO_STRING(and_expr,
77+
"bool greater_than(int64, 100) && bool equals(int64, 100)");
78+
}
79+
80+
} // namespace gandiva

0 commit comments

Comments
 (0)