std::shared_ptr<GroupExpression> Optimizer::InsertQueryTree( std::shared_ptr<Select> tree) { std::shared_ptr<OpExpression> initial = ConvertQueryToOpExpression(column_manager, tree); std::shared_ptr<GroupExpression> gexpr; assert(RecordTransformedExpression(initial, gexpr)); return gexpr; }
////////////////////////////////////////////////////////////////////////////// /// Rule application std::vector<std::shared_ptr<GroupExpression>> Optimizer::TransformExpression(std::shared_ptr<GroupExpression> gexpr, const Rule &rule) { std::shared_ptr<Pattern> pattern = rule.GetMatchPattern(); std::vector<std::shared_ptr<GroupExpression>> output_plans; ItemBindingIterator iterator(*this, gexpr, pattern); while (iterator.HasNext()) { std::shared_ptr<OpExpression> plan = iterator.Next(); // Check rule condition function if (rule.Check(plan)) { LOG_TRACE("Rule matched expression of group %d with op %s", gexpr->GetGroupID(), gexpr->Op().name().c_str()); // Apply rule transformations // We need to be able to analyze the transformations performed by this // rule in order to perform deduplication and launch an exploration of // the newly applied rule std::vector<std::shared_ptr<OpExpression>> transformed_plans; rule.Transform(plan, transformed_plans); // Integrate transformed plans back into groups and explore/cost if new for (std::shared_ptr<OpExpression> plan : transformed_plans) { LOG_TRACE("Trying to integrate expression with op %s", plan->Op().name().c_str()); std::shared_ptr<GroupExpression> new_gexpr; bool new_expression = RecordTransformedExpression(plan, new_gexpr, gexpr->GetGroupID()); if (new_expression) { LOG_TRACE("Expression with op %s was inserted into group %d", plan->Op().name().c_str(), new_gexpr->GetGroupID()); output_plans.push_back(new_gexpr); } } } } return output_plans; }
bool Optimizer::RecordTransformedExpression( std::shared_ptr<OpExpression> expr, std::shared_ptr<GroupExpression> &gexpr) { return RecordTransformedExpression(expr, gexpr, UNDEFINED_GROUP); }