OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RelAlgDagBuilder Struct Reference

#include <RelAlgDag.h>

+ Inheritance diagram for RelAlgDagBuilder:
+ Collaboration diagram for RelAlgDagBuilder:

Static Public Member Functions

static std::unique_ptr< RelAlgDagbuildDag (const std::string &query_ra, const bool optimize_dag)
 
static std::unique_ptr< RelAlgDagbuildDagForSubquery (RelAlgDag &root_dag, const rapidjson::Value &query_ast)
 
static void optimizeDag (RelAlgDag &rel_alg_dag)
 

Static Private Member Functions

static std::unique_ptr< RelAlgDagbuild (const rapidjson::Value &query_ast, RelAlgDag *root_dag, const bool optimize_dag)
 

Additional Inherited Members

- Static Protected Member Functions inherited from RelAlgDagModifier
static std::vector
< std::shared_ptr< RelAlgNode > > & 
getNodes (RelAlgDag &rel_alg_dag)
 
static std::vector
< std::shared_ptr< RexSubQuery > > & 
getSubqueries (RelAlgDag &rel_alg_dag)
 
static std::unordered_map
< size_t, std::unordered_map
< unsigned,
RegisteredQueryHint > > & 
getQueryHints (RelAlgDag &rel_alg_dag)
 
static void setBuildState (RelAlgDag &rel_alg_dag, const RelAlgDag::BuildState build_state)
 

Detailed Description

Builder struct to create a RelAlgDag instance. Can optionally apply high level optimizations which can be expressed through relational algebra extended with RelCompound. The RelCompound node is an equivalent representation for sequences of RelFilter, RelProject and RelAggregate nodes. This coalescing minimizes the amount of intermediate buffers required to evaluate a query. Lower level optimizations are taken care by lower levels, mainly RelAlgTranslator and the IR code generation.

Definition at line 3403 of file RelAlgDag.h.

Member Function Documentation

std::unique_ptr< RelAlgDag > RelAlgDagBuilder::build ( const rapidjson::Value &  query_ast,
RelAlgDag root_dag,
const bool  optimize_dag 
)
staticprivate

Definition at line 3361 of file RelAlgDag.cpp.

References anonymous_namespace{RelAlgDag.cpp}::bind_inputs(), CHECK, field(), RelAlgDagModifier::getNodes(), RelAlgDag::kBuiltNotOptimized, optimizeDag(), details::RelAlgDispatcher::run(), and RelAlgDagModifier::setBuildState().

Referenced by buildDag(), and buildDagForSubquery().

3363  {
3364  const auto& rels = field(query_ast, "rels");
3365  CHECK(rels.IsArray());
3366 
3367  auto rel_alg_dag_ptr = std::make_unique<RelAlgDag>();
3368  auto& rel_alg_dag = *rel_alg_dag_ptr;
3369  auto& nodes = getNodes(rel_alg_dag);
3370 
3371  try {
3372  nodes = details::RelAlgDispatcher().run(rels, root_dag ? *root_dag : rel_alg_dag);
3373  } catch (const QueryNotSupported&) {
3374  throw;
3375  }
3376  CHECK(!nodes.empty());
3377  bind_inputs(nodes);
3378 
3380 
3381  if (optimize_dag) {
3382  optimizeDag(rel_alg_dag);
3383  }
3384 
3385  return rel_alg_dag_ptr;
3386 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:33
void bind_inputs(const std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
Definition: RelAlgDag.cpp:1529
std::vector< std::shared_ptr< RelAlgNode > > run(const rapidjson::Value &rels, RelAlgDag &root_dag)
Definition: RelAlgDag.cpp:2871
static std::vector< std::shared_ptr< RelAlgNode > > & getNodes(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.h:3375
static void optimizeDag(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.cpp:3388
#define CHECK(condition)
Definition: Logger.h:291
static void setBuildState(RelAlgDag &rel_alg_dag, const RelAlgDag::BuildState build_state)
Definition: RelAlgDag.h:3389

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::unique_ptr< RelAlgDag > RelAlgDagBuilder::buildDag ( const std::string &  query_ra,
const bool  optimize_dag 
)
static

Constructs a RelAlg DAG from a relative-algebra JSON representation.

Parameters
query_raA JSON string representation of an RA tree from Calcite.
catDB catalog for the current user.

Definition at line 3335 of file RelAlgDag.cpp.

References build(), CHECK, logger::ERROR, LOG, RelAlgNode::resetRelAlgFirstId(), and VLOG.

3336  {
3337  rapidjson::Document query_ast;
3338  query_ast.Parse(query_ra.c_str());
3339  VLOG(2) << "Parsing query RA JSON: " << query_ra;
3340  if (query_ast.HasParseError()) {
3341  query_ast.GetParseError();
3342  LOG(ERROR) << "Failed to parse RA tree from Calcite (offset "
3343  << query_ast.GetErrorOffset() << "):\n"
3344  << rapidjson::GetParseError_En(query_ast.GetParseError());
3345  VLOG(1) << "Failed to parse query RA: " << query_ra;
3346  throw std::runtime_error(
3347  "Failed to parse relational algebra tree. Possible query syntax error.");
3348  }
3349  CHECK(query_ast.IsObject());
3351 
3352  return build(query_ast, nullptr, optimize_dag);
3353 }
#define LOG(tag)
Definition: Logger.h:285
static std::unique_ptr< RelAlgDag > build(const rapidjson::Value &query_ast, RelAlgDag *root_dag, const bool optimize_dag)
Definition: RelAlgDag.cpp:3361
#define CHECK(condition)
Definition: Logger.h:291
#define VLOG(n)
Definition: Logger.h:388
static void resetRelAlgFirstId() noexcept
Definition: RelAlgDag.cpp:47

+ Here is the call graph for this function:

std::unique_ptr< RelAlgDag > RelAlgDagBuilder::buildDagForSubquery ( RelAlgDag root_dag,
const rapidjson::Value &  query_ast 
)
static

Constructs a rel-alg DAG for any subqueries. Should only be called during DAG building.

Parameters
root_dagThe root DAG builder. The root stores pointers to all subqueries.
query_astThe current JSON node to build a DAG for.
catDB catalog for the current user.

Definition at line 3355 of file RelAlgDag.cpp.

References build().

Referenced by anonymous_namespace{RelAlgDag.cpp}::parse_subquery().

3357  {
3358  return build(query_ast, &root_dag, true);
3359 }
static std::unique_ptr< RelAlgDag > build(const rapidjson::Value &query_ast, RelAlgDag *root_dag, const bool optimize_dag)
Definition: RelAlgDag.cpp:3361

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RelAlgDagBuilder::optimizeDag ( RelAlgDag rel_alg_dag)
static

Definition at line 3388 of file RelAlgDag.cpp.

References anonymous_namespace{RelAlgDag.cpp}::add_window_function_pre_project(), CHECK, anonymous_namespace{RelAlgDag.cpp}::coalesce_nodes(), anonymous_namespace{RelAlgDag.cpp}::compute_node_hash(), anonymous_namespace{RelLeftDeepInnerJoin.cpp}::create_left_deep_join(), eliminate_dead_columns(), eliminate_dead_subqueries(), eliminate_identical_copy(), anonymous_namespace{RelAlgDag.cpp}::eliminate_redundant_projection(), fold_filters(), g_cluster, get_left_deep_join_root(), RelAlgDag::getBuildState(), RelAlgDagModifier::getNodes(), RelAlgDagModifier::getQueryHints(), RelAlgDagModifier::getSubqueries(), anonymous_namespace{RelAlgDag.cpp}::handle_agg_over_join(), anonymous_namespace{RelAlgDag.cpp}::handle_query_hint(), hoist_filter_cond_to_cross_join(), RelAlgDag::kBuiltNotOptimized, RelAlgDag::kBuiltOptimized, anonymous_namespace{RelAlgDag.cpp}::mark_nops(), anonymous_namespace{RelAlgDag.cpp}::separate_window_function_expressions(), RelAlgDagModifier::setBuildState(), simplify_sort(), and sink_projected_boolean_expr_to_join().

Referenced by build().

3388  {
3389  auto const build_state = rel_alg_dag.getBuildState();
3390  if (build_state == RelAlgDag::BuildState::kBuiltOptimized) {
3391  return;
3392  }
3393 
3395  << static_cast<int>(build_state);
3396 
3397  auto& nodes = getNodes(rel_alg_dag);
3398  auto& subqueries = getSubqueries(rel_alg_dag);
3399  auto& query_hints = getQueryHints(rel_alg_dag);
3400 
3401  compute_node_hash(nodes);
3402  handle_query_hint(nodes, rel_alg_dag);
3403  mark_nops(nodes);
3404  simplify_sort(nodes);
3406  eliminate_identical_copy(nodes);
3407  fold_filters(nodes);
3408  std::vector<const RelAlgNode*> filtered_left_deep_joins;
3409  std::vector<const RelAlgNode*> left_deep_joins;
3410  for (const auto& node : nodes) {
3411  const auto left_deep_join_root = get_left_deep_join_root(node);
3412  // The filter which starts a left-deep join pattern must not be coalesced
3413  // since it contains (part of) the join condition.
3414  if (left_deep_join_root) {
3415  left_deep_joins.push_back(left_deep_join_root.get());
3416  if (std::dynamic_pointer_cast<const RelFilter>(left_deep_join_root)) {
3417  filtered_left_deep_joins.push_back(left_deep_join_root.get());
3418  }
3419  }
3420  }
3421  if (filtered_left_deep_joins.empty()) {
3423  }
3424  eliminate_dead_columns(nodes);
3425  eliminate_dead_subqueries(subqueries, nodes.back().get());
3426  separate_window_function_expressions(nodes, query_hints);
3428  nodes,
3429  g_cluster /* always_add_project_if_first_project_is_window_expr */,
3430  query_hints);
3431  coalesce_nodes(nodes, left_deep_joins, query_hints);
3432  CHECK(nodes.back().use_count() == 1);
3433  create_left_deep_join(nodes);
3434  handle_agg_over_join(nodes, query_hints);
3436 
3438 }
void mark_nops(const std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
Definition: RelAlgDag.cpp:1622
static std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint > > & getQueryHints(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.h:3385
void hoist_filter_cond_to_cross_join(std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
std::shared_ptr< const RelAlgNode > get_left_deep_join_root(const std::shared_ptr< RelAlgNode > &node)
void sink_projected_boolean_expr_to_join(std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
void eliminate_redundant_projection(std::vector< std::shared_ptr< RelAlgNode >> &nodes)
Definition: RelAlgDag.cpp:2171
void eliminate_identical_copy(std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
std::pair< std::shared_ptr< RelLeftDeepInnerJoin >, std::shared_ptr< const RelAlgNode > > create_left_deep_join(const std::shared_ptr< RelAlgNode > &left_deep_join_root)
void handle_query_hint(const std::vector< std::shared_ptr< RelAlgNode >> &nodes, RelAlgDag &rel_alg_dag) noexcept
Definition: RelAlgDag.cpp:1570
static std::vector< std::shared_ptr< RexSubQuery > > & getSubqueries(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.h:3379
void add_window_function_pre_project(std::vector< std::shared_ptr< RelAlgNode >> &nodes, const bool always_add_project_if_first_project_is_window_expr, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
Definition: RelAlgDag.cpp:2650
void simplify_sort(std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
void separate_window_function_expressions(std::vector< std::shared_ptr< RelAlgNode >> &nodes, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
Definition: RelAlgDag.cpp:2456
void coalesce_nodes(std::vector< std::shared_ptr< RelAlgNode >> &nodes, const std::vector< const RelAlgNode * > &left_deep_joins, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
Definition: RelAlgDag.cpp:2008
void compute_node_hash(const std::vector< std::shared_ptr< RelAlgNode >> &nodes)
Definition: RelAlgDag.cpp:1608
static std::vector< std::shared_ptr< RelAlgNode > > & getNodes(RelAlgDag &rel_alg_dag)
Definition: RelAlgDag.h:3375
void handle_agg_over_join(std::vector< std::shared_ptr< RelAlgNode >> &nodes, std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint >> &query_hints)
Definition: RelAlgDag.cpp:2135
#define CHECK(condition)
Definition: Logger.h:291
bool g_cluster
void fold_filters(std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
void eliminate_dead_subqueries(std::vector< std::shared_ptr< RexSubQuery >> &subqueries, RelAlgNode const *root)
BuildState getBuildState() const
Definition: RelAlgDag.h:2805
void eliminate_dead_columns(std::vector< std::shared_ptr< RelAlgNode >> &nodes) noexcept
static void setBuildState(RelAlgDag &rel_alg_dag, const RelAlgDag::BuildState build_state)
Definition: RelAlgDag.h:3389

+ Here is the call graph for this function:

+ Here is the caller graph for this function:


The documentation for this struct was generated from the following files: