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
29 changes: 12 additions & 17 deletions src/uu/join/src/join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,25 +320,20 @@ impl<Sep: Separator> Input<Sep> {
}
}

/// Compare two join fields. Like `sort -k`, a field missing from a line
/// that is too short compares as an empty field.
fn compare(&self, field1: Option<&[u8]>, field2: Option<&[u8]>) -> Ordering {
if let (Some(field1), Some(field2)) = (field1, field2) {
if self.ignore_case {
let field1 = CaseInsensitiveSlice { v: field1 };
let field2 = CaseInsensitiveSlice { v: field2 };
field1.cmp(&field2)
} else if self.use_locale {
locale_cmp(field1, field2)
} else {
field1.cmp(field2)
}
let field1 = field1.unwrap_or_default();
let field2 = field2.unwrap_or_default();

if self.ignore_case {
let field1 = CaseInsensitiveSlice { v: field1 };
let field2 = CaseInsensitiveSlice { v: field2 };
field1.cmp(&field2)
} else if self.use_locale {
locale_cmp(field1, field2)
} else {
match field1 {
Some(_) => Ordering::Greater,
None => match field2 {
Some(_) => Ordering::Less,
None => Ordering::Equal,
},
}
field1.cmp(field2)
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions tests/by-util/test_join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,3 +911,29 @@ fn test_operand_count() {
.stderr_contains("join: extra operand 'fields_3.txt'\n")
.stderr_contains("--help");
}

#[test]
fn test_missing_key_is_empty_key() {
// Like `sort -k`, a line too short to have the join field has an empty key.
let ts = TestScenario::new(util_name!());
let at = &ts.fixtures;
at.write("short", "x,\ny\nbob,1002\n");
at.write("keys", "1002\n");
ts.ucmd()
.args(&["-t", ",", "-1", "2", "--check-order", "short", "keys"])
.succeeds()
.stdout_only("1002,bob\n");

// ...and pairs with lines whose join field is empty.
ts.ucmd()
.args(&["-t", ",", "-j", "2", "short", "short"])
.succeeds()
.stdout_only(",x,x\n,x,y\n,y,x\n,y,y\n1002,bob,bob\n");

// Same with the default blank separator and a trailing blank.
at.write("blank", "a \nb\nbob 1002\n");
ts.ucmd()
.args(&["-1", "2", "--check-order", "blank", "keys"])
.succeeds()
.stdout_only("1002 bob\n");
}
Loading