Project
Loading...
Searching...
No Matches
Expressions.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef O2_FRAMEWORK_EXPRESSIONS_H_
12#define O2_FRAMEWORK_EXPRESSIONS_H_
13
14#include "Framework/BasicOps.h"
15#include "Framework/Pack.h"
17#include "Framework/Variant.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>
31#else
32namespace gandiva
33{
34class SelectionVector;
35class Filter;
36class Projector;
37} // namespace gandiva
38#endif
39#include <variant>
40#include <string>
41#include <memory>
42#include <set>
43#include <stack>
44namespace gandiva
45{
46using Selection = std::shared_ptr<gandiva::SelectionVector>;
47using FilterPtr = std::shared_ptr<gandiva::Filter>;
48} // namespace gandiva
49
50using atype = arrow::Type;
52 ExpressionInfo(int ai, size_t hash, std::set<uint32_t>&& hs, gandiva::SchemaPtr sc)
53 : argumentIndex(ai),
55 hashes(hs),
56 schema(sc)
57 {
58 }
61 std::set<uint32_t> hashes;
62 gandiva::SchemaPtr schema;
63 gandiva::NodePtr tree = nullptr;
66 bool resetSelection = false;
67};
68
70{
71void unknownParameterUsed(const char* name);
72const char* stringType(atype::type t);
73
74template <typename... T>
76 using stored_type = std::variant<T...>;
78};
79
81
82template <typename T>
83constexpr auto selectArrowType()
84{
85 return atype::NA;
86}
87
88#define SELECT_ARROW_TYPE(_Ctype_, _Atype_) \
89 template <typename T> \
90 requires std::same_as<T, _Ctype_> \
91 constexpr auto selectArrowType() \
92 { \
93 return atype::_Atype_; \
94 }
95
97SELECT_ARROW_TYPE(float, FLOAT);
98SELECT_ARROW_TYPE(double, DOUBLE);
99SELECT_ARROW_TYPE(uint8_t, UINT8);
100SELECT_ARROW_TYPE(int8_t, INT8);
101SELECT_ARROW_TYPE(uint16_t, UINT16);
102SELECT_ARROW_TYPE(int16_t, INT16);
103SELECT_ARROW_TYPE(uint32_t, UINT32);
104SELECT_ARROW_TYPE(int32_t, INT32);
105SELECT_ARROW_TYPE(uint64_t, UINT64);
106SELECT_ARROW_TYPE(int64_t, INT64);
107
108std::shared_ptr<arrow::DataType> concreteArrowType(atype::type type);
109std::string upcastTo(atype::type f);
110
114
116 : value{-1},
117 type{atype::INT32}
118 {
119 }
120 template <typename T>
122 {
123 }
124
125 LiteralNode(var_t v, atype::type t)
126 : value{v},
127 type{t}
128 {
129 }
130
132 atype::type type = atype::NA;
133};
134
137 constexpr BindingNode()
138 : name{nullptr},
139 hash{0},
140 type{atype::FLOAT}
141 {
142 }
143 BindingNode(BindingNode const&) = default;
145 constexpr BindingNode(const char* name_, uint32_t hash_, atype::type type_) : name{name_}, hash{hash_}, type{type_} {}
146 constexpr BindingNode(uint32_t hash_, atype::type type_) : name{nullptr}, hash{hash_}, type{type_} {}
147 const char* name;
148 uint32_t hash;
149 atype::type type;
150};
151
153struct OpNode {
155 OpNode(BasicOp op_) : op{op_} {}
157};
158
161 template <typename T>
162 requires(variant_trait_v<typename std::decay<T>::type> != VariantType::Unknown)
164 {
165 retrieve = [](InitContext& context, char const* name) { return LiteralNode::var_t{context.options().get<T>(name)}; };
166 }
167
168 template <typename T, typename AT>
169 requires((std::convertible_to<T, AT>) && (variant_trait_v<typename std::decay<T>::type> != VariantType::Unknown))
170 PlaceholderNode(Configurable<T> const& v, AT*) : LiteralNode{static_cast<AT>(v.value)}, name{v.name}
171 {
172 retrieve = [](InitContext& context, char const* name) { return LiteralNode::var_t{static_cast<AT>(context.options().get<T>(name))}; };
173 }
174
175 template <typename T>
176 PlaceholderNode(T defaultValue, std::string&& path)
177 : LiteralNode{defaultValue},
180 {
181 retrieve = [](InitContext& context, char const* name) { return LiteralNode::var_t{context.options().get<T>(name)}; };
182 }
183
184 void reset(InitContext& context)
185 {
186 value = retrieve(context, stored_name.empty() ? name.data() : stored_name.data());
187 }
188
189 std::string stored_name;
190 std::string const& name;
192};
193
194template <typename AT, typename T>
196{
197 return PlaceholderNode(v, (AT*)nullptr);
198}
199
202 ParameterNode(int index_ = -1)
203 : LiteralNode((float)0),
204 index{index_}
205 {
206 }
207
208 template <typename T>
209 void reset(T value_, int index_ = -1)
210 {
211 (*static_cast<LiteralNode*>(this)) = LiteralNode(value_);
212 if (index_ > 0) {
213 index = index_;
214 }
215 }
216
217 int index;
218};
219
222};
223
225template <typename T>
226concept is_literal_like = std::same_as<T, LiteralNode> || std::same_as<T, PlaceholderNode> || std::same_as<T, ParameterNode>;
227
228template <typename T>
229concept is_binding = std::same_as<T, BindingNode>;
230
231template <typename T>
232concept is_operation = std::same_as<T, OpNode>;
233
234template <typename T>
235concept is_conditional = std::same_as<T, ConditionalNode>;
236
238struct Node {
239 Node(LiteralNode&& v) : self{std::forward<LiteralNode>(v)}, left{nullptr}, right{nullptr}, condition{nullptr}
240 {
241 }
242
243 Node(PlaceholderNode&& v) : self{std::forward<PlaceholderNode>(v)}, left{nullptr}, right{nullptr}, condition{nullptr}
244 {
245 }
246
247 Node(Node&& n) : self{std::forward<self_t>(n.self)}, left{std::forward<std::unique_ptr<Node>>(n.left)}, right{std::forward<std::unique_ptr<Node>>(n.right)}, condition{std::forward<std::unique_ptr<Node>>(n.condition)}, binding{std::forward<std::string>(n.binding)}
248 {
249 }
250
251 Node(BindingNode const& n) : self{n}, left{nullptr}, right{nullptr}, condition{nullptr}
252 {
253 }
254
255 Node(BindingNode const& n, std::string binding_) : self{n}, left{nullptr}, right{nullptr}, condition{nullptr}, binding{binding_}
256 {
257 get<BindingNode>(self).name = binding.c_str();
258 }
259
260 Node(ParameterNode&& p) : self{std::forward<ParameterNode>(p)}, left{nullptr}, right{nullptr}, condition{nullptr}
261 {
262 }
263
264 Node(ConditionalNode op, Node&& then_, Node&& else_, Node&& condition_)
265 : self{op},
266 left{std::make_unique<Node>(std::forward<Node>(then_))},
267 right{std::make_unique<Node>(std::forward<Node>(else_))},
268 condition{std::make_unique<Node>(std::forward<Node>(condition_))} {}
269
270 Node(ConditionalNode op, Node&& then_, std::unique_ptr<Node>&& else_, Node&& condition_)
271 : self{op},
272 left{std::make_unique<Node>(std::forward<Node>(then_))},
273 right{std::forward<std::unique_ptr<Node>>(else_)},
274 condition{std::make_unique<Node>(std::forward<Node>(condition_))} {}
275
277 : self{op},
278 left{std::make_unique<Node>(std::forward<Node>(l))},
279 right{std::make_unique<Node>(std::forward<Node>(r))},
280 condition{nullptr} {}
281
282 Node(OpNode op, std::unique_ptr<Node>&& l, Node&& r)
283 : self{op},
284 left{std::forward<std::unique_ptr<Node>>(l)},
285 right{std::make_unique<Node>(std::forward<Node>(r))},
286 condition{nullptr} {}
287
289 : self{op},
290 left{std::make_unique<Node>(std::forward<Node>(l))},
291 right{nullptr},
292 condition{nullptr} {}
293
295 : self{other.self},
297 {
298 if (other.left != nullptr) {
299 left = std::make_unique<Node>(*other.left);
300 }
301 if (other.right != nullptr) {
302 right = std::make_unique<Node>(*other.right);
303 }
304 if (other.condition != nullptr) {
305 condition = std::make_unique<Node>(*other.condition);
306 }
307 binding = other.binding;
308 if (!binding.empty()) {
309 get<BindingNode>(self).name = binding.c_str();
310 }
311 }
312
314 using self_t = std::variant<LiteralNode, BindingNode, OpNode, PlaceholderNode, ConditionalNode, ParameterNode>;
316 size_t index = 0;
318 std::unique_ptr<Node> left = nullptr;
319 std::unique_ptr<Node> right = nullptr;
320 std::unique_ptr<Node> condition = nullptr;
321
323 std::string binding;
324};
325
329 Node* node_ptr = nullptr;
330 size_t index = 0;
331 explicit NodeRecord(Node* node_, size_t index_) : node_ptr(node_), index{index_} {}
332 bool operator!=(NodeRecord const& rhs)
333 {
334 return this->node_ptr != rhs.node_ptr;
335 }
336};
337
339template <typename L>
340void walk(Node* head, L&& pred)
341{
342 std::stack<NodeRecord> path;
343 path.emplace(head, 0);
344 while (!path.empty()) {
345 auto& top = path.top();
346 pred(top.node_ptr);
347
348 auto* leftp = top.node_ptr->left.get();
349 auto* rightp = top.node_ptr->right.get();
350 auto* condp = top.node_ptr->condition.get();
351 path.pop();
352
353 if (leftp != nullptr) {
354 path.emplace(leftp, 0);
355 }
356 if (rightp != nullptr) {
357 path.emplace(rightp, 0);
358 }
359 if (condp != nullptr) {
360 path.emplace(condp, 0);
361 }
362 }
363}
364
366template <typename T>
367concept arithmetic = std::is_arithmetic_v<T>;
368
370
371#define BINARY_OP_NODES(_operator_, _operation_) \
372 inline Node operator _operator_(Node&& left, Node&& right) \
373 { \
374 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), std::forward<Node>(right)}; \
375 } \
376 template <arithmetic T> \
377 inline Node operator _operator_(Node&& left, T right) \
378 { \
379 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), LiteralNode{right}}; \
380 } \
381 template <arithmetic T> \
382 inline Node operator _operator_(T left, Node&& right) \
383 { \
384 return Node{OpNode{BasicOp::_operation_}, LiteralNode{left}, std::forward<Node>(right)}; \
385 } \
386 template <typename T> \
387 inline Node operator _operator_(Node&& left, Configurable<T> const& right) \
388 { \
389 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), PlaceholderNode{right}}; \
390 } \
391 template <typename T> \
392 inline Node operator _operator_(Configurable<T> const& left, Node&& right) \
393 { \
394 return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, std::forward<Node>(right)}; \
395 } \
396 inline Node operator _operator_(BindingNode const& left, BindingNode const& right) \
397 { \
398 return Node{OpNode{BasicOp::_operation_}, left, right}; \
399 } \
400 inline Node operator _operator_(BindingNode const& left, Node&& right) \
401 { \
402 return Node{OpNode{BasicOp::_operation_}, left, std::forward<Node>(right)}; \
403 } \
404 inline Node operator _operator_(Node&& left, BindingNode const& right) \
405 { \
406 return Node{OpNode{BasicOp::_operation_}, std::forward<Node>(left), right}; \
407 } \
408 template <typename T> \
409 inline Node operator _operator_(Configurable<T> const& left, BindingNode const& right) \
410 { \
411 return Node{OpNode{BasicOp::_operation_}, PlaceholderNode{left}, right}; \
412 } \
413 template <typename T> \
414 inline Node operator _operator_(BindingNode const& left, Configurable<T> const& right) \
415 { \
416 return Node{OpNode{BasicOp::_operation_}, left, PlaceholderNode{right}}; \
417 }
418
434
436template <arithmetic T>
437inline Node npow(Node&& left, T right)
438{
439 return Node{OpNode{BasicOp::Power}, std::forward<Node>(left), LiteralNode{right}};
440}
441
442#define BINARY_FUNC_NODES(_func_, _node_) \
443 template <arithmetic L, arithmetic R> \
444 inline Node _node_(L left, R right) \
445 { \
446 return Node{OpNode{BasicOp::_func_}, LiteralNode{left}, LiteralNode{right}}; \
447 } \
448 \
449 inline Node _node_(Node&& left, Node&& right) \
450 { \
451 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), std::forward<Node>(right)}; \
452 } \
453 \
454 inline Node _node_(Node&& left, BindingNode const& right) \
455 { \
456 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), right}; \
457 } \
458 \
459 inline Node _node_(BindingNode const& left, BindingNode const& right) \
460 { \
461 return Node{OpNode{BasicOp::_func_}, left, right}; \
462 } \
463 \
464 inline Node _node_(BindingNode const& left, Node&& right) \
465 { \
466 return Node{OpNode{BasicOp::_func_}, left, std::forward<Node>(right)}; \
467 } \
468 \
469 template <typename T> \
470 inline Node _node_(Node&& left, Configurable<T> const& right) \
471 { \
472 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(left), PlaceholderNode{right}}; \
473 } \
474 \
475 template <typename T> \
476 inline Node _node_(Configurable<T> const& left, Node&& right) \
477 { \
478 return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, std::forward<Node>(right)}; \
479 } \
480 \
481 template <typename T> \
482 inline Node _node_(BindingNode const& left, Configurable<T> const& right) \
483 { \
484 return Node{OpNode{BasicOp::_func_}, left, PlaceholderNode{right}}; \
485 } \
486 \
487 template <typename T> \
488 inline Node _node_(Configurable<T> const& left, BindingNode const& right) \
489 { \
490 return Node{OpNode{BasicOp::_func_}, PlaceholderNode{left}, right}; \
491 }
492
494#define ncheckbit(_node_, _bit_) ((_node_ & _bit_) == _bit_)
495
497#define UNARY_FUNC_NODES(_func_, _node_) \
498 inline Node _node_(Node&& arg) \
499 { \
500 return Node{OpNode{BasicOp::_func_}, std::forward<Node>(arg)}; \
501 }
502
516
518inline Node ifnode(Node&& condition_, Node&& then_, Node&& else_)
519{
520 return Node{ConditionalNode{}, std::forward<Node>(then_), std::forward<Node>(else_), std::forward<Node>(condition_)};
521}
522
523template <arithmetic L>
524inline Node ifnode(Node&& condition_, Node&& then_, L else_)
525{
526 return Node{ConditionalNode{}, std::forward<Node>(then_), LiteralNode{else_}, std::forward<Node>(condition_)};
527}
528
529template <arithmetic L>
530inline Node ifnode(Node&& condition_, L then_, Node&& else_)
531{
532 return Node{ConditionalNode{}, LiteralNode{then_}, std::forward<Node>(else_), std::forward<Node>(condition_)};
533}
534
535template <arithmetic L1, arithmetic L2>
536inline Node ifnode(Node&& condition_, L1 then_, L2 else_)
537{
538 return Node{ConditionalNode{}, LiteralNode{then_}, LiteralNode{else_}, std::forward<Node>(condition_)};
539}
540
541template <typename T>
542inline Node ifnode(Configurable<T> const& condition_, Node&& then_, Node&& else_)
543{
544 return Node{ConditionalNode{}, std::forward<Node>(then_), std::forward<Node>(else_), PlaceholderNode{condition_}};
545}
546
547template <typename L>
548inline Node ifnode(Node&& condition_, Node&& then_, Configurable<L> const& else_)
549{
550 return Node{ConditionalNode{}, std::forward<Node>(then_), PlaceholderNode{else_}, std::forward<Node>(condition_)};
551}
552
553template <typename L>
554inline Node ifnode(Node&& condition_, Configurable<L> const& then_, Node&& else_)
555{
556 return Node{ConditionalNode{}, PlaceholderNode{then_}, std::forward<Node>(else_), std::forward<Node>(condition_)};
557}
558
559template <typename L1, typename L2>
560inline Node ifnode(Node&& condition_, Configurable<L1> const& then_, Configurable<L2> const& else_)
561{
562 return Node{ConditionalNode{}, PlaceholderNode{then_}, PlaceholderNode{else_}, std::forward<Node>(condition_)};
563}
564
566inline Node par(int index)
567{
568 return Node{ParameterNode{index}};
569}
570
572template <typename T>
573inline Node binned(std::vector<T> const& binning, std::vector<T> const& parameters, Node&& binned, Node&& pexp, Node&& out)
574{
575 int bins = binning.size() - 1;
576 const auto binned_copy = binned;
577 const auto out_copy = out;
578 auto root = ifnode(Node{binned_copy} < binning[0], Node{out_copy}, LiteralNode{-1});
579 auto* current = &root;
580 for (auto i = 0; i < bins; ++i) {
581 current->right = std::make_unique<Node>(ifnode(Node{binned_copy} < binning[i + 1], updateParameters(pexp, bins, parameters, i), LiteralNode{-1}));
582 current = current->right.get();
583 }
584 current->right = std::make_unique<Node>(out);
585 return root;
586}
587
588template <typename T>
589inline Node updateParameters(Node const& pexp, int bins, std::vector<T> const& parameters, int bin)
590{
591 Node result{pexp};
592 walk(&result, [&bins, &parameters, &bin](Node* node) {
593 if (node->self.index() == 5) {
594 auto* n = std::get_if<5>(&node->self);
595 n->reset(parameters[n->index * bins + bin]);
596 }
597 });
598 return result;
599}
600
602template <typename T>
603inline Node clamp(Node&& expr, T low, T hi)
604{
605 auto copy = expr;
606 return ifnode(Node{copy} < LiteralNode{low}, LiteralNode{low}, ifnode(Node{copy} > LiteralNode{hi}, LiteralNode{hi}, Node{copy}));
607}
608
610inline Node protect0(Node&& expr)
611{
612 auto copy = expr;
614}
615
617template <typename T>
618inline Node ncfg(T defaultValue, std::string path)
619{
620 return PlaceholderNode(defaultValue, path);
621}
622
624struct Filter {
625 Filter() = default;
626
627 Filter(std::unique_ptr<Node>&& ptr)
628 {
629 node = std::move(ptr);
631 }
632
633 Filter(Node&& node_) : node{std::make_unique<Node>(std::forward<Node>(node_))}
634 {
636 }
637
638 Filter(Filter&& other) : node{std::forward<std::unique_ptr<Node>>(other.node)}
639 {
640 }
641
642 Filter(std::string const& input_) : input{input_} {}
643
645 {
646 node = std::move(other.node);
647 input = std::move(other.input);
648 return *this;
649 }
650
651 Filter& operator=(std::string const& input_)
652 {
653 input = input_;
654 if (node != nullptr) {
655 node = nullptr;
656 }
657 return *this;
658 }
659
660 std::unique_ptr<Node> node = nullptr;
661 std::string input;
662
663 size_t designateSubtrees(Node* node, size_t index = 0);
664 void parse();
665};
666
667template <typename T>
668concept is_filter = std::same_as<T, Filter>;
669
671
673gandiva::Selection createSelection(std::shared_ptr<arrow::Table> const& table, Filter const& expression);
675gandiva::Selection createSelection(std::shared_ptr<arrow::Table> const& table, std::shared_ptr<gandiva::Filter> const& gfilter);
676
678using Operations = std::vector<ColumnOperationSpec>;
679
681Operations createOperations(Filter const& expression);
682
684bool isTableCompatible(std::set<uint32_t> const& hashes, Operations const& specs);
686gandiva::NodePtr createExpressionTree(Operations const& opSpecs,
687 gandiva::SchemaPtr const& Schema);
689std::shared_ptr<gandiva::Filter> createFilter(gandiva::SchemaPtr const& Schema,
690 gandiva::ConditionPtr condition);
692std::shared_ptr<gandiva::Filter> createFilter(gandiva::SchemaPtr const& Schema,
693 Operations const& opSpecs);
695std::shared_ptr<gandiva::Projector> createProjector(gandiva::SchemaPtr const& Schema,
696 Operations const& opSpecs,
697 gandiva::FieldPtr result);
699std::shared_ptr<gandiva::Projector> createProjector(gandiva::SchemaPtr const& Schema,
700 Projector&& p,
701 gandiva::FieldPtr result);
703void updateExpressionInfos(expressions::Filter const& filter, std::vector<ExpressionInfo>& eInfos);
705gandiva::ConditionPtr makeCondition(gandiva::NodePtr node);
707gandiva::ExpressionPtr makeExpression(gandiva::NodePtr node, gandiva::FieldPtr result);
710
711std::shared_ptr<gandiva::Projector> createProjectorHelper(size_t nColumns, expressions::Projector* projectors,
712 std::shared_ptr<arrow::Schema> schema,
713 std::vector<std::shared_ptr<arrow::Field>> const& fields);
714
715template <typename... C>
716std::shared_ptr<gandiva::Projector> createProjectors(framework::pack<C...>, std::vector<std::shared_ptr<arrow::Field>> const& fields, gandiva::SchemaPtr schema)
717{
718 std::array<expressions::Projector, sizeof...(C)> projectors{{std::move(C::Projector())...}};
719
720 return createProjectorHelper(sizeof...(C), projectors.data(), schema, fields);
721}
722
723void updateFilterInfo(ExpressionInfo& info, std::shared_ptr<arrow::Table>& table);
724
725/*
726 * The formal grammar for framework expressions.
727 * Operations are in the order of increasing priority.
728 * Identifier includes namespaces, e.g. o2::aod::track::pt.
729 *
730 * top ::= primary
731 *
732 * primary ::= tier1 ('||' tier1)*
733 * tier1 ::= tier2 ('&&' tier2)*
734 * tier2 ::= tier3 ('|' tier3)*
735 * tier3 ::= tier4 ('^' tier4)*
736 * tier4 ::= tier5 ('&' tier5)*
737 * tier5 ::= tier6 (('=='|'!=') tier6)*
738 * tier6 ::= tier7 (('<'|'>'|'<='|'>=') tier7)*
739 * tier7 ::= tier8 (('+'|'-') tier8)*
740 * tier8 ::= base (('*'|'/') base)*
741 *
742 * base ::= identifier
743 * | number
744 * | function_call
745 * | '(' primary ')'
746 *
747 * number ::= -?[0-9]+(\.[0-9]*)?([uf])?
748 * identifier ::= [a-zA-Z][a-zA-Z0-9_]* ('::' [a-zA-Z][a-zA-Z0-9_]*)*
749 * function_call ::= identifier '(' (primary (',' primary)*)? ')'
750 */
751
753enum Token : int {
754 EoL = -1,
759 Unexpected = -100
761
762struct Tokenizer {
763 std::string source;
764 std::string::iterator current;
765 std::string IdentifierStr;
766 std::string BinaryOpStr;
767 std::string StrValue;
768 std::string TokenStr;
769 std::variant<uint32_t, int32_t, uint64_t, int64_t> IntegerValue;
770 std::variant<float, double> FloatValue;
773
774 Tokenizer(std::string const& input = "");
775 void reset(std::string const& input);
776 [[maybe_unused]] int nextToken();
777 void pop();
778 char peek();
779};
780
781struct Parser {
782 static Node parse(std::string const& input);
783 static std::unique_ptr<Node> parsePrimary(Tokenizer& tk);
784 static std::unique_ptr<Node> parseTier1(Tokenizer& tk);
785 static std::unique_ptr<Node> parseTier2(Tokenizer& tk);
786 static std::unique_ptr<Node> parseTier3(Tokenizer& tk);
787 static std::unique_ptr<Node> parseTier4(Tokenizer& tk);
788 static std::unique_ptr<Node> parseTier5(Tokenizer& tk);
789 static std::unique_ptr<Node> parseTier6(Tokenizer& tk);
790 static std::unique_ptr<Node> parseTier7(Tokenizer& tk);
791 static std::unique_ptr<Node> parseTier8(Tokenizer& tk);
792 static std::unique_ptr<Node> parseBase(Tokenizer& tk);
793
794 static OpNode opFromToken(std::string const& token);
795};
796
797} // namespace o2::framework::expressions
798
799#endif // O2_FRAMEWORK_EXPRESSIONS_H_
std::shared_ptr< arrow::Schema > schema
std::vector< expressions::Projector > projectors
const auto bins
Definition PID.cxx:49
uint32_t hash
std::vector< std::shared_ptr< arrow::Field > > fields
std::unique_ptr< expressions::Node > node
#define SELECT_ARROW_TYPE(_Ctype_, _Atype_)
Definition Expressions.h:88
#define BINARY_FUNC_NODES(_func_, _node_)
arrow::Type atype
Definition Expressions.h:50
#define UNARY_FUNC_NODES(_func_, _node_)
unary functions on nodes
int32_t i
uint32_t op
useful math constants
uint32_t gfilter
Definition RawData.h:6
TBranch * ptr
ConfigParamRegistry const & options()
Definition InitContext.h:33
GLsizei const GLchar *const * string
Definition glcorearb.h:809
GLdouble n
Definition glcorearb.h:1982
GLuint64EXT * result
Definition glcorearb.h:5662
const GLdouble * v
Definition glcorearb.h:832
GLuint index
Definition glcorearb.h:781
GLdouble GLdouble GLdouble GLdouble top
Definition glcorearb.h:4077
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble GLdouble right
Definition glcorearb.h:4077
GLdouble f
Definition glcorearb.h:310
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLenum clamp
Definition glcorearb.h:1245
GLboolean r
Definition glcorearb.h:1233
std::shared_ptr< gandiva::Filter > FilterPtr
Definition Expressions.h:47
std::shared_ptr< gandiva::SelectionVector > Selection
Definition Expressions.h:46
constexpr float Almost0
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()
Definition Expressions.h:83
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 &parameters, 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.
Node ifnode(Node &&condition_, Node &&then_, Node &&else_)
conditionals
Node npow(Node &&left, T right)
functions
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 &parameters, 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 ncfg(T defaultValue, std::string path)
context-independent configurable
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)
@ GreaterThanOrEqual
Definition BasicOps.h:29
constexpr VariantType variant_trait_v
Definition Variant.h:190
std::vector< int64_t > SelectionVector
Definition ASoA.h:415
Defining DataPointCompositeObject explicitly as copiable.
gandiva::Selection selection
Definition Expressions.h:65
gandiva::SchemaPtr schema
Definition Expressions.h:62
ExpressionInfo(int ai, size_t hash, std::set< uint32_t > &&hs, gandiva::SchemaPtr sc)
Definition Expressions.h:52
std::set< uint32_t > hashes
Definition Expressions.h:61
gandiva::NodePtr tree
Definition Expressions.h:63
size_t processHash
Definition Expressions.h:60
An expression tree node corresponding to a column binding.
constexpr BindingNode(const char *name_, uint32_t hash_, atype::type type_)
BindingNode(BindingNode const &)=default
constexpr BindingNode(uint32_t hash_, atype::type type_)
A struct, containing the root of the expression tree.
Filter & operator=(std::string const &input_)
Filter(std::unique_ptr< Node > &&ptr)
Filter(std::string const &input_)
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(var_t v, atype::type t)
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_)
std::unique_ptr< Node > condition
Node(ConditionalNode op, Node &&then_, std::unique_ptr< Node > &&else_, 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(OpNode op, std::unique_ptr< Node > &&l, Node &&r)
std::string binding
buffer for dynamic binding
Node(BindingNode const &n, std::string binding_)
Node(ConditionalNode op, Node &&then_, Node &&else_, Node &&condition_)
An expression tree node corresponding to binary or unary operation.
A placeholder node for parameters taken from an array.
void reset(T value_, int index_=-1)
static std::unique_ptr< Node > parseBase(Tokenizer &tk)
static std::unique_ptr< Node > parseTier8(Tokenizer &tk)
static std::unique_ptr< Node > parseTier3(Tokenizer &tk)
static std::unique_ptr< Node > parseTier1(Tokenizer &tk)
static std::unique_ptr< Node > parseTier6(Tokenizer &tk)
static std::unique_ptr< Node > parseTier7(Tokenizer &tk)
static std::unique_ptr< Node > parsePrimary(Tokenizer &tk)
static std::unique_ptr< Node > parseTier4(Tokenizer &tk)
static std::unique_ptr< Node > parseTier2(Tokenizer &tk)
static Node parse(std::string const &input)
static OpNode opFromToken(std::string const &token)
static std::unique_ptr< Node > parseTier5(Tokenizer &tk)
A placeholder node for simple type configurable.
LiteralNode::var_t(* retrieve)(InitContext &, char const *)
PlaceholderNode(Configurable< T > const &v)
PlaceholderNode(Configurable< T > const &v, AT *)
PlaceholderNode(T defaultValue, std::string &&path)
void reset(std::string const &input)
std::variant< uint32_t, int32_t, uint64_t, int64_t > IntegerValue
std::variant< float, double > FloatValue
VectorOfTObjectPtrs other