OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ExpressionRewrite.h File Reference
#include <llvm/IR/Value.h>
#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  BoundingBoxIntersectJoinConjunction
 
struct  BoundingBoxIntersectJoinTranslationInfo
 
struct  BoundingBoxIntersectJoinTranslationResult
 
struct  BoundingBoxIntersectJoinSupportedFunction
 

Namespaces

 Analyzer
 

Enumerations

enum  BoundingBoxIntersectJoinRewriteType { BoundingBoxIntersectJoinRewriteType::BBOX_INTERSECT_JOIN, BoundingBoxIntersectJoinRewriteType::RANGE_JOIN, BoundingBoxIntersectJoinRewriteType::UNKNOWN }
 

Functions

Analyzer::ExpressionPtr rewrite_expr (const Analyzer::Expr *)
 
Analyzer::ExpressionPtr rewrite_array_elements (const Analyzer::Expr *)
 
BoundingBoxIntersectJoinTranslationResult translate_bbox_intersect_with_reordering (const std::shared_ptr< Analyzer::Expr > expr, std::vector< InputDescriptor > const &input_descs, std::unordered_map< const RelAlgNode *, int > const &input_to_nest_level, std::vector< size_t > const &input_permutation, std::list< std::shared_ptr< const InputColDescriptor >> &input_col_desc, const BoundingBoxIntersectJoinRewriteType rewrite_type, Executor const *executor)
 
BoundingBoxIntersectJoinTranslationInfo convert_bbox_intersect_join (JoinQualsPerNestingLevel const &join_quals, std::vector< InputDescriptor > &input_descs, std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, std::vector< size_t > &input_permutation, std::list< std::shared_ptr< const InputColDescriptor >> &input_col_desc, Executor const *executor)
 
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 *)
 
bool self_join_not_covered_by_left_deep_tree (const Analyzer::ColumnVar *lhs, const Analyzer::ColumnVar *rhs, const int max_rte_covered)
 
const int get_max_rte_scan_table (std::unordered_map< int, llvm::Value * > &scan_idx_to_hash_pos)
 
size_t get_table_cardinality (shared::TableKey const &table_key, Executor const *executor)
 

Enumeration Type Documentation

Function Documentation

BoundingBoxIntersectJoinTranslationInfo convert_bbox_intersect_join ( JoinQualsPerNestingLevel const &  join_quals,
std::vector< InputDescriptor > &  input_descs,
std::unordered_map< const RelAlgNode *, int > &  input_to_nest_level,
std::vector< size_t > &  input_permutation,
std::list< std::shared_ptr< const InputColDescriptor >> &  input_col_desc,
Executor const *  executor 
)

Definition at line 1217 of file ExpressionRewrite.cpp.

References BBOX_INTERSECT_JOIN, BoundingBoxIntersectJoinTranslationResult::converted_bbox_intersect_join_info, g_enable_bbox_intersect_hashjoin, g_enable_distance_rangejoin, Analyzer::FunctionOper::getName(), BoundingBoxIntersectJoinSupportedFunction::is_bbox_intersect_supported_func(), kLE, kLT, RANGE_JOIN, BoundingBoxIntersectJoinTranslationResult::swap_arguments, translate_bounding_box_intersect_with_reordering(), JoinCondition::type, and UNKNOWN.

Referenced by RelAlgExecutor::createCompoundWorkUnit(), and RelAlgExecutor::createProjectWorkUnit().

1223  {
1224  if (!g_enable_bbox_intersect_hashjoin || join_quals.empty()) {
1225  return {join_quals, false, false};
1226  }
1227 
1228  JoinQualsPerNestingLevel join_condition_per_nesting_level;
1229  bool is_reordered{false};
1230  bool has_bbox_intersect{false};
1231  for (const auto& join_condition_in : join_quals) {
1232  JoinCondition join_condition{{}, join_condition_in.type};
1233 
1234  for (const auto& join_qual_expr_in : join_condition_in.quals) {
1235  bool try_to_rewrite_expr_to_bbox_intersect = false;
1238  auto func_oper = dynamic_cast<Analyzer::FunctionOper*>(join_qual_expr_in.get());
1239  if (func_oper) {
1240  const auto func_name = func_oper->getName();
1242  func_name)) {
1243  try_to_rewrite_expr_to_bbox_intersect = true;
1245  }
1246  }
1247  auto bin_oper = dynamic_cast<Analyzer::BinOper*>(join_qual_expr_in.get());
1248  if (bin_oper && (bin_oper->get_optype() == kLE || bin_oper->get_optype() == kLT)) {
1249  auto lhs =
1250  dynamic_cast<const Analyzer::GeoOperator*>(bin_oper->get_left_operand());
1251  auto rhs = dynamic_cast<const Analyzer::Constant*>(bin_oper->get_right_operand());
1252  if (g_enable_distance_rangejoin && lhs && rhs) {
1253  try_to_rewrite_expr_to_bbox_intersect = true;
1255  }
1256  }
1258  if (try_to_rewrite_expr_to_bbox_intersect) {
1259  translation_res =
1261  input_descs,
1262  input_to_nest_level,
1263  input_permutation,
1264  input_col_desc,
1265  rewrite_type,
1266  executor);
1267  }
1268  if (translation_res.converted_bbox_intersect_join_info) {
1269  const auto& bbox_intersect_quals =
1270  *translation_res.converted_bbox_intersect_join_info;
1271  has_bbox_intersect = true;
1272  // Add qual for bounding box intersection
1273  join_condition.quals.insert(join_condition.quals.end(),
1274  bbox_intersect_quals.join_quals.begin(),
1275  bbox_intersect_quals.join_quals.end());
1276  // Add original quals
1277  join_condition.quals.insert(join_condition.quals.end(),
1278  bbox_intersect_quals.quals.begin(),
1279  bbox_intersect_quals.quals.end());
1280  } else {
1281  join_condition.quals.push_back(join_qual_expr_in);
1282  }
1283  is_reordered |= translation_res.swap_arguments;
1284  }
1285  join_condition_per_nesting_level.push_back(join_condition);
1286  }
1287  return {join_condition_per_nesting_level, has_bbox_intersect, is_reordered};
1288 }
std::optional< BoundingBoxIntersectJoinConjunction > converted_bbox_intersect_join_info
Definition: sqldefs.h:34
std::vector< JoinCondition > JoinQualsPerNestingLevel
BoundingBoxIntersectJoinTranslationResult translate_bounding_box_intersect_with_reordering(const std::shared_ptr< Analyzer::Expr > expr, std::vector< InputDescriptor > &input_descs, std::unordered_map< const RelAlgNode *, int > &input_to_nest_level, std::vector< size_t > &input_permutation, std::list< std::shared_ptr< const InputColDescriptor >> &input_col_desc, const BoundingBoxIntersectJoinRewriteType rewrite_type, Executor const *executor)
bool g_enable_distance_rangejoin
Definition: Execute.cpp:108
static bool is_bbox_intersect_supported_func(std::string_view target_func_name)
bool g_enable_bbox_intersect_hashjoin
Definition: Execute.cpp:105
Definition: sqldefs.h:32
BoundingBoxIntersectJoinRewriteType
std::string getName() const
Definition: Analyzer.h:2613

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Definition at line 1356 of file ExpressionRewrite.cpp.

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

Referenced by RelAlgExecutor::createFilterWorkUnit(), RelAlgExecutor::makeJoinQuals(), anonymous_namespace{RelAlgExecutor.cpp}::set_transient_dict_maybe(), anonymous_namespace{RelAlgExecutor.cpp}::translate_quals(), anonymous_namespace{RelAlgExecutor.cpp}::translate_scalar_sources(), anonymous_namespace{RelAlgExecutor.cpp}::translate_targets(), RelAlgTranslator::translateBinaryGeoFunction(), RelAlgTranslator::translateDatePlusMinus(), RelAlgTranslator::translateGeoComparison(), and RelAlgTranslator::translateGeoFunctionArg().

1356  {
1357  if (!expr) {
1358  return nullptr;
1359  }
1360  const auto expr_no_likelihood = strip_likelihood(expr);
1361  ConstantFoldingVisitor visitor;
1362  auto rewritten_expr = visitor.visit(expr_no_likelihood);
1363  if (visitor.get_num_overflows() > 0 && rewritten_expr->get_type_info().is_integer() &&
1364  rewritten_expr->get_type_info().get_type() != kBIGINT) {
1365  auto rewritten_expr_const =
1366  std::dynamic_pointer_cast<const Analyzer::Constant>(rewritten_expr);
1367  if (!rewritten_expr_const) {
1368  // Integer expression didn't fold completely the first time due to
1369  // overflows in smaller type subexpressions, trying again with a cast
1370  const auto& ti = SQLTypeInfo(kBIGINT, false);
1371  auto bigint_expr_no_likelihood = expr_no_likelihood->deep_copy()->add_cast(ti);
1372  auto rewritten_expr_take2 = visitor.visit(bigint_expr_no_likelihood.get());
1373  auto rewritten_expr_take2_const =
1374  std::dynamic_pointer_cast<Analyzer::Constant>(rewritten_expr_take2);
1375  if (rewritten_expr_take2_const) {
1376  // Managed to fold, switch to the new constant
1377  rewritten_expr = rewritten_expr_take2_const;
1378  }
1379  }
1380  }
1381  const auto expr_with_likelihood = dynamic_cast<const Analyzer::LikelihoodExpr*>(expr);
1382  if (expr_with_likelihood) {
1383  // Add back likelihood
1384  return std::make_shared<Analyzer::LikelihoodExpr>(
1385  rewritten_expr, expr_with_likelihood->get_likelihood());
1386  }
1387  return rewritten_expr;
1388 }
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:

const int get_max_rte_scan_table ( std::unordered_map< int, llvm::Value * > &  scan_idx_to_hash_pos)

Definition at line 1401 of file ExpressionRewrite.cpp.

Referenced by BaselineJoinHashTable::codegenKey(), PerfectJoinHashTable::codegenMatchingSet(), and PerfectJoinHashTable::codegenSlot().

1402  {
1403  int ret = INT32_MIN;
1404  for (auto& kv : scan_idx_to_hash_pos) {
1405  if (kv.first > ret) {
1406  ret = kv.first;
1407  }
1408  }
1409  return ret;
1410 }

+ Here is the caller graph for this function:

size_t get_table_cardinality ( shared::TableKey const &  table_key,
Executor const *  executor 
)

Definition at line 1412 of file ExpressionRewrite.cpp.

References CHECK, Catalog_Namespace::get_metadata_for_table(), get_temporary_table(), and shared::TableKey::table_id.

Referenced by anonymous_namespace{FromTableReordering.cpp}::get_join_qual_cost(), and translate_bounding_box_intersect_with_reordering().

1413  {
1414  if (table_key.table_id > 0) {
1415  auto const td = Catalog_Namespace::get_metadata_for_table(table_key);
1416  CHECK(td);
1417  CHECK(td->fragmenter);
1418  return td->fragmenter->getNumRows();
1419  }
1420  auto temp_tbl = get_temporary_table(executor->getTemporaryTables(), table_key.table_id);
1421  return temp_tbl->rowCount();
1422 }
const TableDescriptor * get_metadata_for_table(const ::shared::TableKey &table_key, bool populate_fragmenter)
const ResultSetPtr & get_temporary_table(const TemporaryTables *temporary_tables, const int table_id)
Definition: Execute.h:246
#define CHECK(condition)
Definition: Logger.h:291

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

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

775  {
776  return ArrayElementStringLiteralEncodingVisitor().visit(expr);
777 }

+ Here is the caller graph for this function:

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

Definition at line 779 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(), and anonymous_namespace{RelAlgExecutor.cpp}::translate_targets().

779  {
780  const auto sum_window = rewrite_sum_window(expr);
781  if (sum_window) {
782  return sum_window;
783  }
784  const auto avg_window = rewrite_avg_window(expr);
785  if (avg_window) {
786  return avg_window;
787  }
788  const auto expr_no_likelihood = strip_likelihood(expr);
789  // The following check is not strictly needed, but seems silly to transform a
790  // simple string comparison to an IN just to codegen the same thing anyway.
791 
792  RecursiveOrToInVisitor visitor;
793  auto rewritten_expr = visitor.visit(expr_no_likelihood);
794  const auto expr_with_likelihood =
795  std::dynamic_pointer_cast<const Analyzer::LikelihoodExpr>(rewritten_expr);
796  if (expr_with_likelihood) {
797  // Add back likelihood
798  return std::make_shared<Analyzer::LikelihoodExpr>(
799  rewritten_expr, expr_with_likelihood->get_likelihood());
800  }
801  return rewritten_expr;
802 }
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:

bool self_join_not_covered_by_left_deep_tree ( const Analyzer::ColumnVar lhs,
const Analyzer::ColumnVar rhs,
const int  max_rte_covered 
)

Definition at line 1390 of file ExpressionRewrite.cpp.

References Analyzer::ColumnVar::get_rte_idx(), and Analyzer::ColumnVar::getTableKey().

Referenced by BaselineJoinHashTable::codegenKey(), PerfectJoinHashTable::codegenMatchingSet(), and PerfectJoinHashTable::codegenSlot().

1392  {
1393  if (key_side->getTableKey() == val_side->getTableKey() &&
1394  key_side->get_rte_idx() == val_side->get_rte_idx() &&
1395  key_side->get_rte_idx() > max_rte_covered) {
1396  return true;
1397  }
1398  return false;
1399 }

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

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

Referenced by RelAlgExecutionUnit::createCountAllExecutionUnit().

1334  {
1336  return quals;
1337  }
1338 
1339  if (join_quals.empty()) {
1340  return quals;
1341  }
1342 
1343  std::list<std::shared_ptr<Analyzer::Expr>> quals_to_return;
1344 
1345  JoinCoveredQualVisitor visitor(join_quals);
1346  for (const auto& qual : quals) {
1347  if (!visitor.visit(qual.get())) {
1348  // Not a covered qual, don't elide it from the filtered count
1349  quals_to_return.push_back(qual);
1350  }
1351  }
1352 
1353  return quals_to_return;
1354 }
bool g_strip_join_covered_quals
Definition: Execute.cpp:112

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

BoundingBoxIntersectJoinTranslationResult translate_bbox_intersect_with_reordering ( const std::shared_ptr< Analyzer::Expr expr,
std::vector< InputDescriptor > const &  input_descs,
std::unordered_map< const RelAlgNode *, int > const &  input_to_nest_level,
std::vector< size_t > const &  input_permutation,
std::list< std::shared_ptr< const InputColDescriptor >> &  input_col_desc,
const BoundingBoxIntersectJoinRewriteType  rewrite_type,
Executor const *  executor 
)