mirror of
https://github.com/nushell/nushell.git
synced 2025-04-16 09:18:21 +02:00
Merge 76f012759a
into 885b87a842
This commit is contained in:
commit
8bff35be1b
@ -255,6 +255,16 @@ fn join_rows(
|
||||
config: &Config,
|
||||
span: Span,
|
||||
) {
|
||||
if !this
|
||||
.iter()
|
||||
.any(|this_record| match this_record.as_record() {
|
||||
Ok(record) => record.contains(this_join_key),
|
||||
Err(_) => false,
|
||||
})
|
||||
{
|
||||
// `this` table does not contain the join column; do nothing
|
||||
return;
|
||||
}
|
||||
for this_row in this {
|
||||
if let Value::Record {
|
||||
val: this_record, ..
|
||||
@ -281,39 +291,40 @@ fn join_rows(
|
||||
result.push(Value::record(record, span))
|
||||
}
|
||||
}
|
||||
} else if !matches!(join_type, JoinType::Inner) {
|
||||
// `other` table did not contain any rows matching
|
||||
// `this` row on the join column; emit a single joined
|
||||
// row with null values for columns not present,
|
||||
let other_record = other_keys
|
||||
.iter()
|
||||
.map(|&key| {
|
||||
let val = if Some(key.as_ref()) == shared_join_key {
|
||||
this_record
|
||||
.get(key)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Value::nothing(span))
|
||||
} else {
|
||||
Value::nothing(span)
|
||||
};
|
||||
|
||||
(key.clone(), val)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let record = match join_type {
|
||||
JoinType::Inner | JoinType::Right => {
|
||||
merge_records(&other_record, this_record, shared_join_key)
|
||||
}
|
||||
JoinType::Left => {
|
||||
merge_records(this_record, &other_record, shared_join_key)
|
||||
}
|
||||
_ => panic!("not implemented"),
|
||||
};
|
||||
|
||||
result.push(Value::record(record, span))
|
||||
continue;
|
||||
}
|
||||
} // else { a row is missing a value for the join column }
|
||||
}
|
||||
if !matches!(join_type, JoinType::Inner) {
|
||||
// Either `this` row is missing a value for the join column or
|
||||
// `other` table did not contain any rows matching
|
||||
// `this` row on the join column; emit a single joined
|
||||
// row with null values for columns not present
|
||||
let other_record = other_keys
|
||||
.iter()
|
||||
.map(|&key| {
|
||||
let val = if Some(key.as_ref()) == shared_join_key {
|
||||
this_record
|
||||
.get(key)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Value::nothing(span))
|
||||
} else {
|
||||
Value::nothing(span)
|
||||
};
|
||||
|
||||
(key.clone(), val)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let record = match join_type {
|
||||
JoinType::Inner | JoinType::Right => {
|
||||
merge_records(&other_record, this_record, shared_join_key)
|
||||
}
|
||||
JoinType::Left => merge_records(this_record, &other_record, shared_join_key),
|
||||
_ => panic!("not implemented"),
|
||||
};
|
||||
|
||||
result.push(Value::record(record, span))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -195,6 +195,52 @@ fn do_cases_where_result_differs_between_join_types(join_type: &str) {
|
||||
),
|
||||
],
|
||||
),
|
||||
(
|
||||
// a row in the left table does not have the join column
|
||||
(
|
||||
"[{a: 1 ref: 1} {a: 2 ref: 2} {a: 3}]",
|
||||
"[{ref: 1 b: 1} {ref: 2 b: 2} {ref: 3 b: 3}]",
|
||||
"ref",
|
||||
),
|
||||
[
|
||||
("--inner", "[[a, ref, b]; [1, 1, 1], [2, 2, 2]]"),
|
||||
(
|
||||
"--left",
|
||||
"[[a, ref, b]; [1, 1, 1], [2, 2, 2], [3, null, null]]",
|
||||
),
|
||||
(
|
||||
"--right",
|
||||
"[[a, ref, b]; [1, 1, 1], [2, 2, 2], [null, 3, 3]]",
|
||||
),
|
||||
(
|
||||
"--outer",
|
||||
"[[a, ref, b]; [1, 1, 1], [2, 2, 2], [3, null, null], [null, 3, 3]]",
|
||||
),
|
||||
],
|
||||
),
|
||||
(
|
||||
// a row in the right table does not have the join column
|
||||
(
|
||||
"[{a: 1 ref: 1} {a: 2 ref: 2} {a: 3 ref: 3}]",
|
||||
"[{ref: 1 b: 1} {ref: 2 b: 2} {b: 3}]",
|
||||
"ref",
|
||||
),
|
||||
[
|
||||
("--inner", "[[a, ref, b]; [1, 1, 1], [2, 2, 2]]"),
|
||||
(
|
||||
"--left",
|
||||
"[[a, ref, b]; [1, 1, 1], [2, 2, 2], [3, 3, null]]",
|
||||
),
|
||||
(
|
||||
"--right",
|
||||
"[[a, ref, b]; [1, 1, 1], [2, 2, 2], [null, null, 3]]",
|
||||
),
|
||||
(
|
||||
"--outer",
|
||||
"[[a, ref, b]; [1, 1, 1], [2, 2, 2], [3, 3, null], [null, null, 3]]",
|
||||
),
|
||||
],
|
||||
),
|
||||
] {
|
||||
for (join_type_, expected) in join_types {
|
||||
if join_type_ == join_type {
|
||||
|
Loading…
Reference in New Issue
Block a user