]> git.proxmox.com Git - ceph.git/blob - ceph/src/arrow/cpp/src/gandiva/tree_expr_builder.cc
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / cpp / src / gandiva / tree_expr_builder.cc
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17
18 #include "gandiva/tree_expr_builder.h"
19
20 #include <iostream>
21 #include <utility>
22
23 #include "gandiva/decimal_type_util.h"
24 #include "gandiva/gandiva_aliases.h"
25 #include "gandiva/node.h"
26
27 namespace gandiva {
28
29 #define MAKE_LITERAL(atype, ctype) \
30 NodePtr TreeExprBuilder::MakeLiteral(ctype value) { \
31 return std::make_shared<LiteralNode>(atype, LiteralHolder(value), false); \
32 }
33
34 MAKE_LITERAL(arrow::boolean(), bool)
35 MAKE_LITERAL(arrow::int8(), int8_t)
36 MAKE_LITERAL(arrow::int16(), int16_t)
37 MAKE_LITERAL(arrow::int32(), int32_t)
38 MAKE_LITERAL(arrow::int64(), int64_t)
39 MAKE_LITERAL(arrow::uint8(), uint8_t)
40 MAKE_LITERAL(arrow::uint16(), uint16_t)
41 MAKE_LITERAL(arrow::uint32(), uint32_t)
42 MAKE_LITERAL(arrow::uint64(), uint64_t)
43 MAKE_LITERAL(arrow::float32(), float)
44 MAKE_LITERAL(arrow::float64(), double)
45
46 NodePtr TreeExprBuilder::MakeStringLiteral(const std::string& value) {
47 return std::make_shared<LiteralNode>(arrow::utf8(), LiteralHolder(value), false);
48 }
49
50 NodePtr TreeExprBuilder::MakeBinaryLiteral(const std::string& value) {
51 return std::make_shared<LiteralNode>(arrow::binary(), LiteralHolder(value), false);
52 }
53
54 NodePtr TreeExprBuilder::MakeDecimalLiteral(const DecimalScalar128& value) {
55 return std::make_shared<LiteralNode>(arrow::decimal(value.precision(), value.scale()),
56 LiteralHolder(value), false);
57 }
58
59 NodePtr TreeExprBuilder::MakeNull(DataTypePtr data_type) {
60 static const std::string empty;
61
62 if (data_type == nullptr) {
63 return nullptr;
64 }
65
66 switch (data_type->id()) {
67 case arrow::Type::BOOL:
68 return std::make_shared<LiteralNode>(data_type, LiteralHolder(false), true);
69 case arrow::Type::INT8:
70 return std::make_shared<LiteralNode>(data_type, LiteralHolder((int8_t)0), true);
71 case arrow::Type::INT16:
72 return std::make_shared<LiteralNode>(data_type, LiteralHolder((int16_t)0), true);
73 return std::make_shared<LiteralNode>(data_type, LiteralHolder((int32_t)0), true);
74 case arrow::Type::UINT8:
75 return std::make_shared<LiteralNode>(data_type, LiteralHolder((uint8_t)0), true);
76 case arrow::Type::UINT16:
77 return std::make_shared<LiteralNode>(data_type, LiteralHolder((uint16_t)0), true);
78 case arrow::Type::UINT32:
79 return std::make_shared<LiteralNode>(data_type, LiteralHolder((uint32_t)0), true);
80 case arrow::Type::UINT64:
81 return std::make_shared<LiteralNode>(data_type, LiteralHolder((uint64_t)0), true);
82 case arrow::Type::FLOAT:
83 return std::make_shared<LiteralNode>(data_type,
84 LiteralHolder(static_cast<float>(0)), true);
85 case arrow::Type::DOUBLE:
86 return std::make_shared<LiteralNode>(data_type,
87 LiteralHolder(static_cast<double>(0)), true);
88 case arrow::Type::STRING:
89 case arrow::Type::BINARY:
90 return std::make_shared<LiteralNode>(data_type, LiteralHolder(empty), true);
91 case arrow::Type::INT32:
92 case arrow::Type::DATE32:
93 case arrow::Type::TIME32:
94 case arrow::Type::INTERVAL_MONTHS:
95 return std::make_shared<LiteralNode>(data_type, LiteralHolder((int32_t)0), true);
96 case arrow::Type::INT64:
97 case arrow::Type::DATE64:
98 case arrow::Type::TIME64:
99 case arrow::Type::TIMESTAMP:
100 case arrow::Type::INTERVAL_DAY_TIME:
101 return std::make_shared<LiteralNode>(data_type, LiteralHolder((int64_t)0), true);
102 case arrow::Type::DECIMAL: {
103 std::shared_ptr<arrow::DecimalType> decimal_type =
104 arrow::internal::checked_pointer_cast<arrow::DecimalType>(data_type);
105 DecimalScalar128 literal(decimal_type->precision(), decimal_type->scale());
106 return std::make_shared<LiteralNode>(data_type, LiteralHolder(literal), true);
107 }
108 default:
109 return nullptr;
110 }
111 }
112
113 NodePtr TreeExprBuilder::MakeField(FieldPtr field) {
114 return NodePtr(new FieldNode(field));
115 }
116
117 NodePtr TreeExprBuilder::MakeFunction(const std::string& name, const NodeVector& params,
118 DataTypePtr result_type) {
119 if (result_type == nullptr) {
120 return nullptr;
121 }
122 return std::make_shared<FunctionNode>(name, params, result_type);
123 }
124
125 NodePtr TreeExprBuilder::MakeIf(NodePtr condition, NodePtr then_node, NodePtr else_node,
126 DataTypePtr result_type) {
127 if (condition == nullptr || then_node == nullptr || else_node == nullptr ||
128 result_type == nullptr) {
129 return nullptr;
130 }
131 return std::make_shared<IfNode>(condition, then_node, else_node, result_type);
132 }
133
134 NodePtr TreeExprBuilder::MakeAnd(const NodeVector& children) {
135 return std::make_shared<BooleanNode>(BooleanNode::AND, children);
136 }
137
138 NodePtr TreeExprBuilder::MakeOr(const NodeVector& children) {
139 return std::make_shared<BooleanNode>(BooleanNode::OR, children);
140 }
141
142 // set this to true to print expressions for debugging purposes
143 static bool print_expr = false;
144
145 ExpressionPtr TreeExprBuilder::MakeExpression(NodePtr root_node, FieldPtr result_field) {
146 if (result_field == nullptr) {
147 return nullptr;
148 }
149 if (print_expr) {
150 std::cout << "Expression: " << root_node->ToString() << "\n";
151 }
152 return ExpressionPtr(new Expression(root_node, result_field));
153 }
154
155 ExpressionPtr TreeExprBuilder::MakeExpression(const std::string& function,
156 const FieldVector& in_fields,
157 FieldPtr out_field) {
158 if (out_field == nullptr) {
159 return nullptr;
160 }
161 std::vector<NodePtr> field_nodes;
162 for (auto& field : in_fields) {
163 auto node = MakeField(field);
164 field_nodes.push_back(node);
165 }
166 auto func_node = MakeFunction(function, field_nodes, out_field->type());
167 return MakeExpression(func_node, out_field);
168 }
169
170 ConditionPtr TreeExprBuilder::MakeCondition(NodePtr root_node) {
171 if (root_node == nullptr) {
172 return nullptr;
173 }
174 if (print_expr) {
175 std::cout << "Condition: " << root_node->ToString() << "\n";
176 }
177
178 return ConditionPtr(new Condition(root_node));
179 }
180
181 ConditionPtr TreeExprBuilder::MakeCondition(const std::string& function,
182 const FieldVector& in_fields) {
183 std::vector<NodePtr> field_nodes;
184 for (auto& field : in_fields) {
185 auto node = MakeField(field);
186 field_nodes.push_back(node);
187 }
188
189 auto func_node = MakeFunction(function, field_nodes, arrow::boolean());
190 return ConditionPtr(new Condition(func_node));
191 }
192
193 NodePtr TreeExprBuilder::MakeInExpressionDecimal(
194 NodePtr node, std::unordered_set<gandiva::DecimalScalar128>& constants) {
195 int32_t precision = 0;
196 int32_t scale = 0;
197 if (!constants.empty()) {
198 precision = constants.begin()->precision();
199 scale = constants.begin()->scale();
200 }
201 return std::make_shared<InExpressionNode<gandiva::DecimalScalar128>>(node, constants,
202 precision, scale);
203 }
204
205 #define MAKE_IN(NAME, ctype) \
206 NodePtr TreeExprBuilder::MakeInExpression##NAME( \
207 NodePtr node, const std::unordered_set<ctype>& values) { \
208 return std::make_shared<InExpressionNode<ctype>>(node, values); \
209 }
210
211 MAKE_IN(Int32, int32_t);
212 MAKE_IN(Int64, int64_t);
213 MAKE_IN(Date32, int32_t);
214 MAKE_IN(Date64, int64_t);
215 MAKE_IN(TimeStamp, int64_t);
216 MAKE_IN(Time32, int32_t);
217 MAKE_IN(Time64, int64_t);
218 MAKE_IN(Float, float);
219 MAKE_IN(Double, double);
220 MAKE_IN(String, std::string);
221 MAKE_IN(Binary, std::string);
222
223 } // namespace gandiva