remove block input support in merge (#7177)

# Description

Closes: #6937

# User-Facing Changes

N/A

# Tests + Formatting

Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace --features=extra -- -D warnings -D
clippy::unwrap_used -A clippy::needless_collect` to check that you're
using the standard code style
- `cargo test --workspace --features=extra` 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.
This commit is contained in:
WindSoilder 2022-11-23 12:01:27 +08:00 committed by GitHub
parent da7f77867a
commit 21dedef7f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 54 deletions

View File

@ -1,9 +1,9 @@
use nu_engine::{eval_block, CallExt}; use nu_engine::CallExt;
use nu_protocol::ast::Call; use nu_protocol::ast::Call;
use nu_protocol::engine::{Closure, Command, EngineState, Stack}; use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{ use nu_protocol::{
Category, Example, FromValue, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, ShellError,
ShellError, Signature, Span, SyntaxShape, Type, Value, Signature, Span, SyntaxShape, Type, Value,
}; };
#[derive(Clone)] #[derive(Clone)]
@ -19,8 +19,7 @@ impl Command for Merge {
} }
fn extra_usage(&self) -> &str { fn extra_usage(&self) -> &str {
r#"You may provide a column structure to merge, or a block r#"You may provide a column structure to merge
that generates a column structure.
When merging tables, row 0 of the input table is overwritten When merging tables, row 0 of the input table is overwritten
with values from row 0 of the provided table, then with values from row 0 of the provided table, then
@ -35,7 +34,7 @@ repeating this process with row 1, and so on."#
]) ])
.required( .required(
"block", "block",
// Both this and `update` should have a shape more like <record> | <table> | <block> than just <any>. -Leon 2022-10-27 // Both this and `update` should have a shape more like <record> | <table> than just <any>. -Leon 2022-10-27
SyntaxShape::Any, SyntaxShape::Any,
"the new value to merge with, or a block that produces it", "the new value to merge with, or a block that produces it",
) )
@ -45,7 +44,7 @@ repeating this process with row 1, and so on."#
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![ vec![
Example { Example {
example: "[a b c] | wrap name | merge { [1 2 3] | wrap index }", example: "[a b c] | wrap name | merge ( [1 2 3] | wrap index )",
description: "Add an 'index' column to the input table", description: "Add an 'index' column to the input table",
result: Some(Value::List { result: Some(Value::List {
vals: vec![ vals: vec![
@ -74,14 +73,6 @@ repeating this process with row 1, and so on."#
span: Span::test_data(), span: Span::test_data(),
}), }),
}, },
Example {
example: "{a: 1, b: 3} | merge { { b: 2 } | merge { c: 4 } }",
description: "Merge records, overwriting overlapping values",
result: Some(Value::test_record(
vec!["a", "b", "c"],
vec![Value::test_int(1), Value::test_int(2), Value::test_int(4)],
)),
},
Example { Example {
example: "[{columnA: A0 columnB: B0}] | merge [{columnA: 'A0*'}]", example: "[{columnA: A0 columnB: B0}] | merge [{columnA: 'A0*'}]",
description: "Merge two tables, overwriting overlapping columns", description: "Merge two tables, overwriting overlapping columns",
@ -103,40 +94,12 @@ repeating this process with row 1, and so on."#
call: &Call, call: &Call,
input: PipelineData, input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let replacement: Value = call.req(engine_state, stack, 0)?; let merge_value: Value = call.req(engine_state, stack, 0)?;
let metadata = input.metadata(); let metadata = input.metadata();
let ctrlc = engine_state.ctrlc.clone(); let ctrlc = engine_state.ctrlc.clone();
let call = call.clone(); let call = call.clone();
let argument_was_block = replacement.as_block().is_ok();
let merge_value: Value = if argument_was_block {
// When given a block, run it to obtain the matching value.
let capture_block: Closure = FromValue::from_value(&replacement)?;
let mut stack = stack.captures_to_stack(&capture_block.captures);
stack.with_env(&stack.env_vars.clone(), &stack.env_hidden.clone());
let block = engine_state.get_block(capture_block.block_id);
let result = eval_block(
engine_state,
&mut stack,
block,
PipelineData::new(call.head),
call.redirect_stdout,
call.redirect_stderr,
);
match result {
Ok(res) => res.into_value(call.head),
Err(e) => return Err(e),
}
} else {
// Otherwise, just use the passed-in value as-is.
replacement
};
match (&input, merge_value) { match (&input, merge_value) {
// table (list of records) // table (list of records)
( (
@ -202,16 +165,10 @@ repeating this process with row 1, and so on."#
} }
.into_pipeline_data()) .into_pipeline_data())
} }
(PipelineData::Value(val, ..), merge_value) => { (PipelineData::Value(val, ..), ..) => {
// Only point the "value originates here" arrow at the merge value // Only point the "value originates here" arrow at the merge value
// if it was generated from a block. Otherwise, point at the pipeline value. -Leon 2022-10-27 // if it was generated from a block. Otherwise, point at the pipeline value. -Leon 2022-10-27
let span = if argument_was_block { let span = if val.span()? == Span::test_data() {
if merge_value.span()? == Span::test_data() {
Span::new(call.head.start, call.head.start)
} else {
merge_value.span()?
}
} else if val.span()? == Span::test_data() {
Span::new(call.head.start, call.head.start) Span::new(call.head.start, call.head.start)
} else { } else {
val.span()? val.span()?

View File

@ -30,7 +30,7 @@ fn row() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open caballeros.csv open caballeros.csv
| merge { open new_caballeros.csv } | merge (open new_caballeros.csv)
| where country in ["Guayaquil Ecuador" "New Zealand"] | where country in ["Guayaquil Ecuador" "New Zealand"]
| get luck | get luck
| math sum | math sum