| 43 | } |
| 44 | |
| 45 | LogicalPlan Planner::planQueryGraphCollection(const QueryGraphCollection& queryGraphCollection, |
| 46 | const QueryGraphPlanningInfo& info) { |
| 47 | DASSERT(queryGraphCollection.getNumQueryGraphs() > 0); |
| 48 | auto& corrExprs = info.corrExprs; |
| 49 | int32_t queryGraphIdxToPlanExpressionsScan = -1; |
| 50 | if (info.subqueryType == SubqueryPlanningType::CORRELATED) { |
| 51 | // Pick a query graph to plan ExpressionsScan. If -1 is returned, we fall back to cross |
| 52 | // product. |
| 53 | queryGraphIdxToPlanExpressionsScan = getConnectedQueryGraphIdx(queryGraphCollection, info); |
| 54 | } |
| 55 | std::unordered_set<uint32_t> evaluatedPredicatesIndices; |
| 56 | std::vector<LogicalPlan> planPerQueryGraph; |
| 57 | for (auto i = 0u; i < queryGraphCollection.getNumQueryGraphs(); ++i) { |
| 58 | auto queryGraph = queryGraphCollection.getQueryGraph(i); |
| 59 | // Extract predicates for current query graph |
| 60 | std::unordered_set<uint32_t> predicateToEvaluateIndices; |
| 61 | for (auto j = 0u; j < info.predicates.size(); ++j) { |
| 62 | if (info.predicates[j]->expressionType == ExpressionType::LITERAL) { |
| 63 | continue; |
| 64 | } |
| 65 | if (evaluatedPredicatesIndices.contains(j)) { |
| 66 | continue; |
| 67 | } |
| 68 | if (queryGraph->canProjectExpression(info.predicates[j])) { |
| 69 | predicateToEvaluateIndices.insert(j); |
| 70 | } |
| 71 | } |
| 72 | evaluatedPredicatesIndices.insert(predicateToEvaluateIndices.begin(), |
| 73 | predicateToEvaluateIndices.end()); |
| 74 | expression_vector predicatesToEvaluate; |
| 75 | for (auto idx : predicateToEvaluateIndices) { |
| 76 | predicatesToEvaluate.push_back(info.predicates[idx]); |
| 77 | } |
| 78 | LogicalPlan plan; |
| 79 | auto newInfo = info; |
| 80 | newInfo.predicates = predicatesToEvaluate; |
| 81 | switch (info.subqueryType) { |
| 82 | case SubqueryPlanningType::NONE: |
| 83 | case SubqueryPlanningType::UNNEST_CORRELATED: { |
| 84 | plan = planQueryGraph(*queryGraph, newInfo); |
| 85 | } break; |
| 86 | case SubqueryPlanningType::CORRELATED: { |
| 87 | if (i == (uint32_t)queryGraphIdxToPlanExpressionsScan) { |
| 88 | // Plan ExpressionsScan with current query graph. |
| 89 | plan = planQueryGraph(*queryGraph, newInfo); |
| 90 | } else { |
| 91 | // Plan current query graph as an isolated query graph. |
| 92 | newInfo.subqueryType = SubqueryPlanningType::NONE; |
| 93 | plan = planQueryGraph(*queryGraph, newInfo); |
| 94 | } |
| 95 | } break; |
| 96 | default: |
| 97 | UNREACHABLE_CODE; |
| 98 | } |
| 99 | planPerQueryGraph.push_back(std::move(plan)); |
| 100 | } |
| 101 | // Fail to plan ExpressionsScan with any query graph. Plan it independently and fall back to |
| 102 | // cross product. |
nothing calls this directly
no test coverage detected