OmniSciDB  5ade3759e0
ExpressionRewrite.cpp File Reference
#include "ExpressionRewrite.h"
#include "../Analyzer/Analyzer.h"
#include "../Shared/sqldefs.h"
#include "DeepCopyVisitor.h"
#include "Execute.h"
#include "RelAlgTranslator.h"
#include "ScalarExprVisitor.h"
#include "Shared/Logger.h"
#include "WindowExpressionRewrite.h"
#include <unordered_set>
+ Include dependency graph for ExpressionRewrite.cpp:

Go to the source code of this file.

Classes

class  anonymous_namespace{ExpressionRewrite.cpp}::OrToInVisitor
 
class  anonymous_namespace{ExpressionRewrite.cpp}::RecursiveOrToInVisitor
 
class  anonymous_namespace{ExpressionRewrite.cpp}::ArrayElementStringLiteralEncodingVisitor
 
class  anonymous_namespace{ExpressionRewrite.cpp}::ConstantFoldingVisitor
 
class  JoinCoveredQualVisitor
 

Namespaces

 anonymous_namespace{ExpressionRewrite.cpp}
 

Functions

const Analyzer::Expranonymous_namespace{ExpressionRewrite.cpp}::strip_likelihood (const Analyzer::Expr *expr)
 
Analyzer::ExpressionPtr rewrite_array_elements (Analyzer::Expr const *expr)
 
Analyzer::ExpressionPtr rewrite_expr (const Analyzer::Expr *expr)
 
boost::optional< OverlapsJoinConjunctionrewrite_overlaps_conjunction (const std::shared_ptr< Analyzer::Expr > expr)
 
std::list< std::shared_ptr< Analyzer::Expr > > strip_join_covered_filter_quals (const std::list< std::shared_ptr< Analyzer::Expr >> &quals, const JoinQualsPerNestingLevel &join_quals)
 
std::shared_ptr< Analyzer::Exprfold_expr (const Analyzer::Expr *expr)
 

Variables

static const std::unordered_set< std::string > anonymous_namespace{ExpressionRewrite.cpp}::overlaps_supported_functions
 

Function Documentation

◆ fold_expr()

std::shared_ptr<Analyzer::Expr> fold_expr ( const Analyzer::Expr expr)

Definition at line 823 of file ExpressionRewrite.cpp.

References kBIGINT, and anonymous_namespace{ExpressionRewrite.cpp}::strip_likelihood().

Referenced by RelAlgExecutor::createFilterWorkUnit(), anonymous_namespace{RelAlgExecutor.cpp}::set_transient_dict_maybe(), anonymous_namespace{RelAlgExecutor.cpp}::translate_quals(), anonymous_namespace{RelAlgExecutor.cpp}::translate_targets(), anonymous_namespace{RelAlgExecutor.cpp}::translate_targets_for_update(), RelAlgTranslator::translateDateadd(), RelAlgTranslator::translateDatePlusMinus(), RelAlgTranslator::translateGeoComparison(), RelAlgTranslator::translateGeoFunctionArg(), and RelAlgTranslator::translateTernaryGeoFunction().

823  {
824  if (!expr) {
825  return nullptr;
826  }
827  const auto expr_no_likelihood = strip_likelihood(expr);
828  ConstantFoldingVisitor visitor;
829  auto rewritten_expr = visitor.visit(expr_no_likelihood);
830  if (visitor.get_num_overflows() > 0 && rewritten_expr->get_type_info().is_integer() &&
831  rewritten_expr->get_type_info().get_type() != kBIGINT) {
832  auto rewritten_expr_const =
833  std::dynamic_pointer_cast<const Analyzer::Constant>(rewritten_expr);
834  if (!rewritten_expr_const) {
835  // Integer expression didn't fold completely the first time due to
836  // overflows in smaller type subexpressions, trying again with a cast
837  const auto& ti = SQLTypeInfo(kBIGINT, false);
838  auto bigint_expr_no_likelihood = expr_no_likelihood->deep_copy()->add_cast(ti);
839  auto rewritten_expr_take2 = visitor.visit(bigint_expr_no_likelihood.get());
840  auto rewritten_expr_take2_const =
841  std::dynamic_pointer_cast<Analyzer::Constant>(rewritten_expr_take2);
842  if (rewritten_expr_take2_const) {
843  // Managed to fold, switch to the new constant
844  rewritten_expr = rewritten_expr_take2_const;
845  }
846  }
847  }
848  const auto expr_with_likelihood = dynamic_cast<const Analyzer::LikelihoodExpr*>(expr);
849  if (expr_with_likelihood) {
850  // Add back likelihood
851  return std::make_shared<Analyzer::LikelihoodExpr>(
852  rewritten_expr, expr_with_likelihood->get_likelihood());
853  }
854  return rewritten_expr;
855 }
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:823
const Analyzer::Expr * strip_likelihood(const Analyzer::Expr *expr)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rewrite_array_elements()

Analyzer::ExpressionPtr rewrite_array_elements ( Analyzer::Expr const *  expr)

Definition at line 676 of file ExpressionRewrite.cpp.

Referenced by anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources(), and anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources_for_update().

676  {
677  return ArrayElementStringLiteralEncodingVisitor().visit(expr);
678 }
+ Here is the caller graph for this function:

◆ rewrite_expr()

Analyzer::ExpressionPtr rewrite_expr ( const Analyzer::Expr expr)

Definition at line 680 of file ExpressionRewrite.cpp.

References rewrite_avg_window(), rewrite_sum_window(), and anonymous_namespace{ExpressionRewrite.cpp}::strip_likelihood().

Referenced by RelAlgExecutor::createFilterWorkUnit(), qual_to_conjunctive_form(), qual_to_disjunctive_form(), anonymous_namespace{RelAlgExecutor.cpp}::rewrite_quals(), QueryRewriter::rewriteConstrainedByIn(), anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources(), anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources_for_update(), anonymous_namespace{RelAlgExecutor.cpp}::translate_targets(), and anonymous_namespace{RelAlgExecutor.cpp}::translate_targets_for_update().

680  {
681  const auto sum_window = rewrite_sum_window(expr);
682  if (sum_window) {
683  return sum_window;
684  }
685  const auto avg_window = rewrite_avg_window(expr);
686  if (avg_window) {
687  return avg_window;
688  }
689  const auto expr_no_likelihood = strip_likelihood(expr);
690  // The following check is not strictly needed, but seems silly to transform a
691  // simple string comparison to an IN just to codegen the same thing anyway.
692 
693  RecursiveOrToInVisitor visitor;
694  auto rewritten_expr = visitor.visit(expr_no_likelihood);
695  const auto expr_with_likelihood =
696  std::dynamic_pointer_cast<const Analyzer::LikelihoodExpr>(rewritten_expr);
697  if (expr_with_likelihood) {
698  // Add back likelihood
699  return std::make_shared<Analyzer::LikelihoodExpr>(
700  rewritten_expr, expr_with_likelihood->get_likelihood());
701  }
702  return rewritten_expr;
703 }
std::shared_ptr< Analyzer::WindowFunction > rewrite_avg_window(const Analyzer::Expr *expr)
std::shared_ptr< Analyzer::WindowFunction > rewrite_sum_window(const Analyzer::Expr *expr)
const Analyzer::Expr * strip_likelihood(const Analyzer::Expr *expr)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rewrite_overlaps_conjunction()

boost::optional<OverlapsJoinConjunction> rewrite_overlaps_conjunction ( const std::shared_ptr< Analyzer::Expr expr)

Definition at line 713 of file ExpressionRewrite.cpp.

References CHECK, CHECK_GE, kBOOLEAN, kONE, kOVERLAPS, LOG, anonymous_namespace{ExpressionRewrite.cpp}::overlaps_supported_functions, ScalarExprVisitor< T >::visit(), and logger::WARNING.

Referenced by QueryRewriter::rewriteOverlapsJoin().

714  {
715  auto func_oper = dynamic_cast<Analyzer::FunctionOper*>(expr.get());
716  if (func_oper) {
717  // TODO(adb): consider converting unordered set to an unordered map, potentially
718  // storing the rewrite function we want to apply in the map
719  if (overlaps_supported_functions.find(func_oper->getName()) !=
721  CHECK_GE(func_oper->getArity(), size_t(3));
722 
723  DeepCopyVisitor deep_copy_visitor;
724  auto lhs = func_oper->getOwnArg(2);
725  auto rewritten_lhs = deep_copy_visitor.visit(lhs.get());
726  CHECK(rewritten_lhs);
727  const auto& lhs_ti = rewritten_lhs->get_type_info();
728  if (!lhs_ti.is_geometry()) {
729  // TODO(adb): If ST_Contains is passed geospatial literals instead of columns, the
730  // function will be expanded during translation rather than during code
731  // generation. While this scenario does not make sense for the overlaps join, we
732  // need to detect and abort the overlaps rewrite. Adding a GeospatialConstant
733  // dervied class to the Analyzer may prove to be a better way to handle geo
734  // literals, but for now we ensure the LHS type is a geospatial type, which would
735  // mean the function has not been expanded to the physical types, yet.
736  LOG(WARNING) << "Failed to rewrite " << func_oper->getName()
737  << " to overlaps conjunction. LHS input type is not a geospatial "
738  "type. Are both inputs geospatial columns?";
739  return boost::none;
740  }
741 
742  // Read the bounds arg from the ST_Contains FuncOper (second argument)instead of the
743  // poly column (first argument)
744  auto rhs = func_oper->getOwnArg(1);
745  auto rewritten_rhs = deep_copy_visitor.visit(rhs.get());
746  CHECK(rewritten_rhs);
747 
748  auto overlaps_oper = makeExpr<Analyzer::BinOper>(
749  kBOOLEAN, kOVERLAPS, kONE, rewritten_lhs, rewritten_rhs);
750 
751  return OverlapsJoinConjunction{{expr}, {overlaps_oper}};
752  }
753  }
754  return boost::none;
755 }
#define LOG(tag)
Definition: Logger.h:182
#define CHECK_GE(x, y)
Definition: Logger.h:200
static const std::unordered_set< std::string > overlaps_supported_functions
Definition: sqldefs.h:69
T visit(const Analyzer::Expr *expr) const
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ strip_join_covered_filter_quals()

std::list<std::shared_ptr<Analyzer::Expr> > strip_join_covered_filter_quals ( const std::list< std::shared_ptr< Analyzer::Expr >> &  quals,
const JoinQualsPerNestingLevel join_quals 
)

Definition at line 799 of file ExpressionRewrite.cpp.

References g_strip_join_covered_quals, and ScalarExprVisitor< T >::visit().

Referenced by create_count_all_execution_unit().

801  {
803  return quals;
804  }
805 
806  if (join_quals.empty()) {
807  return quals;
808  }
809 
810  std::list<std::shared_ptr<Analyzer::Expr>> quals_to_return;
811 
812  JoinCoveredQualVisitor visitor(join_quals);
813  for (const auto& qual : quals) {
814  if (!visitor.visit(qual.get())) {
815  // Not a covered qual, don't elide it from the filtered count
816  quals_to_return.push_back(qual);
817  }
818  }
819 
820  return quals_to_return;
821 }
bool g_strip_join_covered_quals
Definition: Execute.cpp:88
+ Here is the call graph for this function:
+ Here is the caller graph for this function: