242 std::stack<NodeRecord>
path;
243 auto isLeaf = [](
Node const*
const node) {
244 return ((node->left ==
nullptr) && (node->right ==
nullptr));
247 auto processLeaf = [](
Node const*
const node) {
258 while (!
path.empty()) {
264 [&](
auto const&
n) {
return makeOp(
n,
top.node_ptr->index); },
270 auto*
left =
top.node_ptr->left.get();
271 bool leftLeaf = isLeaf(
left);
274 operationSpec.left = processLeaf(
left);
281 if (
top.node_ptr->right !=
nullptr) {
284 bool rightLeaf =
true;
285 if (
right !=
nullptr) {
286 rightLeaf = isLeaf(
right);
289 auto isUnary =
false;
290 if (
top.node_ptr->right ==
nullptr) {
295 operationSpec.right = processLeaf(
right);
302 decltype(
left) condition =
nullptr;
303 if (
top.node_ptr->condition !=
nullptr) {
304 condition =
top.node_ptr->condition.get();
306 bool condleaf = condition !=
nullptr ? isLeaf(condition) :
true;
308 if (condition !=
nullptr) {
310 operationSpec.condition = processLeaf(condition);
319 OperationSpecs.push_back(std::move(operationSpec));
323 if (!isUnary && !rightLeaf) {
327 path.emplace(condition, ci);
332 std::vector<atype::type> resultTypes;
333 resultTypes.resize(OperationSpecs.size());
337 if (
left.datum.index() == 0) {
338 throw runtime_error(
"Malformed operation spec: empty left datum");
342 if (
left.datum.index() == 1) {
343 left.type = resultTypes[std::get<size_t>(
left.datum)];
346 if (
right.datum.index() == 1) {
347 right.type = resultTypes[std::get<size_t>(
right.datum)];
351 auto t2 =
right.type;
353 if (
right.datum.index() == 0) {
354 if (
t1 == atype::DOUBLE) {
355 return atype::DOUBLE;
364 auto isIntType = [](
auto t) {
365 return (t == atype::UINT8) || (t == atype::INT8) || (t == atype::UINT16) || (t == atype::INT16) || (t == atype::UINT32) || (t == atype::INT32) || (t == atype::UINT64) || (t == atype::INT64);
369 if (t2 == atype::FLOAT) {
372 if (t2 == atype::DOUBLE) {
373 return atype::DOUBLE;
382 if (
t1 == atype::FLOAT) {
386 if (t2 == atype::DOUBLE) {
387 return atype::DOUBLE;
390 if (
t1 == atype::DOUBLE) {
391 return atype::DOUBLE;
396 for (
auto it = OperationSpecs.rbegin(); it != OperationSpecs.rend(); ++it) {
397 auto type = inferResultType(it->left, it->right);
398 if (it->type == atype::NA) {
402 it->result.type = it->type;
403 resultTypes[std::get<size_t>(it->result.datum)] = it->type;
406 return OperationSpecs;
549 gandiva::SchemaPtr
const& Schema)
551 std::vector<gandiva::NodePtr> opNodes;
552 opNodes.resize(opSpecs.size());
553 std::fill(opNodes.begin(), opNodes.end(),
nullptr);
554 std::unordered_map<std::string, gandiva::NodePtr> fieldNodes;
555 std::unordered_map<size_t, gandiva::NodePtr> subtrees;
557 auto datumNode = [Schema, &opNodes, &fieldNodes](
DatumSpec const& spec) {
558 if (spec.datum.index() == 0) {
559 return gandiva::NodePtr(
nullptr);
561 if (spec.datum.index() == 1) {
562 return opNodes[std::get<size_t>(spec.datum)];
565 if (spec.datum.index() == 2) {
566 auto content = std::get<LiteralNode::var_t>(spec.datum);
567 switch (content.index()) {
569 return gandiva::TreeExprBuilder::MakeLiteral(
static_cast<int32_t
>(std::get<int>(content)));
571 return gandiva::TreeExprBuilder::MakeLiteral(std::get<bool>(content));
573 return gandiva::TreeExprBuilder::MakeLiteral(std::get<float>(content));
575 return gandiva::TreeExprBuilder::MakeLiteral(std::get<double>(content));
577 return gandiva::TreeExprBuilder::MakeLiteral(std::get<uint8_t>(content));
579 return gandiva::TreeExprBuilder::MakeLiteral(std::get<int64_t>(content));
581 return gandiva::TreeExprBuilder::MakeLiteral(std::get<int16_t>(content));
583 return gandiva::TreeExprBuilder::MakeLiteral(std::get<uint16_t>(content));
585 return gandiva::TreeExprBuilder::MakeLiteral(std::get<int8_t>(content));
587 return gandiva::TreeExprBuilder::MakeLiteral(std::get<uint32_t>(content));
589 return gandiva::TreeExprBuilder::MakeLiteral(std::get<uint64_t>(content));
595 if (spec.datum.index() == 3) {
596 auto name = std::get<std::string>(spec.datum);
598 if (
lookup != fieldNodes.end()) {
601 auto field = Schema->GetFieldByName(
name);
602 if (field ==
nullptr) {
605 auto node = gandiva::TreeExprBuilder::MakeField(field);
606 fieldNodes.insert({
name, node});
612 gandiva::NodePtr
tree =
nullptr;
613 for (
auto it = opSpecs.rbegin(); it != opSpecs.rend(); ++it) {
614 auto leftNode = datumNode(it->left);
615 auto rightNode = datumNode(it->right);
616 auto condNode = datumNode(it->condition);
618 auto insertUpcastNode = [](gandiva::NodePtr node, atype::type
t0, atype::type t) {
626 auto insertEqualizeUpcastNode = [](gandiva::NodePtr& node1, gandiva::NodePtr& node2, atype::type
t1, atype::type t2) {
630 }
else if (
t1 > t2) {
636 gandiva::NodePtr temp_node;
640 temp_node = gandiva::TreeExprBuilder::MakeOr({leftNode, rightNode});
643 temp_node = gandiva::TreeExprBuilder::MakeAnd({leftNode, rightNode});
646 temp_node = gandiva::TreeExprBuilder::MakeIf(condNode, leftNode, rightNode,
concreteArrowType(it->type));
650 if (it->type != atype::BOOL) {
651 leftNode = insertUpcastNode(leftNode, it->type, it->left.type);
652 rightNode = insertUpcastNode(rightNode, it->type, it->right.type);
654 insertEqualizeUpcastNode(leftNode, rightNode, it->left.type, it->right.type);
656 temp_node = gandiva::TreeExprBuilder::MakeFunction(basicOperationsMap[it->op], {leftNode, rightNode},
concreteArrowType(it->type));
658 leftNode = insertUpcastNode(leftNode, it->type, it->left.type);
659 temp_node = gandiva::TreeExprBuilder::MakeFunction(basicOperationsMap[it->op], {leftNode},
concreteArrowType(it->type));
663 if (it->index == 0) {
666 auto subtree = subtrees.find(it->index);
667 if (subtree == subtrees.end()) {
668 subtrees.insert({it->index, temp_node});
670 subtree->second = temp_node;
673 opNodes[std::get<size_t>(it->result.datum)] = temp_node;