11#ifndef O2_FRAMEWORK_EXPRESSIONS_H_
12#define O2_FRAMEWORK_EXPRESSIONS_H_
21#include <arrow/type_fwd.h>
22#include <gandiva/gandiva_aliases.h>
23#include <arrow/type.h>
24#include <gandiva/arrow.h>
25#if !defined(__CLING__) && !defined(__ROOTCLING__)
26#include <arrow/table.h>
27#include <gandiva/selection_vector.h>
28#include <gandiva/node.h>
29#include <gandiva/filter.h>
30#include <gandiva/projector.h>
46using Selection = std::shared_ptr<gandiva::SelectionVector>;
52 ExpressionInfo(
int ai,
size_t hash, std::set<uint32_t>&& hs, gandiva::SchemaPtr sc)
63 gandiva::NodePtr
tree =
nullptr;
74template <
typename... T>
80using LiteralValue =
LiteralStorage<int, bool, float, double, uint8_t, int64_t, int16_t, uint16_t, int8_t, uint32_t, uint64_t>;
88#define SELECT_ARROW_TYPE(_Ctype_, _Atype_) \
89 template <typename T> \
90 requires std::same_as<T, _Ctype_> \
91 constexpr auto selectArrowType() \
93 return atype::_Atype_; \
113 template <
typename T>
144 template <
typename T>
151 template <
typename T,
typename AT>
169template <
typename AT,
typename T>
185 template <
typename T>
186 void reset(T value_,
int index_ = -1)
203concept is_literal_like = std::same_as<T, LiteralNode> || std::same_as<T, PlaceholderNode> || std::same_as<T, ParameterNode>;
258 if (
other.left !=
nullptr) {
259 left = std::make_unique<Node>(*
other.left);
261 if (
other.right !=
nullptr) {
264 if (
other.condition !=
nullptr) {
270 using self_t = std::variant<LiteralNode, BindingNode, OpNode, PlaceholderNode, ConditionalNode, ParameterNode>;
274 std::unique_ptr<Node>
left =
nullptr;
275 std::unique_ptr<Node>
right =
nullptr;
287 return this->node_ptr != rhs.node_ptr;
295 std::stack<NodeRecord>
path;
296 path.emplace(head, 0);
297 while (!
path.empty()) {
301 auto* leftp =
top.node_ptr->left.get();
302 auto* rightp =
top.node_ptr->right.get();
303 auto* condp =
top.node_ptr->condition.get();
306 if (leftp !=
nullptr) {
307 path.emplace(leftp, 0);
309 if (rightp !=
nullptr) {
310 path.emplace(rightp, 0);
312 if (condp !=
nullptr) {
313 path.emplace(condp, 0);
320#define BINARY_OP_NODES(_operator_, _operation_) \
321 inline Node operator _operator_(Node&& left, Node&& right) \
323 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), std::forward<Node>(right)}; \
325 template <typename T> \
326 inline Node operator _operator_(Node&& left, T right) requires(std::is_arithmetic_v<std::decay_t<T>>) \
328 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), LiteralNode{right}}; \
330 template <typename T> \
331 inline Node operator _operator_(T left, Node&& right) requires(std::is_arithmetic_v<std::decay_t<T>>) \
333 return Node{OpNode{BasicOp::_operation_}, LiteralNode{left}, std::forward<Node>(right)}; \
335 template <typename T> \
336 inline Node operator _operator_(Node&& left, Configurable<T> const& right) \
338 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), PlaceholderNode{right}}; \
340 template <typename T> \
341 inline Node operator _operator_(Configurable<T> const& left, Node&& right) \
343 return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, std::forward<Node>(right)}; \
345 inline Node operator _operator_(BindingNode const& left, BindingNode const& right) \
347 return Node{OpNode{BasicOp::_operation_}, left, right}; \
349 inline Node operator _operator_(BindingNode const& left, Node&& right) \
351 return Node{OpNode{BasicOp::_operation_}, left, std::forward<Node>(right)}; \
353 inline Node operator _operator_(Node&& left, BindingNode const& right) \
355 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), right}; \
357 template <typename T> \
358 inline Node operator _operator_(Configurable<T> const& left, BindingNode const& right) \
360 return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, right}; \
362 template <typename T> \
363 inline Node operator _operator_(BindingNode const& left, Configurable<T> const& right) \
365 return Node{OpNode{BasicOp::_operation_}, left, PlaceholderNode{right}}; \
391#define BINARY_FUNC_NODES(_func_, _node_) \
392 template <typename L, typename R> \
393 inline Node _node_(L left, R right) requires(std::is_arithmetic_v<L> && std::is_arithmetic_v<R>) \
395 return Node{OpNode{BasicOp::_func_}, LiteralNode{left}, LiteralNode{right}}; \
398 inline Node _node_(Node&& left, Node&& right) \
400 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), std::forward<Node>(right)}; \
403 inline Node _node_(Node&& left, BindingNode const& right) \
405 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), right}; \
408 inline Node _node_(BindingNode const& left, BindingNode const& right) \
410 return Node{OpNode{BasicOp::_func_}, left, right}; \
413 inline Node _node_(BindingNode const& left, Node&& right) \
415 return Node{OpNode{BasicOp::_func_}, left, std::forward<Node>(right)}; \
418 template <typename T> \
419 inline Node _node_(Node&& left, Configurable<T> const& right) \
421 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), PlaceholderNode{right}}; \
424 template <typename T> \
425 inline Node _node_(Configurable<T> const& left, Node&& right) \
427 return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, std::forward<Node>(right)}; \
430 template <typename T> \
431 inline Node _node_(BindingNode const& left, Configurable<T> const& right) \
433 return Node{OpNode{BasicOp::_func_}, left, PlaceholderNode{right}}; \
436 template <typename T> \
437 inline Node _node_(Configurable<T> const& left, BindingNode const& right) \
439 return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, right}; \
443#define ncheckbit(_node_, _bit_) ((_node_ & _bit_) == _bit_)
446#define UNARY_FUNC_NODES(_func_, _node_) \
447 inline Node _node_(Node&& arg) \
449 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(arg)}; \
469 return Node{
ConditionalNode{}, std::forward<Node>(then_), std::forward<Node>(else_), std::forward<Node>(condition_)};
484template <
typename L1,
typename L2>
485inline Node ifnode(
Node&& condition_, L1 then_, L2 else_)
requires(std::is_arithmetic_v<L1>&& std::is_arithmetic_v<L2>)
508template <
typename L1,
typename L2>
525 const auto binned_copy =
binned;
526 const auto out_copy = out;
528 auto* current = &root;
529 for (
auto i = 0;
i <
bins; ++
i) {
531 current = current->right.get();
533 current->right = std::make_unique<Node>(out);
542 if (node->
self.index() == 5) {
543 auto* n = std::get_if<5>(&node->self);
544 n->reset(parameters[n->index * bins + bin]);
585 std::unique_ptr<Node>
node =
nullptr;
610 gandiva::SchemaPtr
const& Schema);
612std::shared_ptr<gandiva::Filter>
createFilter(gandiva::SchemaPtr
const& Schema,
613 gandiva::ConditionPtr condition);
615std::shared_ptr<gandiva::Filter>
createFilter(gandiva::SchemaPtr
const& Schema,
618std::shared_ptr<gandiva::Projector>
createProjector(gandiva::SchemaPtr
const& Schema,
620 gandiva::FieldPtr
result);
622std::shared_ptr<gandiva::Projector>
createProjector(gandiva::SchemaPtr
const& Schema,
624 gandiva::FieldPtr
result);
635 std::shared_ptr<arrow::Schema> schema,
636 std::vector<std::shared_ptr<arrow::Field>>
const& fields);
638template <
typename... C>
#define SELECT_ARROW_TYPE(_Ctype_, _Atype_)
#define BINARY_FUNC_NODES(_func_, _node_)
#define UNARY_FUNC_NODES(_func_, _node_)
unary functions on nodes
T get(const char *key) const
ConfigParamRegistry const & options()
GLdouble GLdouble GLdouble GLdouble top
GLuint const GLchar * name
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLsizei const GLchar *const * path
std::shared_ptr< gandiva::Filter > FilterPtr
std::shared_ptr< gandiva::SelectionVector > Selection
std::shared_ptr< arrow::DataType > concreteArrowType(atype::type type)
std::shared_ptr< gandiva::Filter > createFilter(gandiva::SchemaPtr const &Schema, gandiva::ConditionPtr condition)
Function to create gandiva filter from gandiva condition.
gandiva::ExpressionPtr makeExpression(gandiva::NodePtr node, gandiva::FieldPtr result)
Function to create gandiva projecting expression from generic gandiva expression tree.
BINARY_OP_NODES && LogicalAnd
BINARY_OP_NODES & BitwiseAnd
std::shared_ptr< gandiva::Projector > createProjectorHelper(size_t nColumns, expressions::Projector *projectors, std::shared_ptr< arrow::Schema > schema, std::vector< std::shared_ptr< arrow::Field > > const &fields)
gandiva::Selection createSelection(std::shared_ptr< arrow::Table > const &table, Filter const &expression)
Function for creating gandiva selection from our internal filter tree.
PlaceholderNode as(Configurable< T > const &v)
const char * stringType(atype::type t)
std::vector< ColumnOperationSpec > Operations
void updateExpressionInfos(expressions::Filter const &filter, std::vector< ExpressionInfo > &eInfos)
Function for attaching gandiva filters to to compatible task inputs.
constexpr auto selectArrowType()
Node par(int index)
Parameters.
Operations createOperations(Filter const &expression)
Function to create an internal operation sequence from a filter tree.
Node updateParameters(Node const &pexp, int bins, std::vector< T > const ¶meters, int bin)
gandiva::ConditionPtr makeCondition(gandiva::NodePtr node)
Function to create gandiva condition expression from generic gandiva expression tree.
bool isTableCompatible(std::set< uint32_t > const &hashes, Operations const &specs)
Function to check compatibility of a given arrow schema with operation sequence.
void unknownParameterUsed(const char *name)
void walk(Node *head, L &&pred)
Tree-walker helper.
BINARY_OP_NODES(<, LessThan)
Node ifnode(Node &&condition_, Node &&then_, Node &&else_)
conditionals
gandiva::NodePtr createExpressionTree(Operations const &opSpecs, gandiva::SchemaPtr const &Schema)
Function to create gandiva expression tree from operation sequence.
Node binned(std::vector< T > const &binning, std::vector< T > const ¶meters, Node &&binned, Node &&pexp, Node &&out)
binned functional
void updatePlaceholders(Filter &filter, InitContext &context)
Update placeholder nodes from context.
BINARY_OP_NODES^ BitwiseXor
BINARY_OP_NODES * Multiplication
Node protect0(Node &&expr)
division by 0 protector
Node npow(Node &&left, T right)
functions
std::string upcastTo(atype::type f)
std::shared_ptr< gandiva::Projector > createProjector(gandiva::SchemaPtr const &Schema, Operations const &opSpecs, gandiva::FieldPtr result)
Function to create gandiva projector from operation sequence.
std::shared_ptr< gandiva::Projector > createProjectors(framework::pack< C... >, std::vector< std::shared_ptr< arrow::Field > > const &fields, gandiva::SchemaPtr schema)
void updateFilterInfo(ExpressionInfo &info, std::shared_ptr< arrow::Table > &table)
constexpr VariantType variant_trait_v
std::vector< int64_t > SelectionVector
Defining DataPointCompositeObject explicitly as copiable.
gandiva::Selection selection
gandiva::SchemaPtr schema
ExpressionInfo(int ai, size_t hash, std::set< uint32_t > &&hs, gandiva::SchemaPtr sc)
std::set< uint32_t > hashes
An expression tree node corresponding to a column binding.
constexpr BindingNode(const char *name_, uint32_t hash_, atype::type type_)
BindingNode(BindingNode const &)=default
BindingNode(BindingNode &&)=delete
A struct, containing the root of the expression tree.
Filter & operator=(Filter &&other) noexcept
size_t designateSubtrees(Node *node, size_t index=0)
std::unique_ptr< Node > node
An expression tree node corresponding to a literal value.
LiteralValue::stored_type var_t
LiteralNode(LiteralNode const &other)=default
std::variant< T... > stored_type
helper struct used to parse trees
bool operator!=(NodeRecord const &rhs)
Node * node_ptr
pointer to the actual tree node
NodeRecord(Node *node_, size_t index_)
Node(PlaceholderNode &&v)
Node(OpNode op, Node &&l)
std::unique_ptr< Node > condition
std::unique_ptr< Node > right
std::variant< LiteralNode, BindingNode, OpNode, PlaceholderNode, ConditionalNode, ParameterNode > self_t
variant with possible nodes
Node(BindingNode const &n)
Node(OpNode op, Node &&l, Node &&r)
Node(ConditionalNode op, Node &&then_, Node &&else_, Node &&condition_)
An expression tree node corresponding to binary or unary operation.
OpNode(OpNode const &other)=default
A placeholder node for parameters taken from an array.
ParameterNode(ParameterNode const &)=default
void reset(T value_, int index_=-1)
ParameterNode(int index_=-1)
A placeholder node for simple type configurable.
void reset(InitContext &context)
LiteralNode::var_t(* retrieve)(InitContext &, char const *)
PlaceholderNode(Configurable< T > const &v)
PlaceholderNode(PlaceholderNode const &other)=default
PlaceholderNode(Configurable< T > const &v, AT *)
VectorOfTObjectPtrs other