std::size_t SimpleCostModel::estimateCardinalityForTableReference( const P::TableReferencePtr &physical_plan) { return physical_plan->relation()->estimateTupleCardinality(); }
void PlanVisualizer::visit(const P::PhysicalPtr &input) { int node_id = ++id_counter_; node_id_map_.emplace(input, node_id); std::set<E::ExprId> referenced_ids; for (const auto &attr : input->getReferencedAttributes()) { referenced_ids.emplace(attr->id()); } for (const auto &child : input->children()) { visit(child); int child_id = node_id_map_[child]; edges_.emplace_back(EdgeInfo()); EdgeInfo &edge_info = edges_.back(); edge_info.src_node_id = child_id; edge_info.dst_node_id = node_id; edge_info.dashed = false; if ((input->getPhysicalType() == P::PhysicalType::kHashJoin || input->getPhysicalType() == P::PhysicalType::kFilterJoin) && child == input->children()[1]) { edge_info.dashed = true; } for (const auto &attr : child->getOutputAttributes()) { if (referenced_ids.find(attr->id()) != referenced_ids.end()) { edge_info.labels.emplace_back(attr->attribute_alias()); } } } nodes_.emplace_back(NodeInfo()); NodeInfo &node_info = nodes_.back(); node_info.id = node_id; if (color_map_.find(input->getName()) != color_map_.end()) { node_info.color = color_map_[input->getName()]; } switch (input->getPhysicalType()) { case P::PhysicalType::kTableReference: { const P::TableReferencePtr table_reference = std::static_pointer_cast<const P::TableReference>(input); node_info.labels.emplace_back(table_reference->relation()->getName()); break; } case P::PhysicalType::kHashJoin: { const P::HashJoinPtr hash_join = std::static_pointer_cast<const P::HashJoin>(input); node_info.labels.emplace_back(input->getName()); const auto &left_attributes = hash_join->left_join_attributes(); const auto &right_attributes = hash_join->right_join_attributes(); for (std::size_t i = 0; i < left_attributes.size(); ++i) { node_info.labels.emplace_back( left_attributes[i]->attribute_alias() + " = " + right_attributes[i]->attribute_alias()); } break; } case P::PhysicalType::kFilterJoin: { const P::FilterJoinPtr filter_join = std::static_pointer_cast<const P::FilterJoin>(input); node_info.labels.emplace_back(input->getName()); const auto &probe_attributes = filter_join->probe_attributes(); const auto &build_attributes = filter_join->build_attributes(); for (std::size_t i = 0; i < probe_attributes.size(); ++i) { node_info.labels.emplace_back( probe_attributes[i]->attribute_alias() + " = " + build_attributes[i]->attribute_alias()); } break; } default: { node_info.labels.emplace_back(input->getName()); break; } } const P::PartitionSchemeHeader *partition_scheme_header = input->getOutputPartitionSchemeHeader(); if (partition_scheme_header) { node_info.labels.emplace_back(partition_scheme_header->toString()); } if (lip_filter_conf_ != nullptr) { const auto &build_filters = lip_filter_conf_->getBuildInfoMap(); const auto build_it = build_filters.find(input); if (build_it != build_filters.end()) { for (const auto &build_info : build_it->second) { node_info.labels.emplace_back( std::string("[LIP build] ") + build_info->build_attribute()->attribute_alias()); } } const auto &probe_filters = lip_filter_conf_->getProbeInfoMap(); const auto probe_it = probe_filters.find(input); if (probe_it != probe_filters.end()) { for (const auto &probe_info : probe_it->second) { node_info.labels.emplace_back( std::string("[LIP probe] ") + probe_info->probe_attribute()->attribute_alias()); } } } try { const std::size_t estimated_cardinality = cost_model_->estimateCardinality(input); const double estimated_selectivity = cost_model_->estimateSelectivity(input); node_info.labels.emplace_back( "est. # = " + std::to_string(estimated_cardinality)); node_info.labels.emplace_back( "est. Selectivity = " + std::to_string(estimated_selectivity)); } catch (const std::exception &e) { // NOTE(jianqiao): CostModel::estimateCardinality() may throw UnsupportedPhysicalPlan // exception for some type of physical nodes such as CreateTable. // In this case, we omit the node's cardinality/selectivity information. } }