| 2824 | // |
| 2825 | |
| 2826 | RecordSource* Optimizer::generateOuterJoin(RiverList& rivers, |
| 2827 | SortNode** sortClause) |
| 2828 | { |
| 2829 | struct { |
| 2830 | RecordSource* stream_rsb; |
| 2831 | StreamType stream_num; |
| 2832 | } stream_o, stream_i, *stream_ptr[2]; |
| 2833 | |
| 2834 | // Determine which stream should be outer and which is inner. |
| 2835 | // In the case of a left join, the syntactically left stream is the |
| 2836 | // outer, and the right stream is the inner. For all others, swap |
| 2837 | // the sense of inner and outer, though for a full join it doesn't |
| 2838 | // matter and we should probably try both orders to see which is |
| 2839 | // more efficient. |
| 2840 | if (!rse->isLeftJoin()) |
| 2841 | { |
| 2842 | stream_ptr[1] = &stream_o; |
| 2843 | stream_ptr[0] = &stream_i; |
| 2844 | } |
| 2845 | else |
| 2846 | { |
| 2847 | stream_ptr[0] = &stream_o; |
| 2848 | stream_ptr[1] = &stream_i; |
| 2849 | } |
| 2850 | |
| 2851 | // Loop through the outer join sub-streams in |
| 2852 | // reverse order because rivers may have been PUSHed |
| 2853 | for (int i = 1; i >= 0; i--) |
| 2854 | { |
| 2855 | const auto node = rse->rse_relations[i]; |
| 2856 | |
| 2857 | if (nodeIs<RelationSourceNode>(node) || nodeIs<LocalTableSourceNode>(node)) |
| 2858 | { |
| 2859 | stream_ptr[i]->stream_rsb = nullptr; |
| 2860 | stream_ptr[i]->stream_num = node->getStream(); |
| 2861 | } |
| 2862 | else |
| 2863 | { |
| 2864 | River* const river = rivers.pop(); |
| 2865 | stream_ptr[i]->stream_rsb = river->getRecordSource(); |
| 2866 | } |
| 2867 | } |
| 2868 | |
| 2869 | if (!isFullJoin()) |
| 2870 | { |
| 2871 | // Generate rsbs for the sub-streams. |
| 2872 | // For the left sub-stream we also will get a boolean back. |
| 2873 | BoolExprNode* boolean = nullptr; |
| 2874 | |
| 2875 | if (!stream_o.stream_rsb) |
| 2876 | { |
| 2877 | stream_o.stream_rsb = |
| 2878 | generateRetrieval(stream_o.stream_num, sortClause, true, false, &boolean); |
| 2879 | } |
| 2880 | else |
| 2881 | { |
| 2882 | // Ensure the inner streams are inactive |
| 2883 | StreamList streams; |
nothing calls this directly
no test coverage detected