/** * @brief Convert a Postgres MergeJoin into a Peloton SeqScanNode. * @return Pointer to the constructed AbstractPlanNode. */ std::unique_ptr<planner::AbstractPlan> PlanTransformer::TransformMergeJoin( const MergeJoinPlanState *mj_plan_state) { std::unique_ptr<planner::AbstractPlan> result; PelotonJoinType join_type = PlanTransformer::TransformJoinType(mj_plan_state->jointype); if (join_type == JOIN_TYPE_INVALID) { LOG_ERROR("unsupported join type: %d", mj_plan_state->jointype); return std::unique_ptr<planner::AbstractPlan>(); } LOG_TRACE("Handle merge join with join type: %d", join_type); std::vector<planner::MergeJoinPlan::JoinClause> join_clauses = BuildMergeJoinClauses(mj_plan_state->mj_Clauses, mj_plan_state->mj_NumClauses); expression::AbstractExpression *join_filter = ExprTransformer::TransformExpr( reinterpret_cast<ExprState *>(mj_plan_state->joinqual)); expression::AbstractExpression *plan_filter = ExprTransformer::TransformExpr( reinterpret_cast<ExprState *>(mj_plan_state->qual)); std::unique_ptr<const expression::AbstractExpression> predicate(nullptr); if (join_filter && plan_filter) { predicate.reset(expression::ExpressionUtil::ConjunctionFactory( EXPRESSION_TYPE_CONJUNCTION_AND, join_filter, plan_filter)); } else if (join_filter) { predicate.reset(join_filter); } else { predicate.reset(plan_filter); } /* Transform project info */ std::unique_ptr<const planner::ProjectInfo> project_info(nullptr); std::shared_ptr<const catalog::Schema> project_schema( SchemaTransformer::GetSchemaFromTupleDesc( mj_plan_state->tts_tupleDescriptor)); project_info.reset(BuildProjectInfoFromTLSkipJunk(mj_plan_state->targetlist)); bool non_trivial = (project_info.get() != nullptr && project_info.get()->isNonTrivial()); if (non_trivial) { // we have non-trivial projection LOG_TRACE("We have non-trivial projection"); result = std::unique_ptr<planner::AbstractPlan>( new planner::ProjectionPlan(std::move(project_info), project_schema)); // set project_info to nullptr project_info.reset(); } else { LOG_TRACE("We have direct mapping projection"); } std::unique_ptr<planner::MergeJoinPlan> plan_node(new planner::MergeJoinPlan( join_type, std::move(predicate), std::move(project_info), project_schema, join_clauses)); std::unique_ptr<planner::AbstractPlan> outer{std::move( PlanTransformer::TransformPlan(outerAbstractPlanState(mj_plan_state)))}; std::unique_ptr<planner::AbstractPlan> inner{std::move( PlanTransformer::TransformPlan(innerAbstractPlanState(mj_plan_state)))}; /* Add the children nodes */ plan_node->AddChild(std::move(outer)); plan_node->AddChild(std::move(inner)); if (non_trivial) { result->AddChild(std::move(plan_node)); } else { result.reset(plan_node.release()); } LOG_TRACE("Finishing mapping Merge join, JoinType: %d", join_type); return result; }
/** * @brief Convert a Postgres MergeJoin into a Peloton SeqScanNode. * @return Pointer to the constructed AbstractPlanNode. */ const planner::AbstractPlan *PlanTransformer::TransformMergeJoin( const MergeJoinPlanState *mj_plan_state) { planner::AbstractPlan *result = nullptr; planner::MergeJoinPlan *plan_node = nullptr; PelotonJoinType join_type = PlanTransformer::TransformJoinType(mj_plan_state->jointype); if (join_type == JOIN_TYPE_INVALID) { LOG_ERROR("unsupported join type: %d", mj_plan_state->jointype); return nullptr; } LOG_INFO("Handle merge join with join type: %d", join_type); std::vector<planner::MergeJoinPlan::JoinClause> join_clauses = BuildMergeJoinClauses(mj_plan_state->mj_Clauses, mj_plan_state->mj_NumClauses); expression::AbstractExpression *join_filter = ExprTransformer::TransformExpr( reinterpret_cast<ExprState *>(mj_plan_state->joinqual)); expression::AbstractExpression *plan_filter = ExprTransformer::TransformExpr( reinterpret_cast<ExprState *>(mj_plan_state->qual)); expression::AbstractExpression *predicate = nullptr; if (join_filter && plan_filter) { predicate = expression::ConjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND, join_filter, plan_filter); } else if (join_filter) { predicate = join_filter; } else { predicate = plan_filter; } /* Transform project info */ std::unique_ptr<const planner::ProjectInfo> project_info(nullptr); project_info.reset(BuildProjectInfoFromTLSkipJunk(mj_plan_state->targetlist)); // LOG_INFO("\n%s", project_info.get()->Debug().c_str()); auto project_schema = SchemaTransformer::GetSchemaFromTupleDesc( mj_plan_state->tts_tupleDescriptor); if (project_info.get()->isNonTrivial()) { // we have non-trivial projection LOG_INFO("We have non-trivial projection"); result = new planner::ProjectionPlan(project_info.release(), project_schema); plan_node = new planner::MergeJoinPlan(join_type, predicate, nullptr, join_clauses, project_schema); result->AddChild(plan_node); } else { LOG_INFO("We have direct mapping projection"); plan_node = new planner::MergeJoinPlan( join_type, predicate, project_info.release(), join_clauses, project_schema); result = plan_node; } const planner::AbstractPlan *outer = PlanTransformer::TransformPlan(outerAbstractPlanState(mj_plan_state)); const planner::AbstractPlan *inner = PlanTransformer::TransformPlan(innerAbstractPlanState(mj_plan_state)); /* Add the children nodes */ plan_node->AddChild(outer); plan_node->AddChild(inner); LOG_INFO("Finishing mapping Merge join, JoinType: %d", join_type); return result; }