| 984 | |
| 985 | |
| 986 | MergeJoinAlgorithm::Status MergeJoinAlgorithm::asofJoin() |
| 987 | { |
| 988 | auto & left_cursor = cursors[0]; |
| 989 | if (!left_cursor.isValid()) |
| 990 | return Status(0); |
| 991 | |
| 992 | auto & right_cursor = cursors[1]; |
| 993 | if (!right_cursor.isValid()) |
| 994 | return Status(1); |
| 995 | |
| 996 | const auto & left_columns = left_cursor.getCurrent().getColumns(); |
| 997 | const auto & right_columns = right_cursor.getCurrent().getColumns(); |
| 998 | |
| 999 | MutableColumns result_cols = getEmptyResultColumns(); |
| 1000 | |
| 1001 | while (left_cursor.isValid() && right_cursor.isValid()) |
| 1002 | { |
| 1003 | auto lpos = left_cursor.getRow(); |
| 1004 | auto rpos = right_cursor.getRow(); |
| 1005 | auto cmp = compareCursors(left_cursor, right_cursor, null_direction_hint); |
| 1006 | if (cmp == 0) |
| 1007 | { |
| 1008 | const auto * lhs_null_map = getNullMapData(left_cursor.null_maps.back()); |
| 1009 | if (lhs_null_map && (*lhs_null_map)[lpos]) |
| 1010 | cmp = -1; |
| 1011 | const auto * rhs_null_map = getNullMapData(right_cursor.null_maps.back()); |
| 1012 | if (rhs_null_map && (*rhs_null_map)[rpos]) |
| 1013 | cmp = 1; |
| 1014 | } |
| 1015 | |
| 1016 | if (cmp == 0) |
| 1017 | { |
| 1018 | auto asof_cmp = compareAsofCursors(left_cursor, right_cursor, null_direction_hint); |
| 1019 | |
| 1020 | if ((asof_inequality == ASOFJoinInequality::Less && asof_cmp <= -1) |
| 1021 | || (asof_inequality == ASOFJoinInequality::LessOrEquals && asof_cmp <= 0)) |
| 1022 | { |
| 1023 | /// First row in right table that is greater (or equal) than current row in left table |
| 1024 | /// matches asof join condition the best |
| 1025 | size_t i = 0; |
| 1026 | for (const auto & col : left_columns) |
| 1027 | result_cols[i++]->insertFrom(*col, lpos); |
| 1028 | for (const auto & col : right_columns) |
| 1029 | result_cols[i++]->insertFrom(*col, rpos); |
| 1030 | chassert(i == result_cols.size()); |
| 1031 | |
| 1032 | left_cursor.next(); |
| 1033 | continue; |
| 1034 | } |
| 1035 | |
| 1036 | if (asof_inequality == ASOFJoinInequality::Less || asof_inequality == ASOFJoinInequality::LessOrEquals) |
| 1037 | { |
| 1038 | /// Asof condition is not (yet) satisfied, skip row in right table |
| 1039 | right_cursor.next(); |
| 1040 | continue; |
| 1041 | } |
| 1042 | |
| 1043 | if ((asof_inequality == ASOFJoinInequality::Greater && asof_cmp >= 1) |
nothing calls this directly
no test coverage detected