OmniSciDB  a987f07e93
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction Class Reference
+ Inheritance diagram for anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction:
+ Collaboration diagram for anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction:

Public Types

enum  WindowExprType { WindowExprType::PARTITION_KEY, WindowExprType::ORDER_KEY }
 

Public Member Functions

 PushDownGenericExpressionInWindowFunction (std::shared_ptr< RelProject > new_project, std::vector< std::unique_ptr< const RexScalar >> &scalar_exprs_for_new_project, std::vector< std::string > &fields_for_new_project, std::unordered_map< size_t, size_t > &expr_offset_cache)
 
size_t pushDownExpressionImpl (const RexScalar *expr) const
 
std::optional< size_t > getOffsetForPushedDownExpr (WindowExprType type, size_t expr_offset) const
 
void pushDownExpressionInWindowFunction (const RexWindowFunctionOperator *window_expr) const
 
std::unique_ptr< const RexScalarvisitInput (const RexInput *rex_input) const override
 
std::unique_ptr< const RexScalarvisitLiteral (const RexLiteral *rex_literal) const override
 
std::unique_ptr< const RexScalarvisitRef (const RexRef *rex_ref) const override
 
std::unique_ptr< const RexScalarvisitSubQuery (const RexSubQuery *rex_subquery) const override
 
std::unique_ptr< const RexScalarvisitCase (const RexCase *rex_case) const override
 
std::unique_ptr< const RexScalarvisitOperator (const RexOperator *rex_operator) const override
 
bool hasCaseExprAsWindowOperand ()
 
bool hasPartitionExpression ()
 
- Public Member Functions inherited from RexVisitorBase< std::unique_ptr< const RexScalar > >
virtual std::unique_ptr< const
RexScalar
visit (const RexScalar *rex_scalar) const
 

Private Member Functions

std::unique_ptr< const RexScalardefaultResult () const override
 

Private Attributes

std::shared_ptr< RelProjectnew_project_
 
std::vector< std::unique_ptr
< const RexScalar > > & 
scalar_exprs_for_new_project_
 
std::vector< std::string > & fields_for_new_project_
 
std::unordered_map< size_t,
size_t > & 
expr_offset_cache_
 
bool found_case_expr_window_operand_
 
bool has_partition_expr_
 
std::unordered_map< size_t,
size_t > 
pushed_down_window_operands_offset_
 
std::unordered_map< size_t,
size_t > 
pushed_down_partition_key_offset_
 
std::unordered_map< size_t,
size_t > 
pushed_down_order_key_offset_
 
RexDeepCopyVisitor deep_copier_
 

Additional Inherited Members

Detailed Description

Definition at line 124 of file RelAlgDag.cpp.

Member Enumeration Documentation

enum anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::WindowExprType
strong
Enumerator
PARTITION_KEY 
ORDER_KEY 

Definition at line 127 of file RelAlgDag.cpp.

127 { PARTITION_KEY, ORDER_KEY };

Constructor & Destructor Documentation

anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::PushDownGenericExpressionInWindowFunction ( std::shared_ptr< RelProject new_project,
std::vector< std::unique_ptr< const RexScalar >> &  scalar_exprs_for_new_project,
std::vector< std::string > &  fields_for_new_project,
std::unordered_map< size_t, size_t > &  expr_offset_cache 
)
inline

Member Function Documentation

std::unique_ptr<const RexScalar> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::defaultResult ( ) const
inlineoverrideprivatevirtual

Implements RexVisitorBase< std::unique_ptr< const RexScalar > >.

Definition at line 329 of file RelAlgDag.cpp.

329 { return nullptr; }
std::optional<size_t> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::getOffsetForPushedDownExpr ( WindowExprType  type,
size_t  expr_offset 
) const
inline

Definition at line 157 of file RelAlgDag.cpp.

References CHECK, and UNREACHABLE.

158  {
159  // given window expr offset and inner expr's offset,
160  // return a (push-downed) expression's offset from the new projection node
161  switch (type) {
163  auto it = pushed_down_partition_key_offset_.find(expr_offset);
165  return it->second;
166  }
168  auto it = pushed_down_order_key_offset_.find(expr_offset);
170  return it->second;
171  }
172  default:
173  UNREACHABLE();
174  return std::nullopt;
175  }
176  }
#define UNREACHABLE()
Definition: Logger.h:333
#define CHECK(condition)
Definition: Logger.h:289
bool anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::hasCaseExprAsWindowOperand ( )
inline
bool anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::hasPartitionExpression ( )
inline
size_t anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::pushDownExpressionImpl ( const RexScalar expr) const
inline

Definition at line 140 of file RelAlgDag.cpp.

References CHECK, and Rex::toHash().

140  {
141  auto hash = expr->toHash();
142  auto it = expr_offset_cache_.find(hash);
143  auto new_offset = -1;
144  if (it == expr_offset_cache_.end()) {
145  CHECK(
146  expr_offset_cache_.emplace(hash, scalar_exprs_for_new_project_.size()).second);
147  new_offset = scalar_exprs_for_new_project_.size();
148  fields_for_new_project_.emplace_back("");
150  } else {
151  // we already pushed down the same expression, so reuse it
152  new_offset = it->second;
153  }
154  return new_offset;
155  }
std::vector< std::unique_ptr< const RexScalar > > & scalar_exprs_for_new_project_
Definition: RelAlgDag.cpp:332
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
#define CHECK(condition)
Definition: Logger.h:289
virtual size_t toHash() const =0

+ Here is the call graph for this function:

void anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::pushDownExpressionInWindowFunction ( const RexWindowFunctionOperator window_expr) const
inline

Definition at line 178 of file RelAlgDag.cpp.

References CHECK, RexOperator::getOperand(), RexWindowFunctionOperator::getOrderKeys(), RexWindowFunctionOperator::getPartitionKeys(), and RexOperator::size().

179  {
180  // step 1. push "all" target expressions of the window_func_project_node down to the
181  // new child projection
182  // each window expr is a separate target expression of the projection node
183  // and they have their own inner expression related to partition / order clauses
184  // so we capture their offsets to correctly rebind their input
188  for (size_t offset = 0; offset < window_expr->size(); ++offset) {
189  auto expr = window_expr->getOperand(offset);
190  auto literal_expr = dynamic_cast<const RexLiteral*>(expr);
191  auto case_expr = dynamic_cast<const RexCase*>(expr);
192  if (case_expr) {
193  // when columnar output is enabled, pushdown case expr can incur an issue
194  // during columnarization, so we record this and try to force rowwise-output
195  // until we fix the issue
196  // todo (yoonmin) : relax this
198  }
199  if (!literal_expr) {
200  auto new_offset = pushDownExpressionImpl(expr);
201  pushed_down_window_operands_offset_.emplace(offset, new_offset);
202  }
203  }
204  size_t offset = 0;
205  for (const auto& partition_key : window_expr->getPartitionKeys()) {
206  auto new_offset = pushDownExpressionImpl(partition_key.get());
207  pushed_down_partition_key_offset_.emplace(offset, new_offset);
208  ++offset;
209  }
210  has_partition_expr_ = !window_expr->getPartitionKeys().empty();
211  offset = 0;
212  for (const auto& order_key : window_expr->getOrderKeys()) {
213  auto new_offset = pushDownExpressionImpl(order_key.get());
214  pushed_down_order_key_offset_.emplace(offset, new_offset);
215  ++offset;
216  }
217 
218  // step 2. rebind projected targets of the window_func_project_node with the new
219  // project node
220  std::vector<std::unique_ptr<const RexScalar>> window_operands;
221  auto deconst_window_expr = const_cast<RexWindowFunctionOperator*>(window_expr);
222  for (size_t idx = 0; idx < window_expr->size(); ++idx) {
223  auto it = pushed_down_window_operands_offset_.find(idx);
224  if (it != pushed_down_window_operands_offset_.end()) {
225  auto new_input = std::make_unique<const RexInput>(new_project_.get(), it->second);
226  CHECK(new_input);
227  window_operands.emplace_back(std::move(new_input));
228  } else {
229  auto copied_expr = deep_copier_.visit(window_expr->getOperand(idx));
230  window_operands.emplace_back(std::move(copied_expr));
231  }
232  }
233  deconst_window_expr->replaceOperands(std::move(window_operands));
234 
235  for (size_t idx = 0; idx < window_expr->getPartitionKeys().size(); ++idx) {
237  CHECK(new_offset);
238  auto new_input = std::make_unique<const RexInput>(new_project_.get(), *new_offset);
239  CHECK(new_input);
240  deconst_window_expr->replacePartitionKey(idx, std::move(new_input));
241  }
242 
243  for (size_t idx = 0; idx < window_expr->getOrderKeys().size(); ++idx) {
245  CHECK(new_offset);
246  auto new_input = std::make_unique<const RexInput>(new_project_.get(), *new_offset);
247  CHECK(new_input);
248  deconst_window_expr->replaceOrderKey(idx, std::move(new_input));
249  }
250  }
std::optional< size_t > getOffsetForPushedDownExpr(WindowExprType type, size_t expr_offset) const
Definition: RelAlgDag.cpp:157
size_t size() const
Definition: RelAlgDag.h:270
const RexScalar * getOperand(const size_t idx) const
Definition: RelAlgDag.h:272
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
const ConstRexScalarPtrVector & getPartitionKeys() const
Definition: RelAlgDag.h:627
#define CHECK(condition)
Definition: Logger.h:289
const ConstRexScalarPtrVector & getOrderKeys() const
Definition: RelAlgDag.h:637

+ Here is the call graph for this function:

std::unique_ptr<const RexScalar> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::visitCase ( const RexCase rex_case) const
inlineoverridevirtual

Implements RexVisitorBase< std::unique_ptr< const RexScalar > >.

Definition at line 278 of file RelAlgDag.cpp.

References RexCase::branchCount(), RexCase::getElse(), RexCase::getThen(), and RexCase::getWhen().

278  {
279  std::vector<
280  std::pair<std::unique_ptr<const RexScalar>, std::unique_ptr<const RexScalar>>>
281  new_expr_pair_list;
282  std::unique_ptr<const RexScalar> new_else_expr;
283  for (size_t i = 0; i < rex_case->branchCount(); ++i) {
284  const auto when = rex_case->getWhen(i);
286  const auto then = rex_case->getThen(i);
288  new_expr_pair_list.emplace_back(std::move(new_when), std::move(new_then));
289  }
290  if (rex_case->getElse()) {
291  new_else_expr = deep_copier_.visit(rex_case->getElse());
292  }
293  auto new_case = std::make_unique<const RexCase>(new_expr_pair_list, new_else_expr);
294  return new_case;
295  }
const RexScalar * getThen(const size_t idx) const
Definition: RelAlgDag.h:443
const RexScalar * getElse() const
Definition: RelAlgDag.h:448
const RexScalar * getWhen(const size_t idx) const
Definition: RelAlgDag.h:438
virtual std::unique_ptr< const RexScalar > visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
size_t branchCount() const
Definition: RelAlgDag.h:436

+ Here is the call graph for this function:

std::unique_ptr<const RexScalar> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::visitInput ( const RexInput rex_input) const
inlineoverridevirtual

Implements RexVisitorBase< std::unique_ptr< const RexScalar > >.

Definition at line 252 of file RelAlgDag.cpp.

References CHECK, CHECK_EQ, CHECK_LT, and RexInput::toHash().

252  {
253  auto new_offset = pushDownExpressionImpl(rex_input);
254  CHECK_LT(new_offset, scalar_exprs_for_new_project_.size());
255  auto hash = rex_input->toHash();
256  auto it = expr_offset_cache_.find(hash);
257  CHECK(it != expr_offset_cache_.end());
258  CHECK_EQ(new_offset, it->second);
259  auto new_input = std::make_unique<const RexInput>(new_project_.get(), new_offset);
260  CHECK(new_input);
261  return new_input;
262  }
#define CHECK_EQ(x, y)
Definition: Logger.h:297
std::vector< std::unique_ptr< const RexScalar > > & scalar_exprs_for_new_project_
Definition: RelAlgDag.cpp:332
size_t toHash() const override
Definition: RelAlgDag.cpp:3395
#define CHECK_LT(x, y)
Definition: Logger.h:299
#define CHECK(condition)
Definition: Logger.h:289

+ Here is the call graph for this function:

std::unique_ptr<const RexScalar> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::visitLiteral ( const RexLiteral rex_literal) const
inlineoverridevirtual

Implements RexVisitorBase< std::unique_ptr< const RexScalar > >.

Definition at line 264 of file RelAlgDag.cpp.

265  {
266  return deep_copier_.visit(rex_literal);
267  }
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
std::unique_ptr<const RexScalar> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::visitOperator ( const RexOperator rex_operator) const
inlineoverridevirtual

Implements RexVisitorBase< std::unique_ptr< const RexScalar > >.

Definition at line 297 of file RelAlgDag.cpp.

References CHECK, RexOperator::getOperand(), RexOperator::getOperator(), RexOperator::getType(), and RexOperator::size().

298  {
299  const auto rex_window_func_operator =
300  dynamic_cast<const RexWindowFunctionOperator*>(rex_operator);
301  if (rex_window_func_operator) {
302  pushDownExpressionInWindowFunction(rex_window_func_operator);
303  return deep_copier_.visit(rex_operator);
304  } else {
305  std::unique_ptr<const RexOperator> new_operator{nullptr};
306  std::vector<std::unique_ptr<const RexScalar>> new_operands;
307  for (size_t i = 0; i < rex_operator->size(); ++i) {
308  const auto operand = rex_operator->getOperand(i);
309  auto new_operand = PushDownGenericExpressionInWindowFunction::visit(operand);
310  new_operands.emplace_back(std::move(new_operand));
311  }
312  if (auto function_op = dynamic_cast<const RexFunctionOperator*>(rex_operator)) {
313  new_operator = std::make_unique<const RexFunctionOperator>(
314  function_op->getName(), new_operands, rex_operator->getType());
315  } else {
316  new_operator = std::make_unique<const RexOperator>(
317  rex_operator->getOperator(), new_operands, rex_operator->getType());
318  }
319  CHECK(new_operator);
320  return new_operator;
321  }
322  }
const SQLTypeInfo & getType() const
Definition: RelAlgDag.h:284
size_t size() const
Definition: RelAlgDag.h:270
const RexScalar * getOperand(const size_t idx) const
Definition: RelAlgDag.h:272
void pushDownExpressionInWindowFunction(const RexWindowFunctionOperator *window_expr) const
Definition: RelAlgDag.cpp:178
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
SQLOps getOperator() const
Definition: RelAlgDag.h:282
#define CHECK(condition)
Definition: Logger.h:289

+ Here is the call graph for this function:

std::unique_ptr<const RexScalar> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::visitRef ( const RexRef rex_ref) const
inlineoverridevirtual

Implements RexVisitorBase< std::unique_ptr< const RexScalar > >.

Definition at line 269 of file RelAlgDag.cpp.

269  {
270  return deep_copier_.visit(rex_ref);
271  }
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27
std::unique_ptr<const RexScalar> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::visitSubQuery ( const RexSubQuery rex_subquery) const
inlineoverridevirtual

Implements RexVisitorBase< std::unique_ptr< const RexScalar > >.

Definition at line 273 of file RelAlgDag.cpp.

274  {
275  return deep_copier_.visit(rex_subquery);
276  }
virtual T visit(const RexScalar *rex_scalar) const
Definition: RexVisitor.h:27

Member Data Documentation

RexDeepCopyVisitor anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::deep_copier_
private

Definition at line 340 of file RelAlgDag.cpp.

std::unordered_map<size_t, size_t>& anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::expr_offset_cache_
private

Definition at line 334 of file RelAlgDag.cpp.

std::vector<std::string>& anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::fields_for_new_project_
private

Definition at line 333 of file RelAlgDag.cpp.

bool anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::found_case_expr_window_operand_
mutableprivate

Definition at line 335 of file RelAlgDag.cpp.

bool anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::has_partition_expr_
mutableprivate

Definition at line 336 of file RelAlgDag.cpp.

std::shared_ptr<RelProject> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::new_project_
private

Definition at line 331 of file RelAlgDag.cpp.

std::unordered_map<size_t, size_t> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::pushed_down_order_key_offset_
mutableprivate

Definition at line 339 of file RelAlgDag.cpp.

std::unordered_map<size_t, size_t> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::pushed_down_partition_key_offset_
mutableprivate

Definition at line 338 of file RelAlgDag.cpp.

std::unordered_map<size_t, size_t> anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::pushed_down_window_operands_offset_
mutableprivate

Definition at line 337 of file RelAlgDag.cpp.

std::vector<std::unique_ptr<const RexScalar> >& anonymous_namespace{RelAlgDag.cpp}::PushDownGenericExpressionInWindowFunction::scalar_exprs_for_new_project_
private

Definition at line 332 of file RelAlgDag.cpp.


The documentation for this class was generated from the following file: