Skip to content

Commit 69c0cdd

Browse files
authored
Merge pull request #2412 from dathere/issue-2391-fix
fix: `extsort` underflow in CSV mode
2 parents bbcbeba + c6fb774 commit 69c0cdd

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed

resources/test/issue2391-test_ids.csv

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
pnm,tc_id,pc_id
2+
405,139280,9730000630075
3+
405,139281,9730000630075
4+
131,139282862,9730065908379
5+
138,139282863,9730065908379
6+
138,139282864,9730065908379
7+
405,139282865,9730065908379
8+
138,139282866,9730065908379
9+
138,139282867,9730065908379
10+
138,139282868,9730065908379
11+
138,139282869,9730065908379
12+
138,139282870,9730065908379
13+
138,139282871,9730065908379
14+
252,139282,9730000630075
15+
241,139283,9730000630075
16+
272,139284,9730000630075
17+
273,139285,9730000630075

src/cmd/extsort.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ fn sort_csv(
237237
return fail!("Failed to retrieve position: invalid integer");
238238
};
239239

240-
idxfile.seek(position - position_delta)?;
240+
idxfile.seek(position.saturating_sub(position_delta))?;
241241
idxfile.read_byte_record(&mut record_wrk)?;
242242
sorted_csv_wtr.write_byte_record(&record_wrk)?;
243243
}

tests/test_extsort.rs

+65
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,68 @@ fn extsort_csvmode() {
5353

5454
assert_eq!(dos2unix(&sorted_output), dos2unix(&expected_csv));
5555
}
56+
57+
#[test]
58+
fn extsort_issue_2391() {
59+
let wrk = Workdir::new("extsort_issue_2391").flexible(true);
60+
wrk.clear_contents().unwrap();
61+
62+
let unsorted_csv = wrk.load_test_resource("issue2391-test_ids.csv");
63+
wrk.create_from_string("issue2391-test_ids.csv", &unsorted_csv);
64+
// create index
65+
let mut cmd_wrk = wrk.command("index");
66+
cmd_wrk.arg("issue2391-test_ids.csv");
67+
68+
wrk.assert_success(&mut cmd_wrk);
69+
70+
// as git mangles line endings, we need to convert manually to CRLF as per issue 2391
71+
// see https://github.com/dathere/qsv/issues/2391
72+
// convert LF to CRLF in test file to ensure consistent line endings
73+
#[cfg(target_os = "windows")]
74+
{
75+
let mut cmd = wrk.command("cmd");
76+
cmd.args([
77+
"/C",
78+
"type issue2391-test_ids.csv > issue2391-test_ids.tmp.csv && move /Y \
79+
issue2391-test_ids.tmp.csv issue2391-test_ids.csv",
80+
]);
81+
wrk.output(&mut cmd);
82+
}
83+
#[cfg(not(target_os = "windows"))]
84+
{
85+
let mut cmd = wrk.command("sh");
86+
cmd.args([
87+
"-c",
88+
"sed 's/$/\r/' issue2391-test_ids.csv > issue2391-test_ids.tmp.csv && mv \
89+
issue2391-test_ids.tmp.csv issue2391-test_ids.csv",
90+
]);
91+
wrk.output(&mut cmd);
92+
}
93+
94+
let mut cmd = wrk.command("extsort");
95+
cmd.arg("issue2391-test_ids.csv")
96+
.args(["--select", "tc_id,pnm,pc_id"]);
97+
98+
wrk.assert_success(&mut cmd);
99+
let got: Vec<Vec<String>> = wrk.read_stdout(&mut cmd);
100+
let expected = vec![
101+
svec!["pnm", "tc_id", "pc_id"],
102+
svec!["405", "139280", "9730000630075"],
103+
svec!["405", "139281", "9730000630075"],
104+
svec!["252", "139282", "9730000630075"],
105+
svec!["131", "139282862", "9730065908379"],
106+
svec!["138", "139282863", "9730065908379"],
107+
svec!["138", "139282864", "9730065908379"],
108+
svec!["405", "139282865", "9730065908379"],
109+
svec!["138", "139282866", "9730065908379"],
110+
svec!["138", "139282867", "9730065908379"],
111+
svec!["138", "139282868", "9730065908379"],
112+
svec!["138", "139282869", "9730065908379"],
113+
svec!["138", "139282870", "9730065908379"],
114+
svec!["138", "139282871", "9730065908379"],
115+
svec!["241", "139283", "9730000630075"],
116+
svec!["272", "139284", "9730000630075"],
117+
svec!["273", "139285", "9730000630075"],
118+
];
119+
assert_eq!(got, expected);
120+
}

0 commit comments

Comments
 (0)