| 2462 | // |
| 2463 | |
| 2464 | void Optimizer::formRivers(const StreamList& streams, |
| 2465 | RiverList& rivers, |
| 2466 | SortNode** sortClause, |
| 2467 | const PlanNode* planClause) |
| 2468 | { |
| 2469 | StreamList tempStreams; |
| 2470 | |
| 2471 | // This must be a join or a merge node, so go through |
| 2472 | // the substreams and place them into the temp vector |
| 2473 | // for formation into a river |
| 2474 | |
| 2475 | for (const auto planNode : planClause->subNodes) |
| 2476 | { |
| 2477 | if (planNode->type == PlanNode::TYPE_JOIN) |
| 2478 | { |
| 2479 | formRivers(streams, rivers, sortClause, planNode); |
| 2480 | continue; |
| 2481 | } |
| 2482 | |
| 2483 | // At this point we must have a retrieval node, so put |
| 2484 | // the stream into the river |
| 2485 | fb_assert(planNode->type == PlanNode::TYPE_RETRIEVE); |
| 2486 | |
| 2487 | if (!nodeIs<RelationSourceNode>(planNode->recordSourceNode)) |
| 2488 | continue; |
| 2489 | |
| 2490 | const auto stream = planNode->recordSourceNode->getStream(); |
| 2491 | |
| 2492 | // dimitr: the plan may contain more retrievals than the "streams" |
| 2493 | // array (some streams could already be joined to the active |
| 2494 | // rivers), so we populate the "temp" array only with the |
| 2495 | // streams that appear in both the plan and the "streams" |
| 2496 | // array. |
| 2497 | |
| 2498 | if (streams.exist(stream)) |
| 2499 | tempStreams.add(stream); |
| 2500 | } |
| 2501 | |
| 2502 | // Just because the user specified a join does not mean that |
| 2503 | // we are able to form a river; thus form as many rivers out |
| 2504 | // of the join are as necessary to exhaust the streams. |
| 2505 | // AB: Only form rivers when any retrieval node is seen, for |
| 2506 | // example a MERGE on two JOINs will come with no retrievals |
| 2507 | // at this point. |
| 2508 | |
| 2509 | if (tempStreams.hasData()) |
| 2510 | { |
| 2511 | InnerJoin innerJoin(tdbb, this, tempStreams, |
| 2512 | sortClause, (planClause != nullptr)); |
| 2513 | |
| 2514 | while (innerJoin.findJoinOrder()) |
| 2515 | rivers.add(innerJoin.formRiver()); |
| 2516 | } |
| 2517 | } |
| 2518 | |
| 2519 | |
| 2520 | // |