mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
WasmOperator.hpp
Go to the documentation of this file.
1#pragma once
2
7
8
9namespace m {
10
11namespace wasm {
12
13// forward declarations
14struct MatchBaseVisitor;
15struct ConstMatchBaseVisitor;
16
17}
18
19namespace option_configs {
20
21/*----- algorithmic decisions ----------------------------------------------------------------------------------------*/
22enum class ScanImplementation : uint64_t {
23 ALL = 0b11,
24 SCAN = 0b01,
25 INDEX_SCAN = 0b10,
26};
27
28enum class GroupingImplementation : uint64_t {
29 ALL = 0b11,
30 HASH_BASED = 0b01,
31 ORDERED = 0b10,
32};
33
34enum class SortingImplementation : uint64_t {
35 ALL = 0b11,
36 QUICKSORT = 0b01,
37 NOOP = 0b10,
38};
39
40enum class JoinImplementation : uint64_t {
41 ALL = 0b111,
42 NESTED_LOOPS = 0b001,
43 SIMPLE_HASH = 0b010,
44 SORT_MERGE = 0b100,
45};
46
47enum class IndexImplementation : uint64_t {
48 ALL = 0b11,
49 ARRAY = 0b01,
50 RMI = 0b10,
51};
52
53enum class SoftPipelineBreakerStrategy : uint64_t {
54 AFTER_ALL = 0b1111111,
55 AFTER_SCAN = 0b0000001,
56 AFTER_FILTER = 0b0000010,
57 AFTER_INDEX_SCAN = 0b0000100,
58 AFTER_PROJECTION = 0b0001000,
59 AFTER_NESTED_LOOPS_JOIN = 0b0010000,
60 AFTER_SIMPLE_HASH_JOIN = 0b0100000,
62 NONE = 0b0000000,
63};
64
65/*----- implementation decisions -------------------------------------------------------------------------------------*/
66enum class IndexScanStrategy : uint64_t {
67 COMPILATION = 0b001,
68 INTERPRETATION = 0b010,
69 HYBRID = 0b100,
70};
71
72enum class IndexScanCompilationStrategy : uint64_t {
73 CALLBACK = 0b01,
74 EXPOSED_MEMORY = 0b10,
75};
76
77enum class IndexScanMaterializationStrategy : uint64_t {
78 INLINE = 0b01,
79 MEMORY = 0b10,
80};
81
82enum class SelectionStrategy : uint64_t {
83 AUTO = 0b11,
84 BRANCHING = 0b01,
85 PREDICATED = 0b10,
86};
87
88enum class HashTableImplementation : uint64_t {
89 ALL = 0b11,
90 OPEN_ADDRESSING = 0b01,
91 CHAINED = 0b10,
92};
93
94enum class ProbingStrategy : uint64_t {
95 AUTO = 0b11,
96 LINEAR = 0b01,
97 QUADRATIC = 0b10,
98};
99
100enum class StoringStrategy : uint64_t {
101 AUTO = 0b11,
102 IN_PLACE = 0b01,
103 OUT_OF_PLACE = 0b10,
104};
105
106enum class OrderingStrategy : uint64_t {
107 AUTO = 0b11,
108 BUILD_ON_LEFT = 0b01,
109 BUILD_ON_RIGHT = 0b10,
110};
111
112}
113
114namespace options {
115
116/*----- options ------------------------------------------------------------------------------------------------------*/
119
122
125
128
131
134
138
142
145
148
151
154
157
160
164
167
171
175
178inline double load_factor_open_addressing = 0.8;
179
182inline double load_factor_chained = 1.5;
183
185inline std::optional<uint32_t> hash_table_initial_capacity;
186
188inline bool hash_based_group_join = true;
189
191inline std::unique_ptr<const m::storage::DataLayoutFactory> hard_pipeline_breaker_layout =
192 std::make_unique<storage::RowLayoutFactory>();
193
197
199inline std::unique_ptr<const m::storage::DataLayoutFactory> soft_pipeline_breaker_layout =
200 std::make_unique<storage::RowLayoutFactory>();
201
203inline std::size_t soft_pipeline_breaker_num_tuples = 0;
204
207inline std::size_t index_sequential_scan_batch_size = 1;
208
210inline std::size_t result_set_window_size = 0;
211
213inline bool exploit_unique_build = true;
214
216inline bool simd = true;
217
219inline bool double_pumping = true;
220
222inline std::size_t simd_lanes = 1;
223
226inline std::vector<std::pair<m::Schema::Identifier, bool>> sorted_attributes;
227
228}
229
230}
231
232namespace m {
233
234#define M_WASM_OPERATOR_LIST_NON_TEMPLATED(X) \
235 X(NoOp) \
236 X(LazyDisjunctiveFilter) \
237 X(Projection) \
238 X(HashBasedGrouping) \
239 X(OrderedGrouping) \
240 X(Aggregation) \
241 X(NoOpSorting) \
242 X(Limit) \
243 X(HashBasedGroupJoin)
244#define M_WASM_OPERATOR_LIST_TEMPLATED(X) \
245 X(Callback<false>) \
246 X(Callback<true>) \
247 X(Print<false>) \
248 X(Print<true>) \
249 X(Scan<false>) \
250 X(Scan<true>) \
251 X(IndexScan<m::idx::IndexMethod::Array>) \
252 X(IndexScan<m::idx::IndexMethod::Rmi>) \
253 X(Filter<false>) \
254 X(Filter<true>) \
255 X(Quicksort<false>) \
256 X(Quicksort<true>) \
257 X(NestedLoopsJoin<false>) \
258 X(NestedLoopsJoin<true>) \
259 X(SimpleHashJoin<M_COMMA(false) false>) \
260 X(SimpleHashJoin<M_COMMA(false) true>) \
261 X(SimpleHashJoin<M_COMMA(true) false>) \
262 X(SimpleHashJoin<M_COMMA(true) true>) \
263 X(SortMergeJoin<M_COMMA(false) M_COMMA(false) M_COMMA(false) false>) \
264 X(SortMergeJoin<M_COMMA(false) M_COMMA(false) M_COMMA(false) true>) \
265 X(SortMergeJoin<M_COMMA(false) M_COMMA(false) M_COMMA(true) false>) \
266 X(SortMergeJoin<M_COMMA(false) M_COMMA(false) M_COMMA(true) true>) \
267 X(SortMergeJoin<M_COMMA(false) M_COMMA(true) M_COMMA(false) false>) \
268 X(SortMergeJoin<M_COMMA(false) M_COMMA(true) M_COMMA(false) true>) \
269 X(SortMergeJoin<M_COMMA(false) M_COMMA(true) M_COMMA(true) false>) \
270 X(SortMergeJoin<M_COMMA(false) M_COMMA(true) M_COMMA(true) true>) \
271 X(SortMergeJoin<M_COMMA(true) M_COMMA(false) M_COMMA(false) false>) \
272 X(SortMergeJoin<M_COMMA(true) M_COMMA(false) M_COMMA(false) true>) \
273 X(SortMergeJoin<M_COMMA(true) M_COMMA(false) M_COMMA(true) false>) \
274 X(SortMergeJoin<M_COMMA(true) M_COMMA(false) M_COMMA(true) true>) \
275 X(SortMergeJoin<M_COMMA(true) M_COMMA(true) M_COMMA(false) false>) \
276 X(SortMergeJoin<M_COMMA(true) M_COMMA(true) M_COMMA(false) true>) \
277 X(SortMergeJoin<M_COMMA(true) M_COMMA(true) M_COMMA(true) false>) \
278 X(SortMergeJoin<M_COMMA(true) M_COMMA(true) M_COMMA(true) true>)
279#define M_WASM_OPERATOR_LIST(X) \
280 M_WASM_OPERATOR_LIST_NON_TEMPLATED(X) \
281 M_WASM_OPERATOR_LIST_TEMPLATED(X)
282
283
284#define MAKE_WASM_MATCH_(OP) m::Match<m::wasm::OP>
285#define M_WASM_MATCH_LIST_NON_TEMPLATED(X) M_TRANSFORM_X_MACRO(X, M_WASM_OPERATOR_LIST_NON_TEMPLATED, MAKE_WASM_MATCH_)
286#define M_WASM_MATCH_LIST_TEMPLATED(X) \
287 X(m::Match<m::wasm::Callback<false>>) \
288 X(m::Match<m::wasm::Callback<true>>) \
289 X(m::Match<m::wasm::Print<false>>) \
290 X(m::Match<m::wasm::Print<true>>) \
291 X(m::Match<m::wasm::Scan<false>>) \
292 X(m::Match<m::wasm::Scan<true>>) \
293 X(m::Match<m::wasm::IndexScan<m::idx::IndexMethod::Array>>) \
294 X(m::Match<m::wasm::IndexScan<m::idx::IndexMethod::Rmi>>) \
295 X(m::Match<m::wasm::Filter<false>>) \
296 X(m::Match<m::wasm::Filter<true>>) \
297 X(m::Match<m::wasm::Quicksort<false>>) \
298 X(m::Match<m::wasm::Quicksort<true>>) \
299 X(m::Match<m::wasm::NestedLoopsJoin<false>>) \
300 X(m::Match<m::wasm::NestedLoopsJoin<true>>) \
301 X(m::Match<m::wasm::SimpleHashJoin<M_COMMA(false) false>>) \
302 X(m::Match<m::wasm::SimpleHashJoin<M_COMMA(false) true>>) \
303 X(m::Match<m::wasm::SimpleHashJoin<M_COMMA(true) false>>) \
304 X(m::Match<m::wasm::SimpleHashJoin<M_COMMA(true) true>>) \
305 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(false) M_COMMA(false) M_COMMA(false) false>>) \
306 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(false) M_COMMA(false) M_COMMA(false) true>>) \
307 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(false) M_COMMA(false) M_COMMA(true) false>>) \
308 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(false) M_COMMA(false) M_COMMA(true) true>>) \
309 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(false) M_COMMA(true) M_COMMA(false) false>>) \
310 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(false) M_COMMA(true) M_COMMA(false) true>>) \
311 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(false) M_COMMA(true) M_COMMA(true) false>>) \
312 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(false) M_COMMA(true) M_COMMA(true) true>>) \
313 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(true) M_COMMA(false) M_COMMA(false) false>>) \
314 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(true) M_COMMA(false) M_COMMA(false) true>>) \
315 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(true) M_COMMA(false) M_COMMA(true) false>>) \
316 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(true) M_COMMA(false) M_COMMA(true) true>>) \
317 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(true) M_COMMA(true) M_COMMA(false) false>>) \
318 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(true) M_COMMA(true) M_COMMA(false) true>>) \
319 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(true) M_COMMA(true) M_COMMA(true) false>>) \
320 X(m::Match<m::wasm::SortMergeJoin<M_COMMA(true) M_COMMA(true) M_COMMA(true) true>>)
321#define M_WASM_MATCH_LIST(X) \
322 M_WASM_MATCH_LIST_NON_TEMPLATED(X) \
323 M_WASM_MATCH_LIST_TEMPLATED(X)
324
325// forward declarations
326#define DECLARE(OP) \
327 namespace wasm { struct OP; } \
328 template<> struct Match<wasm::OP>;
330#undef DECLARE
331
332namespace wasm { template<bool SIMDfied> struct Callback; }
333template<bool SIMDfied> struct Match<wasm::Callback<SIMDfied>>;
334
335namespace wasm { template<bool SIMDfied> struct Print; }
336template<bool SIMDfied> struct Match<wasm::Print<SIMDfied>>;
337
338namespace wasm { template<bool SIMDfied> struct Scan; }
339template<bool SIMDfied> struct Match<wasm::Scan<SIMDfied>>;
340
341namespace wasm { template<idx::IndexMethod IndexMethod> struct IndexScan; }
342template<idx::IndexMethod IndexMethod> struct Match<wasm::IndexScan<IndexMethod>>;
343
344namespace wasm { template<bool Predicated> struct Filter; }
345template<bool Predicated> struct Match<wasm::Filter<Predicated>>;
346
347namespace wasm { template<bool CmpPredicated> struct Quicksort; }
348template<bool CmpPredicated> struct Match<wasm::Quicksort<CmpPredicated>>;
349
350namespace wasm { template<bool Predicated> struct NestedLoopsJoin; }
351template<bool Predicated> struct Match<wasm::NestedLoopsJoin<Predicated>>;
352
353namespace wasm { template<bool UniqueBuild, bool Predicated> struct SimpleHashJoin; }
354template<bool UniqueBuild, bool Predicated> struct Match<wasm::SimpleHashJoin<UniqueBuild, Predicated>>;
355
356namespace wasm { template<bool SortLeft, bool SortRight, bool Predicated, bool CmpPredicated> struct SortMergeJoin; }
357template<bool SortLeft, bool SortRight, bool Predicated, bool CmpPredicated>
358struct Match<wasm::SortMergeJoin<SortLeft, SortRight, Predicated, CmpPredicated>>;
359
360
361namespace wasm {
362
363struct NoOp : PhysicalOperator<NoOp, NoOpOperator>
364{
365 static void execute(const Match<NoOp> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
366 static double cost(const Match<NoOp>&) { return 1.0; }
367};
368
369template<bool SIMDfied>
370struct Callback : PhysicalOperator<Callback<SIMDfied>, CallbackOperator>
371{
372 static void execute(const Match<Callback> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
373 static double cost(const Match<Callback>&) { return 1.0; }
374 static ConditionSet pre_condition(std::size_t child_idx,
375 const std::tuple<const CallbackOperator*> &partial_inner_nodes);
376};
377
378template<bool SIMDfied>
379struct Print : PhysicalOperator<Print<SIMDfied>, PrintOperator>
380{
381 static void execute(const Match<Print> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
382 static double cost(const Match<Print>&) { return 1.0; }
383 static ConditionSet pre_condition(std::size_t child_idx,
384 const std::tuple<const PrintOperator*> &partial_inner_nodes);
385};
386
387template<bool SIMDfied>
388struct Scan : PhysicalOperator<Scan<SIMDfied>, ScanOperator>
389{
390 static void execute(const Match<Scan> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
391 static double cost(const Match<Scan>&) { return M_CONSTEXPR_COND(SIMDfied, 1.0, 2.0); }
392 static ConditionSet pre_condition(std::size_t child_idx,
393 const std::tuple<const ScanOperator*> &partial_inner_nodes);
394 static ConditionSet post_condition(const Match<Scan> &M);
395};
396
397template<idx::IndexMethod IndexMethod>
398struct IndexScan : PhysicalOperator<IndexScan<IndexMethod>, pattern_t<FilterOperator, ScanOperator>>
399{
400 static void execute(const Match<IndexScan> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
401 static double cost(const Match<IndexScan> &M);
402 static ConditionSet pre_condition(std::size_t child_idx,
403 const std::tuple<const FilterOperator*, const ScanOperator*> &partial_inner_nodes);
404 static ConditionSet post_condition(const Match<IndexScan> &M);
405};
406
407template<bool Predicated>
408struct Filter : PhysicalOperator<Filter<Predicated>, FilterOperator>
409{
410 static void execute(const Match<Filter> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
411 static double cost(const Match<Filter>&);
412 static ConditionSet pre_condition(std::size_t child_idx,
413 const std::tuple<const FilterOperator*> &partial_inner_nodes);
414 static ConditionSet adapt_post_condition(const Match<Filter> &M, const ConditionSet &post_cond_child);
415};
416
417struct LazyDisjunctiveFilter : PhysicalOperator<LazyDisjunctiveFilter, DisjunctiveFilterOperator>
418{
419 static void execute(const Match<LazyDisjunctiveFilter> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
420 static double cost(const Match<LazyDisjunctiveFilter> &M);
421 static ConditionSet pre_condition(std::size_t child_idx,
422 const std::tuple<const FilterOperator*> &partial_inner_nodes);
423};
424
425struct Projection : PhysicalOperator<Projection, ProjectionOperator>
426{
427 static void execute(const Match<Projection> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
428 static double cost(const Match<Projection>&) { return 1.0; }
429 static ConditionSet pre_condition(std::size_t child_idx,
430 const std::tuple<const ProjectionOperator*> &partial_inner_nodes);
431 static ConditionSet adapt_post_condition(const Match<Projection> &M, const ConditionSet &post_cond_child);
432};
433
434struct HashBasedGrouping : PhysicalOperator<HashBasedGrouping, GroupingOperator>
435{
436 static void execute(const Match<HashBasedGrouping> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
437 static double cost(const Match<HashBasedGrouping>&);
438 static ConditionSet pre_condition(std::size_t child_idx,
439 const std::tuple<const GroupingOperator*> &partial_inner_nodes);
440 static ConditionSet post_condition(const Match<HashBasedGrouping> &M);
441};
442
443struct OrderedGrouping : PhysicalOperator<OrderedGrouping, GroupingOperator>
444{
445 private:
446 template<bool IsGlobal, typename T>
447 using var_t_ = std::conditional_t<IsGlobal, Global<T>, Var<T>>;
448 template<bool IsGlobal>
449 using agg_t_ = std::variant<
451 std::pair<var_t_<IsGlobal, I8x1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
452 std::pair<var_t_<IsGlobal, I16x1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
453 std::pair<var_t_<IsGlobal, I32x1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
454 std::pair<var_t_<IsGlobal, I64x1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
455 std::pair<var_t_<IsGlobal, Floatx1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
456 std::pair<var_t_<IsGlobal, Doublex1>, std::optional<var_t_<IsGlobal, Boolx1>>>
457 >;
458 template<bool IsGlobal>
459 using key_t_ = std::variant<
461 std::pair<var_t_<IsGlobal, Boolx1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
462 std::pair<var_t_<IsGlobal, I8x1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
463 std::pair<var_t_<IsGlobal, I16x1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
464 std::pair<var_t_<IsGlobal, I32x1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
465 std::pair<var_t_<IsGlobal, I64x1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
466 std::pair<var_t_<IsGlobal, Floatx1>, std::optional<var_t_<IsGlobal, Boolx1>>>,
467 std::pair<var_t_<IsGlobal, Doublex1>, std::optional<var_t_<IsGlobal, Boolx1>>>
468 >;
469
470 public:
471 static void execute(const Match<OrderedGrouping> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
472 static double cost(const Match<OrderedGrouping>&);
473 static ConditionSet pre_condition(std::size_t child_idx,
474 const std::tuple<const GroupingOperator*> &partial_inner_nodes);
475 static ConditionSet adapt_post_condition(const Match<OrderedGrouping> &M, const ConditionSet &post_cond_child);
476};
477
478struct Aggregation : PhysicalOperator<Aggregation, AggregationOperator>
479{
480 private:
481 template<bool IsGlobal, typename T>
482 using var_t_ = std::conditional_t<IsGlobal, Global<T>, Var<T>>;
483 template<bool IsGlobal, std::size_t L>
484 using agg_t_ = std::variant<
486 std::pair<var_t_<IsGlobal, I8<L>>, var_t_<IsGlobal, Bool<L>>>,
487 std::pair<var_t_<IsGlobal, I16<L>>, var_t_<IsGlobal, Bool<L>>>,
488 std::pair<var_t_<IsGlobal, I32<L>>, var_t_<IsGlobal, Bool<L>>>,
489 std::pair<var_t_<IsGlobal, I64<L>>, var_t_<IsGlobal, Bool<L>>>,
490 std::pair<var_t_<IsGlobal, Float<L>>, var_t_<IsGlobal, Bool<L>>>,
491 std::pair<var_t_<IsGlobal, Double<L>>, var_t_<IsGlobal, Bool<L>>>
492 >;
493
494 public:
495 static void execute(const Match<Aggregation> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
496 static double cost(const Match<Aggregation>&) { return 1.0; }
497 static ConditionSet pre_condition(std::size_t child_idx,
498 const std::tuple<const AggregationOperator*> &partial_inner_nodes);
499 static ConditionSet post_condition(const Match<Aggregation> &M);
500};
501
502template<bool CmpPredicated>
503struct Quicksort : PhysicalOperator<Quicksort<CmpPredicated>, SortingOperator>
504{
505 static void execute(const Match<Quicksort> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
506 static double cost(const Match<Quicksort>&) { return M_CONSTEXPR_COND(CmpPredicated, 1.0, 1.1); }
507 static ConditionSet pre_condition(std::size_t child_idx,
508 const std::tuple<const SortingOperator*> &partial_inner_nodes);
509 static ConditionSet post_condition(const Match<Quicksort> &M);
510};
511
512struct NoOpSorting : PhysicalOperator<NoOpSorting, SortingOperator>
513{
514 static void execute(const Match<NoOpSorting> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
515 static double cost(const Match<NoOpSorting>&) { return 0.0; }
516 static ConditionSet pre_condition(std::size_t child_idx,
517 const std::tuple<const SortingOperator*> &partial_inner_nodes);
518};
519
520template<bool Predicated>
521struct NestedLoopsJoin : PhysicalOperator<NestedLoopsJoin<Predicated>, JoinOperator>
522{
523 static void execute(const Match<NestedLoopsJoin> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
524 static double cost(const Match<NestedLoopsJoin> &M);
525 static ConditionSet pre_condition(std::size_t child_idx, const std::tuple<const JoinOperator*> &partial_inner_nodes);
526 static ConditionSet
527 adapt_post_conditions(const Match<NestedLoopsJoin> &M,
528 std::vector<std::reference_wrapper<const ConditionSet>> &&post_cond_children);
529};
530
531template<bool UniqueBuild, bool Predicated>
533 : PhysicalOperator<SimpleHashJoin<UniqueBuild, Predicated>, pattern_t<JoinOperator, Wildcard, Wildcard>>
534{
535 static void execute(const Match<SimpleHashJoin> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
536 static double cost(const Match<SimpleHashJoin> &M);
537 static ConditionSet
538 pre_condition(std::size_t child_idx,
539 const std::tuple<const JoinOperator*, const Wildcard*, const Wildcard*> &partial_inner_nodes);
540 static ConditionSet
541 adapt_post_conditions(const Match<SimpleHashJoin> &M,
542 std::vector<std::reference_wrapper<const ConditionSet>> &&post_cond_children);
543};
544
545template<bool SortLeft, bool SortRight, bool Predicated, bool CmpPredicated>
547 : PhysicalOperator<SortMergeJoin<SortLeft, SortRight, Predicated, CmpPredicated>,
548 pattern_t<JoinOperator, Wildcard, Wildcard>>
549{
550 static void execute(const Match<SortMergeJoin> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
551 static double cost(const Match<SortMergeJoin> &M);
552 static ConditionSet
553 pre_condition(std::size_t child_idx,
554 const std::tuple<const JoinOperator*, const Wildcard*, const Wildcard*> &partial_inner_nodes);
555 static ConditionSet
556 adapt_post_conditions(const Match<SortMergeJoin> &M,
557 std::vector<std::reference_wrapper<const ConditionSet>> &&post_cond_children);
558};
559
560struct Limit : PhysicalOperator<Limit, LimitOperator>
561{
562 static void execute(const Match<Limit> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
563 static double cost(const Match<Limit>&) { return 1.0; }
564 static ConditionSet pre_condition(std::size_t child_idx,
565 const std::tuple<const LimitOperator*> &partial_inner_nodes);
566};
567
569 : PhysicalOperator<HashBasedGroupJoin, pattern_t<GroupingOperator, pattern_t<JoinOperator, Wildcard, Wildcard>>>
570{
571 static void execute(const Match<HashBasedGroupJoin> &M, setup_t setup, pipeline_t pipeline, teardown_t teardown);
572 static double cost(const Match<HashBasedGroupJoin>&);
573 static ConditionSet
574 pre_condition(std::size_t child_idx,
575 const std::tuple<const GroupingOperator*, const JoinOperator*, const Wildcard*, const Wildcard*>
576 &partial_inner_nodes);
577 static ConditionSet post_condition(const Match<HashBasedGroupJoin> &M);
578};
579
580}
581
584
585template<typename T>
586void execute_buffered(const Match<T> &M, const Schema &schema,
587 const std::unique_ptr<const storage::DataLayoutFactory> &buffer_factory,
588 std::size_t buffer_num_tuples, setup_t setup, pipeline_t pipeline, teardown_t teardown)
589{
590 if (buffer_factory) {
591 auto buffer_schema = schema.drop_constants().deduplicate();
592 if (buffer_schema.num_entries()) {
593 /* Use global buffer since own operator may be executed partially in multiple function calls. */
594 wasm::GlobalBuffer buffer(buffer_schema, *buffer_factory, wasm::CodeGenContext::Get().num_simd_lanes() > 1,
595 buffer_num_tuples, std::move(setup), std::move(pipeline), std::move(teardown));
596 T::execute(
597 /* M= */ M,
598 /* setup= */ setup_t::Make_Without_Parent([&buffer](){ buffer.setup(); }),
599 /* pipeline= */ [&buffer](){ buffer.consume(); },
600 /* teardown= */ teardown_t::Make_Without_Parent([&buffer](){ buffer.teardown(); })
601 );
602 buffer.resume_pipeline();
603 } else {
604 T::execute(M, std::move(setup), std::move(pipeline), std::move(teardown));
605 }
606 } else {
607 T::execute(M, std::move(setup), std::move(pipeline), std::move(teardown));
608 }
609}
610
611namespace wasm {
612
615{
616 virtual void accept(MatchBaseVisitor &v) = 0;
617 virtual void accept(ConstMatchBaseVisitor &v) const = 0;
618};
619
624{
626
628 : child(as<const wasm::MatchBase>(std::move(children[0])))
629 {
630 M_insist(children.size() == 1);
631 }
632};
635{
636 std::vector<unsharable_shared_ptr<const wasm::MatchBase>> children;
637
639 : children([&children](){
640 std::vector<unsharable_shared_ptr<const wasm::MatchBase>> res;
641 for (auto &c : children)
642 res.push_back(as<const wasm::MatchBase>(std::move(c)));
643 return res;
644 }())
645 {
646 M_insist(children.size() >= 2);
647 }
648};
649
650};
651
652template<>
654{
656
658 : wasm::MatchSingleChild(std::move(children))
659 , noop(*noop)
660 { }
661
662 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
663 wasm::NoOp::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
664 }
665
666 const Operator & get_matched_root() const override { return noop; }
667
668 void accept(wasm::MatchBaseVisitor &v) override;
669 void accept(wasm::ConstMatchBaseVisitor &v) const override;
670
671 protected:
672 void print(std::ostream &out, unsigned level) const override;
673};
674
675template<bool SIMDfied>
676struct Match<wasm::Callback<SIMDfied>> : wasm::MatchSingleChild
677{
679 std::unique_ptr<const storage::DataLayoutFactory> result_set_factory =
681 std::size_t result_set_window_size = options::result_set_window_size;
682
683 Match(const CallbackOperator *callback, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
684 : wasm::MatchSingleChild(std::move(children))
685 , callback(*callback)
686 { }
687
688 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
689 wasm::Callback<SIMDfied>::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
690 }
691
692 const Operator & get_matched_root() const override { return callback; }
693
694 void accept(wasm::MatchBaseVisitor &v) override;
695 void accept(wasm::ConstMatchBaseVisitor &v) const override;
696
697 protected:
698 void print(std::ostream &out, unsigned level) const override;
699};
700
701template<bool SIMDfied>
702struct Match<wasm::Print<SIMDfied>> : wasm::MatchSingleChild
703{
705 std::unique_ptr<const storage::DataLayoutFactory> result_set_factory =
707 std::size_t result_set_window_size = options::result_set_window_size;
708
709 Match(const PrintOperator *print, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
710 : wasm::MatchSingleChild(std::move(children))
711 , print_op(*print)
712 { }
713
714 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
715 wasm::Print<SIMDfied>::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
716 }
717
718 const Operator & get_matched_root() const override { return print_op; }
719
720 void accept(wasm::MatchBaseVisitor &v) override;
721 void accept(wasm::ConstMatchBaseVisitor &v) const override;
722
723 protected:
724 void print(std::ostream &out, unsigned level) const override;
725};
726
727template<bool SIMDfied>
728struct Match<wasm::Scan<SIMDfied>> : wasm::MatchLeaf
729{
731 private:
732 std::unique_ptr<const storage::DataLayoutFactory> buffer_factory_ =
735 : std::unique_ptr<storage::DataLayoutFactory>();
736 std::size_t buffer_num_tuples_ = options::soft_pipeline_breaker_num_tuples;
737
738 public:
740 : scan(*scan)
741 {
742 M_insist(children.empty());
743 }
744
745 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
746 if (buffer_factory_) {
747 auto buffer_schema = scan.schema().drop_constants().deduplicate();
748 if (buffer_schema.num_entries()) {
749 /* Use local buffer since scan loop will not be executed partially in multiple function calls. */
750 wasm::LocalBuffer buffer(buffer_schema, *buffer_factory_, SIMDfied or options::simd, buffer_num_tuples_,
751 std::move(setup), std::move(pipeline), std::move(teardown));
753 /* M= */ *this,
754 /* setup= */ setup_t::Make_Without_Parent([&buffer](){ buffer.setup(); }),
755 /* pipeline= */ [&buffer](){ buffer.consume(); },
756 /* teardown= */ teardown_t::Make_Without_Parent([&buffer](){
757 buffer.resume_pipeline(); // must be placed before teardown method for local buffers
758 buffer.teardown();
759 })
760 );
761 } else {
762 wasm::Scan<SIMDfied>::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
763 }
764 } else {
765 wasm::Scan<SIMDfied>::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
766 }
767 }
768
769 const Operator & get_matched_root() const override { return scan; }
770
771 void accept(wasm::MatchBaseVisitor &v) override;
772 void accept(wasm::ConstMatchBaseVisitor &v) const override;
773
774 protected:
775 void print(std::ostream &out, unsigned level) const override;
776};
777
778template<idx::IndexMethod IndexMethod>
779struct Match<wasm::IndexScan<IndexMethod>> : wasm::MatchLeaf
780{
784 private:
785 std::unique_ptr<const storage::DataLayoutFactory> buffer_factory_ =
788 : std::unique_ptr<storage::DataLayoutFactory>();
789 std::size_t buffer_num_tuples_ = options::soft_pipeline_breaker_num_tuples;
790
791 public:
792 Match(const FilterOperator *filter, const ScanOperator *scan,
793 std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
794 : scan(*scan)
795 , filter(*filter)
796 {
797 M_insist(children.empty());
798 }
799
800 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
801 execute_buffered(*this, filter.schema(), buffer_factory_, buffer_num_tuples_,
802 std::move(setup), std::move(pipeline), std::move(teardown));
803 }
804
805 const Operator & get_matched_root() const override { return filter; }
806
807 void accept(wasm::MatchBaseVisitor &v) override;
808 void accept(wasm::ConstMatchBaseVisitor &v) const override;
809
810 protected:
811 void print(std::ostream &out, unsigned level) const override;
812};
813
814template<bool Predicated>
815struct Match<wasm::Filter<Predicated>> : wasm::MatchSingleChild
816{
818 private:
819 std::unique_ptr<const storage::DataLayoutFactory> buffer_factory_ =
822 : std::unique_ptr<storage::DataLayoutFactory>();
823 std::size_t buffer_num_tuples_ = options::soft_pipeline_breaker_num_tuples;
824
825 public:
826 Match(const FilterOperator *filter, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
827 : wasm::MatchSingleChild(std::move(children))
828 , filter(*filter)
829 { }
830
831 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
832 execute_buffered(*this, filter.schema(), buffer_factory_, buffer_num_tuples_,
833 std::move(setup), std::move(pipeline), std::move(teardown));
834 }
835
836 const Operator & get_matched_root() const override { return filter; }
837
838 void accept(wasm::MatchBaseVisitor &v) override;
839 void accept(wasm::ConstMatchBaseVisitor &v) const override;
840
841 protected:
842 void print(std::ostream &out, unsigned level) const override;
843};
844
845template<>
846struct Match<wasm::LazyDisjunctiveFilter> : wasm::MatchSingleChild
847{
849 private:
850 std::unique_ptr<const storage::DataLayoutFactory> buffer_factory_ =
853 : std::unique_ptr<storage::DataLayoutFactory>();
854 std::size_t buffer_num_tuples_ = options::soft_pipeline_breaker_num_tuples;
855
856 public:
858 : wasm::MatchSingleChild(std::move(children))
859 , filter(*filter)
860 { }
861
862 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
863 execute_buffered(*this, filter.schema(), buffer_factory_, buffer_num_tuples_,
864 std::move(setup), std::move(pipeline), std::move(teardown));
865 }
866
867 const Operator & get_matched_root() const override { return filter; }
868
869 void accept(wasm::MatchBaseVisitor &v) override;
870 void accept(wasm::ConstMatchBaseVisitor &v) const override;
871
872 protected:
873 void print(std::ostream &out, unsigned level) const override;
874};
875
876template<>
877struct Match<wasm::Projection> : wasm::MatchBase
878{
880 std::optional<unsharable_shared_ptr<const wasm::MatchBase>> child;
881 private:
882 std::unique_ptr<const storage::DataLayoutFactory> buffer_factory_ =
885 : std::unique_ptr<storage::DataLayoutFactory>();
886 std::size_t buffer_num_tuples_ = options::soft_pipeline_breaker_num_tuples;
887
888 public:
889 Match(const ProjectionOperator *projection, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
890 : projection(*projection)
891 {
892 if (not children.empty()) {
893 M_insist(children.size() == 1);
894 child = as<const wasm::MatchBase>(std::move(children[0]));
895 }
896 }
897
898 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
899 execute_buffered(*this, projection.schema(), buffer_factory_, buffer_num_tuples_,
900 std::move(setup), std::move(pipeline), std::move(teardown));
901 }
902
903 const Operator & get_matched_root() const override { return projection; }
904
905 void accept(wasm::MatchBaseVisitor &v) override;
906 void accept(wasm::ConstMatchBaseVisitor &v) const override;
907
908 protected:
909 void print(std::ostream &out, unsigned level) const override;
910};
911
912template<>
913struct Match<wasm::HashBasedGrouping> : wasm::MatchSingleChild
914{
916 bool use_open_addressing_hashing =
920 double load_factor =
922
923 Match(const GroupingOperator *grouping, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
924 : wasm::MatchSingleChild(std::move(children))
925 , grouping(*grouping)
926 { }
927
928 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
929 wasm::HashBasedGrouping::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
930 }
931
932 const Operator & get_matched_root() const override { return grouping; }
933
934 void accept(wasm::MatchBaseVisitor &v) override;
935 void accept(wasm::ConstMatchBaseVisitor &v) const override;
936
937 protected:
938 void print(std::ostream &out, unsigned level) const override;
939};
940
941template<>
942struct Match<wasm::OrderedGrouping> : wasm::MatchSingleChild
943{
945
946 Match(const GroupingOperator *grouping, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
947 : wasm::MatchSingleChild(std::move(children))
948 , grouping(*grouping)
949 { }
950
951 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
952 wasm::OrderedGrouping::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
953 }
954
955 const Operator & get_matched_root() const override { return grouping; }
956
957 void accept(wasm::MatchBaseVisitor &v) override;
958 void accept(wasm::ConstMatchBaseVisitor &v) const override;
959
960 protected:
961 void print(std::ostream &out, unsigned level) const override;
962};
963
964template<>
965struct Match<wasm::Aggregation> : wasm::MatchSingleChild
966{
968
969 Match(const AggregationOperator *aggregation, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
970 : wasm::MatchSingleChild(std::move(children))
971 , aggregation(*aggregation)
972 { }
973
974 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
975 wasm::Aggregation::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
976 }
977
978 const Operator & get_matched_root() const override { return aggregation; }
979
980 void accept(wasm::MatchBaseVisitor &v) override;
981 void accept(wasm::ConstMatchBaseVisitor &v) const override;
982
983 protected:
984 void print(std::ostream &out, unsigned level) const override;
985};
986
987template<bool CmpPredicated>
988struct Match<wasm::Quicksort<CmpPredicated>> : wasm::MatchSingleChild
989{
991 std::unique_ptr<const storage::DataLayoutFactory> materializing_factory =
993
994 Match(const SortingOperator *sorting, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
995 : wasm::MatchSingleChild(std::move(children))
996 , sorting(*sorting)
997 { }
998
999 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
1000 wasm::Quicksort<CmpPredicated>::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
1001 }
1002
1003 const Operator & get_matched_root() const override { return sorting; }
1004
1005 void accept(wasm::MatchBaseVisitor &v) override;
1006 void accept(wasm::ConstMatchBaseVisitor &v) const override;
1007
1008 protected:
1009 void print(std::ostream &out, unsigned level) const override;
1010};
1011
1012template<>
1013struct Match<wasm::NoOpSorting> : wasm::MatchSingleChild
1014{
1016
1017 Match(const SortingOperator *sorting, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
1018 : wasm::MatchSingleChild(std::move(children))
1019 , sorting(*sorting)
1020 { }
1021
1022 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
1023 wasm::NoOpSorting::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
1024 }
1025
1026 const Operator & get_matched_root() const override { return sorting; }
1027
1028 void accept(wasm::MatchBaseVisitor &v) override;
1029 void accept(wasm::ConstMatchBaseVisitor &v) const override;
1030
1031 protected:
1032 void print(std::ostream &out, unsigned level) const override;
1033};
1034
1035template<bool Predicated>
1036struct Match<wasm::NestedLoopsJoin<Predicated>> : wasm::MatchMultipleChildren
1037{
1039 std::vector<std::unique_ptr<const storage::DataLayoutFactory>> materializing_factories_;
1040 private:
1041 std::unique_ptr<const storage::DataLayoutFactory> buffer_factory_ =
1044 : std::unique_ptr<storage::DataLayoutFactory>();
1045 std::size_t buffer_num_tuples_ = options::soft_pipeline_breaker_num_tuples;
1046
1047 public:
1049 : wasm::MatchMultipleChildren(std::move(children))
1050 , join(*join)
1051 {
1052 for (std::size_t i = 0; i < children.size() - 1; ++i)
1053 materializing_factories_.push_back(M_notnull(options::hard_pipeline_breaker_layout.get())->clone());
1054 }
1055
1056 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
1057 execute_buffered(*this, join.schema(), buffer_factory_, buffer_num_tuples_,
1058 std::move(setup), std::move(pipeline), std::move(teardown));
1059 }
1060
1061 const Operator & get_matched_root() const override { return join; }
1062
1063 void accept(wasm::MatchBaseVisitor &v) override;
1064 void accept(wasm::ConstMatchBaseVisitor &v) const override;
1065
1066 protected:
1067 void print(std::ostream &out, unsigned level) const override;
1068};
1069
1070template<bool UniqueBuild, bool Predicated>
1071struct Match<wasm::SimpleHashJoin<UniqueBuild, Predicated>> : wasm::MatchMultipleChildren
1072{
1076 bool use_open_addressing_hashing =
1080 double load_factor =
1082 private:
1083 std::unique_ptr<const storage::DataLayoutFactory> buffer_factory_ =
1086 : std::unique_ptr<storage::DataLayoutFactory>();
1087 std::size_t buffer_num_tuples_ = options::soft_pipeline_breaker_num_tuples;
1088
1089 public:
1090 Match(const JoinOperator *join, const Wildcard *build, const Wildcard *probe,
1091 std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
1092 : wasm::MatchMultipleChildren(std::move(children))
1093 , join(*join)
1094 , build(*build)
1095 , probe(*probe)
1096 {
1097 M_insist(children.size() == 2);
1098 }
1099
1100 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
1101 execute_buffered(*this, join.schema(), buffer_factory_, buffer_num_tuples_,
1102 std::move(setup), std::move(pipeline), std::move(teardown));
1103 }
1104
1105 const Operator & get_matched_root() const override { return join; }
1106
1107 void accept(wasm::MatchBaseVisitor &v) override;
1108 void accept(wasm::ConstMatchBaseVisitor &v) const override;
1109
1110 protected:
1111 void print(std::ostream &out, unsigned level) const override;
1112};
1113
1114template<bool SortLeft, bool SortRight, bool Predicated, bool CmpPredicated>
1115struct Match<wasm::SortMergeJoin<SortLeft, SortRight, Predicated, CmpPredicated>> : wasm::MatchMultipleChildren
1116{
1120 std::unique_ptr<const storage::DataLayoutFactory> left_materializing_factory =
1122 std::unique_ptr<const storage::DataLayoutFactory> right_materializing_factory =
1124
1125 Match(const JoinOperator *join, const Wildcard *parent, const Wildcard *child,
1126 std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
1127 : wasm::MatchMultipleChildren(std::move(children))
1128 , join(*join)
1129 , parent(*parent)
1130 , child(*child)
1131 {
1132 M_insist(children.size() == 2);
1133 }
1134
1135 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
1137 *this, std::move(setup), std::move(pipeline), std::move(teardown)
1138 );
1139 }
1140
1141 const Operator & get_matched_root() const override { return join; }
1142
1143 void accept(wasm::MatchBaseVisitor &v) override;
1144 void accept(wasm::ConstMatchBaseVisitor &v) const override;
1145
1146 protected:
1147 void print(std::ostream &out, unsigned level) const override;
1148};
1149
1150template<>
1152{
1154
1156 : wasm::MatchSingleChild(std::move(children))
1157 , limit(*limit)
1158 { }
1159
1160 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
1161 wasm::Limit::execute(*this, std::move(setup), std::move(pipeline), std::move(teardown));
1162 }
1163
1164 const Operator & get_matched_root() const override { return limit; }
1165
1166 void accept(wasm::MatchBaseVisitor &v) override;
1167 void accept(wasm::ConstMatchBaseVisitor &v) const override;
1168
1169 protected:
1170 void print(std::ostream &out, unsigned level) const override;
1171};
1172
1173template<>
1174struct Match<wasm::HashBasedGroupJoin> : wasm::MatchMultipleChildren
1175{
1180 bool use_open_addressing_hashing =
1184 double load_factor =
1186 private:
1187 std::unique_ptr<const storage::DataLayoutFactory> buffer_factory_ =
1190 : std::unique_ptr<storage::DataLayoutFactory>();
1191 std::size_t buffer_num_tuples_ = options::soft_pipeline_breaker_num_tuples;
1192
1193 public:
1194 Match(const GroupingOperator* grouping, const JoinOperator *join, const Wildcard *build, const Wildcard *probe,
1195 std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children)
1196 : wasm::MatchMultipleChildren(std::move(children))
1197 , grouping(*grouping)
1198 , join(*join)
1199 , build(*build)
1200 , probe(*probe)
1201 {
1202 M_insist(children.size() == 2);
1203 }
1204
1205 void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override {
1206 execute_buffered(*this, grouping.schema(), buffer_factory_, buffer_num_tuples_,
1207 std::move(setup), std::move(pipeline), std::move(teardown));
1208 }
1209
1210 const Operator & get_matched_root() const override { return grouping; }
1211
1212 void accept(wasm::MatchBaseVisitor &v) override;
1213 void accept(wasm::ConstMatchBaseVisitor &v) const override;
1214
1215 protected:
1216 void print(std::ostream &out, unsigned level) const override;
1217};
1218
1219namespace wasm {
1220
1221#define M_WASM_VISITABLE_MATCH_LIST(X) \
1222 M_WASM_MATCH_LIST(X) \
1223 X(MatchLeaf) \
1224 X(MatchSingleChild) \
1225 X(MatchMultipleChildren)
1226
1229
1230
1231template<bool C>
1232struct TheRecursiveMatchBaseVisitorBase : std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>
1233{
1234 using super = std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>;
1235 template<typename T> using Const = typename super::template Const<T>;
1236
1238
1239 /* omit using super::operator() to convert to intermediate match classes and call recursive implementation */
1240 void operator()(Const<MatchBase> &M) override { super::operator()(M); }
1241 void operator()(Const<MatchLeaf>&) override { /* nothing to be done */ }
1242 void operator()(Const<MatchSingleChild> &M) override { (*this)(*M.child); }
1243 void operator()(Const<Match<Projection>> &M) override { if (M.child) (*this)(**M.child); }
1244 void operator()(Const<MatchMultipleChildren> &M) override { for (auto &c : M.children) (*this)(*c); }
1245};
1246
1248
1249template<bool C>
1250struct ThePreOrderMatchBaseVisitor : std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>
1251{
1252 using super = std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>;
1253 template<typename T> using Const = typename super::template Const<T>;
1254
1256
1257 void operator()(Const<MatchBase>&);
1258};
1259
1260template<bool C>
1261struct ThePostOrderMatchBaseVisitor : std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>
1262{
1263 using super = std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>;
1264 template<typename T> using Const = typename super::template Const<T>;
1265
1267
1268 void operator()(Const<MatchBase>&);
1269};
1270
1273
1276
1277#undef M_WASM_VISITABLE_MATCH_LIST
1278
1279}
1280
1281// delayed definitions (must occur *before* explicit instantiation below)
1282#define ACCEPT(CLASS) \
1283 inline void CLASS::accept(wasm::MatchBaseVisitor &v) { v(*this); } \
1284 inline void CLASS::accept(wasm::ConstMatchBaseVisitor &v) const { v(*this); }
1286#undef ACCEPT
1287
1288#define ACCEPT(CLASS) \
1289 template<> inline void CLASS::accept(wasm::MatchBaseVisitor &v) { v(*this); } \
1290 template<> inline void CLASS::accept(wasm::ConstMatchBaseVisitor &v) const { v(*this); }
1292#undef ACCEPT
1293
1294}
1295
1296
1297// explicit instantiation declarations
1298#define DECLARE(CLASS) \
1299 extern template struct m::wasm::CLASS; \
1300 extern template struct m::Match<m::wasm::CLASS>;
1302#undef DECLARE
#define ACCEPT(CLASS)
#define DECLARE(CLASS)
#define M_DECLARE_VISITOR(VISITOR_NAME, BASE_CLASS, CLASS_LIST)
Defines a visitor VISITOR_NAME to visit the class hierarchy rooted in BASE_CLASS and with subclasses ...
Definition: Visitor.hpp:181
#define M_MAKE_STL_VISITABLE(VISITOR, BASE_CLASS, CLASS_LIST)
Defines a function visit() to make the class hierarchy STL-style visitable with VISITOR.
Definition: Visitor.hpp:166
#define M_WASM_MATCH_LIST_NON_TEMPLATED(X)
#define M_WASM_OPERATOR_LIST_NON_TEMPLATED(X)
#define M_WASM_MATCH_LIST_TEMPLATED(X)
#define M_WASM_VISITABLE_MATCH_LIST(X)
#define DECLARE(OP)
#define M_WASM_OPERATOR_LIST_TEMPLATED(X)
#define M_CONSTEXPR_COND(COND, IF_TRUE, IF_FALSE)
Definition: macro.hpp:54
#define M_notnull(ARG)
Definition: macro.hpp:182
#define M_insist(...)
Definition: macro.hpp:129
option_configs::SoftPipelineBreakerStrategy soft_pipeline_breaker
Where soft pipeline breakers should be added.
option_configs::OrderingStrategy simple_hash_join_ordering_strategy
Which ordering strategy should be used for wasm::SimpleHashJoin.
option_configs::JoinImplementation join_implementations
Which implementations should be considered for a JoinOperator.
option_configs::StoringStrategy hash_table_storing_strategy
Which storing strategy should be used for wasm::OpenAddressingHashTables.
option_configs::IndexScanStrategy index_scan_strategy
Which index scan strategy should be used for wasm::IndexScan.
option_configs::ScanImplementation scan_implementations
Which implementations should be considered for a ScanOperator.
std::optional< uint32_t > hash_table_initial_capacity
Which initial capacity should be used for wasm::HashTables.
option_configs::IndexScanMaterializationStrategy index_scan_materialization_strategy
Which materialization strategy should be used for wasm::IndexScan.
option_configs::SortingImplementation sorting_implementations
Which implementations should be considered for a SortingOperator.
std::vector< std::pair< m::Schema::Identifier, bool > > sorted_attributes
Which attributes are assumed to be sorted.
double load_factor_open_addressing
Which maximal load factor should be used for wasm::OpenAddressingHashTables.
std::size_t index_sequential_scan_batch_size
The number of results from index sequential scan to be communicated between host and v8 per batch.
bool exploit_unique_build
Whether to exploit uniqueness of build key in hash joins.
option_configs::SelectionStrategy nested_loops_join_selection_strategy
Which selection strategy should be used for wasm::NestedLoopsJoin.
option_configs::SelectionStrategy filter_selection_strategy
Which selection strategy should be used for wasm::Filter.
bool double_pumping
Whether to use double pumping if SIMDfication is enabled.
option_configs::SelectionStrategy sort_merge_join_selection_strategy
Which selection strategy should be used for wasm::SortMergeJoin.
std::size_t soft_pipeline_breaker_num_tuples
Which size in tuples should be used for soft pipeline breakers.
option_configs::ProbingStrategy hash_table_probing_strategy
Which probing strategy should be used for wasm::OpenAddressingHashTables.
option_configs::SelectionStrategy quicksort_cmp_selection_strategy
Which selection strategy should be used for comparisons in wasm::Quicksort.
bool hash_based_group_join
Whether to use wasm::HashBasedGroupJoin if possible.
std::size_t result_set_window_size
Which window size should be used for the result set.
bool simd
Whether to use SIMDfication.
option_configs::GroupingImplementation grouping_implementations
Which implementations should be considered for a GroupingOperator.
option_configs::IndexImplementation index_implementations
Which index implementations should be considered for an IndexScan.
std::size_t simd_lanes
Which number of SIMD lanes to prefer.
std::unique_ptr< const m::storage::DataLayoutFactory > hard_pipeline_breaker_layout
Which layout factory should be used for hard pipeline breakers.
option_configs::SelectionStrategy sort_merge_join_cmp_selection_strategy
Which selection strategy should be used for comparisons while sorting in wasm::SortMergeJoin.
double load_factor_chained
Which maximal load factor should be used for wasm::ChainedHashTables.
option_configs::IndexScanCompilationStrategy index_scan_compilation_strategy
Which compilation strategy should be used for wasm::IndexScan.
std::unique_ptr< const m::storage::DataLayoutFactory > soft_pipeline_breaker_layout
Which layout factory should be used for soft pipeline breakers.
option_configs::HashTableImplementation hash_table_implementation
Which implementation should be used for wasm::HashTables.
option_configs::SelectionStrategy simple_hash_join_selection_strategy
Which selection strategy should be used for wasm::SimpleHashJoin.
typename detail::var_helper< T >::type Var
Local variable.
Definition: WasmDSL.hpp:5779
for(std::size_t idx=1;idx< num_vectors;++idx) res.emplace((vectors_[idx].bitmask()<< uint32_t(idx *vector_type return * res
Definition: WasmDSL.hpp:3696
std::pair<::wasm::Expression *, std::list< std::shared_ptr< Bit > > > move()
Moves the underlying Binaryen ::wasm::Expression and the referenced bits out of this.
Definition: WasmDSL.hpp:1567
‍mutable namespace
Definition: Backend.hpp:10
void execute_buffered(const Match< T > &M, const Schema &schema, const std::unique_ptr< const storage::DataLayoutFactory > &buffer_factory, std::size_t buffer_num_tuples, setup_t setup, pipeline_t pipeline, teardown_t teardown)
std::function< void(void)> pipeline_t
void register_wasm_operators(PhysicalOptimizer &phys_opt)
Registers physical Wasm operators in phys_opt depending on the set CLI options.
‍command-line options for the HeuristicSearchPlanEnumerator
Definition: V8Engine.cpp:44
STL namespace.
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
Match(const AggregationOperator *aggregation, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::MatchBaseVisitor &v) override
void accept(wasm::ConstMatchBaseVisitor &v) const override
void print(std::ostream &out, unsigned level) const override
const AggregationOperator & aggregation
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
void accept(wasm::ConstMatchBaseVisitor &v) const override
void accept(wasm::MatchBaseVisitor &v) override
Match(const CallbackOperator *callback, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void print(std::ostream &out, unsigned level) const override
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
Match(const FilterOperator *filter, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
void accept(wasm::MatchBaseVisitor &v) override
void print(std::ostream &out, unsigned level) const override
void accept(wasm::ConstMatchBaseVisitor &v) const override
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::ConstMatchBaseVisitor &v) const override
void accept(wasm::MatchBaseVisitor &v) override
void print(std::ostream &out, unsigned level) const override
const GroupingOperator & grouping
Match(const GroupingOperator *grouping, const JoinOperator *join, const Wildcard *build, const Wildcard *probe, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
Match(const GroupingOperator *grouping, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
const GroupingOperator & grouping
void print(std::ostream &out, unsigned level) const override
void accept(wasm::ConstMatchBaseVisitor &v) const override
void accept(wasm::MatchBaseVisitor &v) override
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void print(std::ostream &out, unsigned level) const override
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::MatchBaseVisitor &v) override
Match(const FilterOperator *filter, const ScanOperator *scan, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void accept(wasm::ConstMatchBaseVisitor &v) const override
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
void print(std::ostream &out, unsigned level) const override
void accept(wasm::MatchBaseVisitor &v) override
Match(const DisjunctiveFilterOperator *filter, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
const DisjunctiveFilterOperator & filter
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
void accept(wasm::ConstMatchBaseVisitor &v) const override
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
const LimitOperator & limit
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
Match(const LimitOperator *limit, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void accept(wasm::ConstMatchBaseVisitor &v) const override
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
void accept(wasm::MatchBaseVisitor &v) override
void print(std::ostream &out, unsigned level) const override
Match(const JoinOperator *join, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void accept(wasm::ConstMatchBaseVisitor &v) const override
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
std::vector< std::unique_ptr< const storage::DataLayoutFactory > > materializing_factories_
void accept(wasm::MatchBaseVisitor &v) override
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void print(std::ostream &out, unsigned level) const override
Match(const SortingOperator *sorting, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::MatchBaseVisitor &v) override
void print(std::ostream &out, unsigned level) const override
void accept(wasm::ConstMatchBaseVisitor &v) const override
const SortingOperator & sorting
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::MatchBaseVisitor &v) override
void accept(wasm::ConstMatchBaseVisitor &v) const override
Match(const NoOpOperator *noop, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void print(std::ostream &out, unsigned level) const override
const NoOpOperator & noop
void accept(wasm::MatchBaseVisitor &v) override
Match(const GroupingOperator *grouping, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void print(std::ostream &out, unsigned level) const override
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::ConstMatchBaseVisitor &v) const override
const GroupingOperator & grouping
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
Match(const PrintOperator *print, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void accept(wasm::MatchBaseVisitor &v) override
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
void print(std::ostream &out, unsigned level) const override
void accept(wasm::ConstMatchBaseVisitor &v) const override
Match(const ProjectionOperator *projection, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
void print(std::ostream &out, unsigned level) const override
void accept(wasm::ConstMatchBaseVisitor &v) const override
const ProjectionOperator & projection
std::optional< unsharable_shared_ptr< const wasm::MatchBase > > child
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::MatchBaseVisitor &v) override
Match(const SortingOperator *sorting, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void print(std::ostream &out, unsigned level) const override
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::MatchBaseVisitor &v) override
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
void accept(wasm::ConstMatchBaseVisitor &v) const override
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
Match(const ScanOperator *scan, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void accept(wasm::MatchBaseVisitor &v) override
void print(std::ostream &out, unsigned level) const override
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::ConstMatchBaseVisitor &v) const override
Match(const JoinOperator *join, const Wildcard *build, const Wildcard *probe, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void print(std::ostream &out, unsigned level) const override
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void accept(wasm::ConstMatchBaseVisitor &v) const override
void accept(wasm::MatchBaseVisitor &v) override
const Operator & get_matched_root() const override
Returns the matched logical root operator for physical operators.
void execute(setup_t setup, pipeline_t pipeline, teardown_t teardown) const override
Executes this physical operator match.
const Wildcard & parent
the referenced relation with unique join attributes
const Wildcard & child
the relation referencing the parent relation
Match(const JoinOperator *join, const Wildcard *parent, const Wildcard *child, std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
void print(std::ostream &out, unsigned level) const override
Drops the produced results and outputs only the number of result tuples produced.
Definition: Operator.hpp:238
An Operator represents an operation in a query plan.
Definition: Operator.hpp:45
Schema & schema()
Returns the Schema of this Operator.
Definition: Operator.hpp:67
The physical optimizer interface.
Prints the produced Tuples to a std::ostream instance.
Definition: Operator.hpp:223
A Producer is an Operator that can be evaluated to a sequence of tuples.
Definition: Operator.hpp:120
A Schema represents a sequence of identifiers, optionally with a prefix, and their associated types.
Definition: Schema.hpp:39
Schema deduplicate() const
Returns a deduplicated version of this Schema, i.e.
Definition: Schema.hpp:190
Schema drop_constants() const
Returns a copy of this Schema where all constant entries are removed.
Definition: Schema.hpp:200
static setup_t Make_Without_Parent(base_t &&callback=base_t())
static teardown_t Make_Without_Parent(base_t &&callback=base_t())
This class extends std::shared_ptr to allow for unsharing an exclusively held object and thereby conv...
static double cost(const Match< Aggregation > &)
std::conditional_t< IsGlobal, Global< T >, Var< T > > var_t_
static void execute(const Match< Aggregation > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
std::variant< var_t_< IsGlobal, I64< L > >, std::pair< var_t_< IsGlobal, I8< L > >, var_t_< IsGlobal, Bool< L > > >, std::pair< var_t_< IsGlobal, I16< L > >, var_t_< IsGlobal, Bool< L > > >, std::pair< var_t_< IsGlobal, I32< L > >, var_t_< IsGlobal, Bool< L > > >, std::pair< var_t_< IsGlobal, I64< L > >, var_t_< IsGlobal, Bool< L > > >, std::pair< var_t_< IsGlobal, Float< L > >, var_t_< IsGlobal, Bool< L > > >, std::pair< var_t_< IsGlobal, Double< L > >, var_t_< IsGlobal, Bool< L > > > > agg_t_
Buffers tuples by materializing them into memory.
Definition: WasmUtil.hpp:1070
void resume_pipeline(param_t tuple_value_schema=param_t(), param_t tuple_addr_schema=param_t()) const
Emits code into a separate function to resume the pipeline for each value tuple of schema tuple_value...
Definition: WasmUtil.cpp:2679
void consume()
Emits code to store the current tuple into the buffer.
Definition: WasmUtil.cpp:2910
void setup()
Performs the setup of all local variables of this buffer (by reading them from the global backups iff...
Definition: WasmUtil.cpp:2583
void teardown()
Performs the teardown of all local variables of this buffer (by storing them into the global backups ...
Definition: WasmUtil.cpp:2642
static double cost(const Match< Callback > &)
static void execute(const Match< Callback > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
static CodeGenContext & Get()
Definition: WasmUtil.hpp:889
static void execute(const Match< HashBasedGrouping > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
static void execute(const Match< Limit > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
static double cost(const Match< Limit > &)
An abstract MatchBase for the WasmV8 backend.
virtual void accept(MatchBaseVisitor &v)=0
virtual void accept(ConstMatchBaseVisitor &v) const =0
Intermediate match type for leaves, i.e.
Intermediate match type for physical operator matches with multiple children.
std::vector< unsharable_shared_ptr< const wasm::MatchBase > > children
MatchMultipleChildren(std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
Intermediate match type for physical operator matches with a single child.
unsharable_shared_ptr< const wasm::MatchBase > child
MatchSingleChild(std::vector< unsharable_shared_ptr< const m::MatchBase > > &&children)
static void execute(const Match< NoOpSorting > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
static double cost(const Match< NoOpSorting > &)
static void execute(const Match< NoOp > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
static double cost(const Match< NoOp > &)
std::variant< var_t_< IsGlobal, I64x1 >, std::pair< var_t_< IsGlobal, I8x1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, I16x1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, I32x1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, I64x1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, Floatx1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, Doublex1 >, std::optional< var_t_< IsGlobal, Boolx1 > > > > agg_t_
std::variant< var_t_< IsGlobal, Ptr< Charx1 > >, std::pair< var_t_< IsGlobal, Boolx1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, I8x1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, I16x1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, I32x1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, I64x1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, Floatx1 >, std::optional< var_t_< IsGlobal, Boolx1 > > >, std::pair< var_t_< IsGlobal, Doublex1 >, std::optional< var_t_< IsGlobal, Boolx1 > > > > key_t_
static void execute(const Match< OrderedGrouping > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
std::conditional_t< IsGlobal, Global< T >, Var< T > > var_t_
static double cost(const Match< Print > &)
static void execute(const Match< Print > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
static double cost(const Match< Projection > &)
static double cost(const Match< Quicksort > &)
static void execute(const Match< Quicksort > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
static double cost(const Match< Scan > &)
static void execute(const Match< Scan > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
static void execute(const Match< SortMergeJoin > &M, setup_t setup, pipeline_t pipeline, teardown_t teardown)
std::conditional_t< C, ConstMatchBaseVisitor, MatchBaseVisitor > super
void operator()(Const< MatchBase > &)
typename super::template Const< T > Const
typename super::template Const< T > Const
void operator()(Const< MatchBase > &)
std::conditional_t< C, ConstMatchBaseVisitor, MatchBaseVisitor > super
A generic base class for implementing recursive wasm::MatchBase visitors.
std::conditional_t< C, ConstMatchBaseVisitor, MatchBaseVisitor > super
void operator()(Const< MatchMultipleChildren > &M) override
void operator()(Const< Match< Projection > > &M) override
void operator()(Const< MatchBase > &M) override
typename super::template Const< T > Const
void operator()(Const< MatchLeaf > &) override
void operator()(Const< MatchSingleChild > &M) override