From 96e3a3de685eba15191723e9d0e75ff06b604187 Mon Sep 17 00:00:00 2001 From: David Matos Date: Mon, 27 Feb 2023 03:14:15 +0100 Subject: [PATCH] Error out when Select gets same row (#8200) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Fixes #8145, by disallowing any rows that are duplicated. ``` ❯ ls | select 0 0 Error: × Select only allows unique rows ╭─[entry #1:1:1] 1 │ ls | select 0 0 · ┬ · ╰── duplicated row ╰──── ``` # User-Facing Changes # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - [X] `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - [X] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - [X] `cargo test --workspace` to check that all tests pass # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --------- Co-authored-by: Reilly Wood --- crates/nu-command/src/filters/select.rs | 22 ++++++++++++++++------ crates/nu-command/tests/commands/select.rs | 12 ++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/crates/nu-command/src/filters/select.rs b/crates/nu-command/src/filters/select.rs index 3be756729a..b1a627487b 100644 --- a/crates/nu-command/src/filters/select.rs +++ b/crates/nu-command/src/filters/select.rs @@ -5,6 +5,7 @@ use nu_protocol::{ Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, PipelineIterator, ShellError, Signature, Span, SyntaxShape, Type, Value, }; +use std::collections::HashSet; #[derive(Clone)] pub struct Select; @@ -98,7 +99,7 @@ fn select( input: PipelineData, ignore_errors: bool, ) -> Result { - let mut rows = vec![]; + let mut unique_rows: HashSet = HashSet::new(); let mut new_columns = vec![]; @@ -118,23 +119,32 @@ fn select( Vec::new(), )); } - - rows.push(*val); + if unique_rows.contains(val) { + return Err(ShellError::GenericError( + "Select can't get the same row twice".into(), + "duplicated row index".into(), + Some(*span), + None, + Vec::new(), + )); + } + unique_rows.insert(*val); } _ => new_columns.push(column), }; } let columns = new_columns; + let mut unique_rows: Vec = unique_rows.into_iter().collect(); - let input = if !rows.is_empty() { - rows.sort_unstable(); + let input = if !unique_rows.is_empty() { + unique_rows.sort_unstable(); // let skip = call.has_flag("skip"); let metadata = input.metadata(); let pipeline_iter: PipelineIterator = input.into_iter(); NthIterator { input: pipeline_iter, - rows, + rows: unique_rows, skip: false, current: 0, } diff --git a/crates/nu-command/tests/commands/select.rs b/crates/nu-command/tests/commands/select.rs index f13751c8eb..e01eb2a0a3 100644 --- a/crates/nu-command/tests/commands/select.rs +++ b/crates/nu-command/tests/commands/select.rs @@ -272,3 +272,15 @@ fn select_failed3() { assert!(actual.out.is_empty()); assert!(actual.err.contains("cannot find column")); } + +#[test] +fn select_failed4() { + let actual = nu!( + cwd: ".", pipeline( + r#" + [{a: 1 b: 10}, {a:2, b:11}] | select 0 0 + "# + )); + + assert!(actual.err.contains("Select can't get the same row twice")); +}