]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
1d09f67e
TL
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
27namespace 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
34MAKE_LITERAL(arrow::boolean(), bool)
35MAKE_LITERAL(arrow::int8(), int8_t)
36MAKE_LITERAL(arrow::int16(), int16_t)
37MAKE_LITERAL(arrow::int32(), int32_t)
38MAKE_LITERAL(arrow::int64(), int64_t)
39MAKE_LITERAL(arrow::uint8(), uint8_t)
40MAKE_LITERAL(arrow::uint16(), uint16_t)
41MAKE_LITERAL(arrow::uint32(), uint32_t)
42MAKE_LITERAL(arrow::uint64(), uint64_t)
43MAKE_LITERAL(arrow::float32(), float)
44MAKE_LITERAL(arrow::float64(), double)
45
46NodePtr TreeExprBuilder::MakeStringLiteral(const std::string& value) {
47 return std::make_shared<LiteralNode>(arrow::utf8(), LiteralHolder(value), false);
48}
49
50NodePtr TreeExprBuilder::MakeBinaryLiteral(const std::string& value) {
51 return std::make_shared<LiteralNode>(arrow::binary(), LiteralHolder(value), false);
52}
53
54NodePtr TreeExprBuilder::MakeDecimalLiteral(const DecimalScalar128& value) {
55 return std::make_shared<LiteralNode>(arrow::decimal(value.precision(), value.scale()),
56 LiteralHolder(value), false);
57}
58
59NodePtr 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
113NodePtr TreeExprBuilder::MakeField(FieldPtr field) {
114 return NodePtr(new FieldNode(field));
115}
116
117NodePtr 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
125NodePtr 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
134NodePtr TreeExprBuilder::MakeAnd(const NodeVector& children) {
135 return std::make_shared<BooleanNode>(BooleanNode::AND, children);
136}
137
138NodePtr 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
143static bool print_expr = false;
144
145ExpressionPtr 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
155ExpressionPtr 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
170ConditionPtr 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
181ConditionPtr 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
193NodePtr 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
211MAKE_IN(Int32, int32_t);
212MAKE_IN(Int64, int64_t);
213MAKE_IN(Date32, int32_t);
214MAKE_IN(Date64, int64_t);
215MAKE_IN(TimeStamp, int64_t);
216MAKE_IN(Time32, int32_t);
217MAKE_IN(Time64, int64_t);
218MAKE_IN(Float, float);
219MAKE_IN(Double, double);
220MAKE_IN(String, std::string);
221MAKE_IN(Binary, std::string);
222
223} // namespace gandiva