11#ifndef O2_FRAMEWORK_EXPRESSIONS_H_
12#define O2_FRAMEWORK_EXPRESSIONS_H_
22#include <arrow/type_fwd.h>
23#include <gandiva/gandiva_aliases.h>
24#include <arrow/type.h>
25#include <gandiva/arrow.h>
26#if !defined(__CLING__) && !defined(__ROOTCLING__)
27#include <arrow/table.h>
28#include <gandiva/selection_vector.h>
29#include <gandiva/node.h>
30#include <gandiva/filter.h>
31#include <gandiva/projector.h>
47using Selection = std::shared_ptr<gandiva::SelectionVector>;
53 ExpressionInfo(
int ai,
size_t hash, std::set<uint32_t>&& hs, gandiva::SchemaPtr sc)
64 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>
175 template <
typename T>
176 void reset(T value_,
int index_ = -1)
235 if (
other.left !=
nullptr) {
236 left = std::make_unique<Node>(*
other.left);
238 if (
other.right !=
nullptr) {
241 if (
other.condition !=
nullptr) {
247 using self_t = std::variant<LiteralNode, BindingNode, OpNode, PlaceholderNode, ConditionalNode, ParameterNode>;
251 std::unique_ptr<Node>
left =
nullptr;
252 std::unique_ptr<Node>
right =
nullptr;
264 return this->node_ptr != rhs.node_ptr;
272 std::stack<NodeRecord>
path;
273 path.emplace(head, 0);
274 while (!
path.empty()) {
278 auto* leftp =
top.node_ptr->left.get();
279 auto* rightp =
top.node_ptr->right.get();
280 auto* condp =
top.node_ptr->condition.get();
283 if (leftp !=
nullptr) {
284 path.emplace(leftp, 0);
286 if (rightp !=
nullptr) {
287 path.emplace(rightp, 0);
289 if (condp !=
nullptr) {
290 path.emplace(condp, 0);
297#define BINARY_OP_NODES(_operator_, _operation_) \
298 inline Node operator _operator_(Node&& left, Node&& right) \
300 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), std::forward<Node>(right)}; \
302 template <typename T> \
303 inline Node operator _operator_(Node&& left, T right) requires(std::is_arithmetic_v<std::decay_t<T>>) \
305 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), LiteralNode{right}}; \
307 template <typename T> \
308 inline Node operator _operator_(T left, Node&& right) requires(std::is_arithmetic_v<std::decay_t<T>>) \
310 return Node{OpNode{BasicOp::_operation_}, LiteralNode{left}, std::forward<Node>(right)}; \
312 template <typename T> \
313 inline Node operator _operator_(Node&& left, Configurable<T> const& right) \
315 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), PlaceholderNode{right}}; \
317 template <typename T> \
318 inline Node operator _operator_(Configurable<T> const& left, Node&& right) \
320 return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, std::forward<Node>(right)}; \
322 inline Node operator _operator_(BindingNode const& left, BindingNode const& right) \
324 return Node{OpNode{BasicOp::_operation_}, left, right}; \
326 inline Node operator _operator_(BindingNode const& left, Node&& right) \
328 return Node{OpNode{BasicOp::_operation_}, left, std::forward<Node>(right)}; \
330 inline Node operator _operator_(Node&& left, BindingNode const& right) \
332 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), right}; \
334 template <typename T> \
335 inline Node operator _operator_(Configurable<T> const& left, BindingNode const& right) \
337 return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, right}; \
339 template <typename T> \
340 inline Node operator _operator_(BindingNode const& left, Configurable<T> const& right) \
342 return Node{OpNode{BasicOp::_operation_}, left, PlaceholderNode{right}}; \
368#define BINARY_FUNC_NODES(_func_, _node_) \
369 template <typename L, typename R> \
370 inline Node _node_(L left, R right) requires(std::is_arithmetic_v<L> && std::is_arithmetic_v<R>) \
372 return Node{OpNode{BasicOp::_func_}, LiteralNode{left}, LiteralNode{right}}; \
375 inline Node _node_(Node&& left, Node&& right) \
377 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), std::forward<Node>(right)}; \
380 inline Node _node_(Node&& left, BindingNode const& right) \
382 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), right}; \
385 inline Node _node_(BindingNode const& left, BindingNode const& right) \
387 return Node{OpNode{BasicOp::_func_}, left, right}; \
390 inline Node _node_(BindingNode const& left, Node&& right) \
392 return Node{OpNode{BasicOp::_func_}, left, std::forward<Node>(right)}; \
395 template <typename T> \
396 inline Node _node_(Node&& left, Configurable<T> const& right) \
398 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), PlaceholderNode{right}}; \
401 template <typename T> \
402 inline Node _node_(Configurable<T> const& left, Node&& right) \
404 return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, std::forward<Node>(right)}; \
407 template <typename T> \
408 inline Node _node_(BindingNode const& left, Configurable<T> const& right) \
410 return Node{OpNode{BasicOp::_func_}, left, PlaceholderNode{right}}; \
413 template <typename T> \
414 inline Node _node_(Configurable<T> const& left, BindingNode const& right) \
416 return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, right}; \
420#define ncheckbit(_node_, _bit_) ((_node_ & _bit_) == _bit_)
423#define UNARY_FUNC_NODES(_func_, _node_) \
424 inline Node _node_(Node&& arg) \
426 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(arg)}; \
446 return Node{
ConditionalNode{}, std::forward<Node>(then_), std::forward<Node>(else_), std::forward<Node>(condition_)};
461template <
typename L1,
typename L2>
462inline Node ifnode(
Node&& condition_, L1 then_, L2 else_)
requires(std::is_arithmetic_v<L1>&& std::is_arithmetic_v<L2>)
485template <
typename L1,
typename L2>
502 const auto binned_copy =
binned;
503 const auto out_copy = out;
505 auto* current = &root;
506 for (
auto i = 0;
i <
bins; ++
i) {
508 current = current->right.get();
510 current->right = std::make_unique<Node>(out);
518 auto updateParameter = [&
bins, ¶meters, &bin](
Node* node) {
519 if (node->self.index() == 5) {
520 auto*
n = std::get_if<5>(&node->self);
521 n->reset(parameters[
n->index *
bins + bin]);
548 std::unique_ptr<Node>
node =
nullptr;
573 gandiva::SchemaPtr
const& Schema);
575std::shared_ptr<gandiva::Filter>
createFilter(gandiva::SchemaPtr
const& Schema,
576 gandiva::ConditionPtr condition);
578std::shared_ptr<gandiva::Filter>
createFilter(gandiva::SchemaPtr
const& Schema,
581std::shared_ptr<gandiva::Projector>
createProjector(gandiva::SchemaPtr
const& Schema,
583 gandiva::FieldPtr
result);
585std::shared_ptr<gandiva::Projector>
createProjector(gandiva::SchemaPtr
const& Schema,
587 gandiva::FieldPtr
result);
597template <
typename... C>
600 return {C::Projector()...};
604 std::shared_ptr<arrow::Schema> schema,
605 std::vector<std::shared_ptr<arrow::Field>>
const& fields);
607template <
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.
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.
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 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::vector< expressions::Projector > makeProjectors(framework::pack< C... >)
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)
void walk(Node *head, L const &pred)
Tree-walker helper.
RuntimeErrorRef runtime_error(const char *)
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(PlaceholderNode const &other)=default
PlaceholderNode(Configurable< T > const &v)
VectorOfTObjectPtrs other