Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/duckdb/src/execution/column_binding_resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ void ColumnBindingResolver::VisitOperator(LogicalOperator &op) {
// for now, only ASOF supports this.
if (comp_join.predicate) {
D_ASSERT(op.type == LogicalOperatorType::LOGICAL_ASOF_JOIN);
// If this is a SEMI or ANTI join and we have an arbitrary predicate,
// we need to include the bindings of the RHS
if (comp_join.join_type == JoinType::SEMI || comp_join.join_type == JoinType::ANTI) {
auto right_bindings = op.children[1]->GetColumnBindings();
bindings.insert(bindings.end(), right_bindings.begin(), right_bindings.end());
auto &right_types = op.children[1]->types;
types.insert(types.end(), right_types.begin(), right_types.end());
}
VisitExpression(&comp_join.predicate);
}
return;
Expand Down
44 changes: 27 additions & 17 deletions src/duckdb/src/execution/join_hashtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1130,25 +1130,35 @@ void ScanStructure::NextRightSemiOrAntiJoin(DataChunk &keys) {
// resolve the equality_predicates for this set of keys
idx_t result_count = ResolvePredicates(keys, chain_match_sel_vector, nullptr);

// for each match, fully follow the chain
for (idx_t i = 0; i < result_count; i++) {
const auto idx = chain_match_sel_vector.get_index(i);
auto &ptr = ptrs[idx];
if (Load<bool>(ptr + ht.tuple_size)) { // Early out: chain has been fully marked as found before
ptr = ht.dead_end.get();
continue;
}
if (ht.non_equality_predicates.empty()) {
// we only have equality predicates - the match is found for the entire chain
for (idx_t i = 0; i < result_count; i++) {
const auto idx = chain_match_sel_vector.get_index(i);
auto &ptr = ptrs[idx];
if (Load<bool>(ptr + ht.tuple_size)) { // Early out: chain has been fully marked as found before
ptr = ht.dead_end.get();
continue;
}

// Fully mark chain as found
while (true) {
// NOTE: threadsan reports this as a data race because this can be set concurrently by separate threads
// Technically it is, but it does not matter, since the only value that can be written is "true"
Store<bool>(true, ptr + ht.tuple_size);
auto next_ptr = LoadPointer(ptr + ht.pointer_offset);
if (!next_ptr) {
break;
// Fully mark chain as found
while (true) {
// NOTE: threadsan reports this as a data race because this can be set concurrently by separate
// threads Technically it is, but it does not matter, since the only value that can be written is
// "true"
Store<bool>(true, ptr + ht.tuple_size);
auto next_ptr = LoadPointer(ptr + ht.pointer_offset);
if (!next_ptr) {
break;
}
ptr = next_ptr;
}
ptr = next_ptr;
}
} else {
// we have non-equality predicates - we need to evaluate the join condition for every row
// for each match found in the current pass - mark the match as found
for (idx_t i = 0; i < result_count; i++) {
auto idx = chain_match_sel_vector.get_index(i);
Store<bool>(true, ptrs[idx] + ht.tuple_size);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/duckdb/src/function/table/version/pragma_version.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef DUCKDB_PATCH_VERSION
#define DUCKDB_PATCH_VERSION "4-dev168"
#define DUCKDB_PATCH_VERSION "4-dev173"
#endif
#ifndef DUCKDB_MINOR_VERSION
#define DUCKDB_MINOR_VERSION 4
Expand All @@ -8,10 +8,10 @@
#define DUCKDB_MAJOR_VERSION 1
#endif
#ifndef DUCKDB_VERSION
#define DUCKDB_VERSION "v1.4.4-dev168"
#define DUCKDB_VERSION "v1.4.4-dev173"
#endif
#ifndef DUCKDB_SOURCE_ID
#define DUCKDB_SOURCE_ID "908d3eb281"
#define DUCKDB_SOURCE_ID "23dcc0f1f6"
#endif
#include "duckdb/function/table/system_functions.hpp"
#include "duckdb/main/database.hpp"
Expand Down