OmniSciDB  b24e664e58
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ExpressionRewrite.h File Reference
#include <boost/optional.hpp>
#include <list>
#include <memory>
#include <vector>
#include "Analyzer/Analyzer.h"
#include "RelAlgExecutionUnit.h"
+ Include dependency graph for ExpressionRewrite.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  OverlapsJoinConjunction
 

Namespaces

 Analyzer
 

Functions

Analyzer::ExpressionPtr rewrite_expr (const Analyzer::Expr *)
 
Analyzer::ExpressionPtr rewrite_array_elements (const Analyzer::Expr *)
 
boost::optional
< OverlapsJoinConjunction
rewrite_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 *)
 

Function Documentation

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

Definition at line 836 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().

836  {
837  if (!expr) {
838  return nullptr;
839  }
840  const auto expr_no_likelihood = strip_likelihood(expr);
841  ConstantFoldingVisitor visitor;
842  auto rewritten_expr = visitor.visit(expr_no_likelihood);
843  if (visitor.get_num_overflows() > 0 && rewritten_expr->get_type_info().is_integer() &&
844  rewritten_expr->get_type_info().get_type() != kBIGINT) {
845  auto rewritten_expr_const =
846  std::dynamic_pointer_cast<const Analyzer::Constant>(rewritten_expr);
847  if (!rewritten_expr_const) {
848  // Integer expression didn't fold completely the first time due to
849  // overflows in smaller type subexpressions, trying again with a cast
850  const auto& ti = SQLTypeInfo(kBIGINT, false);
851  auto bigint_expr_no_likelihood = expr_no_likelihood->deep_copy()->add_cast(ti);
852  auto rewritten_expr_take2 = visitor.visit(bigint_expr_no_likelihood.get());
853  auto rewritten_expr_take2_const =
854  std::dynamic_pointer_cast<Analyzer::Constant>(rewritten_expr_take2);
855  if (rewritten_expr_take2_const) {
856  // Managed to fold, switch to the new constant
857  rewritten_expr = rewritten_expr_take2_const;
858  }
859  }
860  }
861  const auto expr_with_likelihood = dynamic_cast<const Analyzer::LikelihoodExpr*>(expr);
862  if (expr_with_likelihood) {
863  // Add back likelihood
864  return std::make_shared<Analyzer::LikelihoodExpr>(
865  rewritten_expr, expr_with_likelihood->get_likelihood());
866  }
867  return rewritten_expr;
868 }
SQLTypeInfoCore< ArrayContextTypeSizer, ExecutorTypePackaging, DateTimeFacilities > SQLTypeInfo
Definition: sqltypes.h:852
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:

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

Definition at line 689 of file ExpressionRewrite.cpp.

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

689  {
690  return ArrayElementStringLiteralEncodingVisitor().visit(expr);
691 }

+ Here is the caller graph for this function:

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

Definition at line 693 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().

693  {
694  const auto sum_window = rewrite_sum_window(expr);
695  if (sum_window) {
696  return sum_window;
697  }
698  const auto avg_window = rewrite_avg_window(expr);
699  if (avg_window) {
700  return avg_window;
701  }
702  const auto expr_no_likelihood = strip_likelihood(expr);
703  // The following check is not strictly needed, but seems silly to transform a
704  // simple string comparison to an IN just to codegen the same thing anyway.
705 
706  RecursiveOrToInVisitor visitor;
707  auto rewritten_expr = visitor.visit(expr_no_likelihood);
708  const auto expr_with_likelihood =
709  std::dynamic_pointer_cast<const Analyzer::LikelihoodExpr>(rewritten_expr);
710  if (expr_with_likelihood) {
711  // Add back likelihood
712  return std::make_shared<Analyzer::LikelihoodExpr>(
713  rewritten_expr, expr_with_likelihood->get_likelihood());
714  }
715  return rewritten_expr;
716 }
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:

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

Definition at line 726 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().

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 812 of file ExpressionRewrite.cpp.

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

Referenced by create_count_all_execution_unit().

814  {
816  return quals;
817  }
818 
819  if (join_quals.empty()) {
820  return quals;
821  }
822 
823  std::list<std::shared_ptr<Analyzer::Expr>> quals_to_return;
824 
825  JoinCoveredQualVisitor visitor(join_quals);
826  for (const auto& qual : quals) {
827  if (!visitor.visit(qual.get())) {
828  // Not a covered qual, don't elide it from the filtered count
829  quals_to_return.push_back(qual);
830  }
831  }
832 
833  return quals_to_return;
834 }
bool g_strip_join_covered_quals
Definition: Execute.cpp:90

+ Here is the call graph for this function:

+ Here is the caller graph for this function: