OmniSciDB  c07336695a
WindowContext.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "../Analyzer/Analyzer.h"
20 #include "../Chunk/Chunk.h"
21 #include "JoinHashTableInterface.h"
22 
23 #include <functional>
24 #include <unordered_map>
25 
26 // Returns true for value window functions, false otherwise.
28  switch (kind) {
33  return true;
34  }
35  default: {
36  return false;
37  }
38  }
39 }
40 
41 // Returns true for aggregate window functions, false otherwise.
43  switch (kind) {
50  return true;
51  }
52  default: {
53  return false;
54  }
55  }
56 }
57 
58 // Per-window function context which encapsulates the logic for computing the various
59 // window function kinds and keeps ownership of buffers which contain the results. For
60 // rank functions, the code generated for the projection simply reads the values and
61 // writes them to the result set. For value and aggregate functions, only the iteration
62 // order is written to the buffer, the rest is handled by generating code in a similar way
63 // we do for non-window queries.
65  public:
67  const std::shared_ptr<JoinHashTableInterface>& partitions,
68  const size_t elem_count,
69  const ExecutorDeviceType device_type);
70 
72 
74 
76 
77  // Adds the order column buffer to the context and keeps ownership of it.
78  void addOrderColumn(const int8_t* column,
79  const Analyzer::ColumnVar* col_var,
80  const std::vector<std::shared_ptr<Chunk_NS::Chunk>>& chunks_owner);
81 
82  // Computes the window function result to be used during the actual projection query.
83  void compute();
84 
85  // Returns a pointer to the window function associated with this context.
87 
88  // Returns a pointer to the output buffer of the window function result.
89  const int8_t* output() const;
90 
91  // Returns a pointer to the value field of the aggregation state.
92  const int64_t* aggregateState() const;
93 
94  // Returns a pointer to the count field of the aggregation state.
95  const int64_t* aggregateStateCount() const;
96 
97  // Returns a handle to the pending outputs for the aggregate window function.
98  int64_t aggregateStatePendingOutputs() const;
99 
100  // Returns a pointer to the partition start bitmap.
101  const int8_t* partitionStart() const;
102 
103  // Returns a pointer to the partition end bitmap.
104  const int8_t* partitionEnd() const;
105 
106  // Returns the element count in the columns used by the window function.
107  size_t elementCount() const;
108 
109  // Sets the row number expression for this window function.
110  void setRowNumber(llvm::Value* row_number);
111 
112  // Gets the row number expression for this window function.
113  llvm::Value* getRowNumber() const;
114 
115  using Comparator = std::function<bool(const int64_t lhs, const int64_t rhs)>;
116 
117  private:
118  // State for a window aggregate. The count field is only used for average.
119  struct AggregateState {
120  int64_t val;
121  int64_t count;
122  std::vector<void*> outputs;
123  llvm::Value* row_number = nullptr;
124  };
125 
126  static Comparator makeComparator(const Analyzer::ColumnVar* col_var,
127  const int8_t* partition_values,
128  const int32_t* partition_indices,
129  const bool nulls_first);
130 
131  void computePartition(
132  int64_t* output_for_partition_buff,
133  const size_t partition_size,
134  const size_t off,
135  const Analyzer::WindowFunction* window_func,
136  const std::function<bool(const int64_t lhs, const int64_t rhs)>& comparator);
137 
138  void fillPartitionStart();
139 
140  void fillPartitionEnd();
141 
142  const int32_t* payload() const;
143 
144  const int32_t* offsets() const;
145 
146  const int32_t* counts() const;
147 
148  size_t partitionCount() const;
149 
151  // Keeps ownership of order column.
152  std::vector<std::vector<std::shared_ptr<Chunk_NS::Chunk>>> order_columns_owner_;
153  // Order column buffers.
154  std::vector<const int8_t*> order_columns_;
155  // Hash table which contains the partitions specified by the window.
156  std::shared_ptr<JoinHashTableInterface> partitions_;
157  // The number of elements in the table.
158  size_t elem_count_;
159  // The output of the window function.
160  int8_t* output_;
161  // Markers for partition start used to reinitialize state for aggregate window
162  // functions.
164  // Markers for partition start used to reinitialize state for aggregate window
165  // functions.
166  int8_t* partition_end_;
167  // State for aggregate function over a window.
170 };
171 
172 // Keeps track of the multiple window functions in a window query.
174  public:
175  void addWindowFunctionContext(
176  std::unique_ptr<WindowFunctionContext> window_function_context,
177  const size_t target_index);
178 
179  // Marks the window function at the given target index as active. This simplifies the
180  // code generation since it's now context sensitive. Each value window function can have
181  // its own iteration order, therefore fetching a column at a given position changes
182  // depending on which window function is active.
183  const WindowFunctionContext* activateWindowFunctionContext(
184  const size_t target_index) const;
185 
186  // Resets the active window function, which restores the regular (non-window) codegen
187  // behavior.
188  static void resetWindowFunctionContext();
189 
190  // Gets the current active window function.
191  static WindowFunctionContext* getActiveWindowFunctionContext();
192 
193  // Creates the context for a window function execution unit.
195 
196  // Retrieves the context for the active window function execution unit.
197  static const WindowProjectNodeContext* get();
198 
199  // Resets the active context.
200  static void reset();
201 
202  private:
203  // A map from target index to the context associated with the window function at that
204  // target index.
205  std::unordered_map<size_t, std::unique_ptr<WindowFunctionContext>> window_contexts_;
206  // Singleton instance used for an execution unit which is a project with window
207  // functions.
208  static std::unique_ptr<WindowProjectNodeContext> s_instance_;
209  // The active window function. Method comments in this class describe how it's used.
211 };
212 
214 
size_t elementCount() const
static WindowFunctionContext * s_active_window_function_
const int32_t * payload() const
static std::unique_ptr< WindowProjectNodeContext > s_instance_
ExecutorDeviceType
const int32_t * counts() const
std::function< bool(const int64_t lhs, const int64_t rhs)> Comparator
const Analyzer::WindowFunction * window_func_
size_t partitionCount() const
void computePartition(int64_t *output_for_partition_buff, const size_t partition_size, const size_t off, const Analyzer::WindowFunction *window_func, const std::function< bool(const int64_t lhs, const int64_t rhs)> &comparator)
AggregateState aggregate_state_
bool window_function_is_value(const SqlWindowFunctionKind kind)
Definition: WindowContext.h:27
const Analyzer::WindowFunction * getWindowFunction() const
void setRowNumber(llvm::Value *row_number)
const int64_t * aggregateState() const
static Comparator makeComparator(const Analyzer::ColumnVar *col_var, const int8_t *partition_values, const int32_t *partition_indices, const bool nulls_first)
WindowFunctionContext & operator=(const WindowFunctionContext &)=delete
std::shared_ptr< JoinHashTableInterface > partitions_
llvm::Value * getRowNumber() const
bool window_function_is_aggregate(const SqlWindowFunctionKind kind)
Definition: WindowContext.h:42
int64_t aggregateStatePendingOutputs() const
const int8_t * partitionStart() const
const int32_t * offsets() const
const int64_t * aggregateStateCount() const
SqlWindowFunctionKind
Definition: sqldefs.h:73
const int8_t * output() const
std::unordered_map< size_t, std::unique_ptr< WindowFunctionContext > > window_contexts_
std::vector< const int8_t * > order_columns_
WindowFunctionContext(const Analyzer::WindowFunction *window_func, const std::shared_ptr< JoinHashTableInterface > &partitions, const size_t elem_count, const ExecutorDeviceType device_type)
bool window_function_requires_peer_handling(const Analyzer::WindowFunction *window_func)
const int8_t * partitionEnd() const
std::vector< std::vector< std::shared_ptr< Chunk_NS::Chunk > > > order_columns_owner_
void addOrderColumn(const int8_t *column, const Analyzer::ColumnVar *col_var, const std::vector< std::shared_ptr< Chunk_NS::Chunk >> &chunks_owner)
const ExecutorDeviceType device_type_