Fix #15571 panic on write to source parquet file (#15601)

Fixes #15571 

# Description

Writing to a source `.parquet` (`polars open some_file.parquet | polars
save some_file.parquet`) file made the plugin panic, added a guard to
check the data_source path as per [this
comment](https://github.com/nushell/nushell/issues/15571#issuecomment-2812707161)

Example output now:
<img width="850" alt="Screenshot 2025-04-18 at 21 10 30"
src="https://github.com/user-attachments/assets/40a73cc7-6635-43dc-a423-19c7a0c8f59c"
/>

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
 - Add 1 test
 - clippy OK
 - cargo fmt OK

# After Submitting
No action required
This commit is contained in:
Julian Amarilla 2025-05-23 20:31:28 -03:00 committed by GitHub
parent f90035e084
commit 6bf955a5a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
110 changed files with 452 additions and 165 deletions

View File

@ -1,6 +1,7 @@
use super::util::{build_metadata_record, extend_record_with_metadata};
use nu_engine::command_prelude::*;
use nu_protocol::{
DataSource, PipelineMetadata,
PipelineMetadata,
ast::{Expr, Expression},
};
@ -56,56 +57,40 @@ impl Command for Metadata {
} => {
let origin = stack.get_var_with_origin(*var_id, *span)?;
Ok(
build_metadata_record(&origin, input.metadata().as_ref(), head)
.into_pipeline_data(),
Ok(build_metadata_record_value(
&origin,
input.metadata().as_ref(),
head,
)
.into_pipeline_data())
}
_ => {
let val: Value = call.req(engine_state, stack, 0)?;
Ok(build_metadata_record(&val, input.metadata().as_ref(), head)
.into_pipeline_data())
Ok(
build_metadata_record_value(&val, input.metadata().as_ref(), head)
.into_pipeline_data(),
)
}
}
} else {
let val: Value = call.req(engine_state, stack, 0)?;
Ok(build_metadata_record(&val, input.metadata().as_ref(), head)
.into_pipeline_data())
Ok(
build_metadata_record_value(&val, input.metadata().as_ref(), head)
.into_pipeline_data(),
)
}
}
Some(_) => {
let val: Value = call.req(engine_state, stack, 0)?;
Ok(build_metadata_record(&val, input.metadata().as_ref(), head)
.into_pipeline_data())
}
None => {
let mut record = Record::new();
if let Some(x) = input.metadata().as_ref() {
match x {
PipelineMetadata {
data_source: DataSource::Ls,
..
} => record.push("source", Value::string("ls", head)),
PipelineMetadata {
data_source: DataSource::HtmlThemes,
..
} => record.push("source", Value::string("into html --list", head)),
PipelineMetadata {
data_source: DataSource::FilePath(path),
..
} => record.push(
"source",
Value::string(path.to_string_lossy().to_string(), head),
),
_ => {}
}
if let Some(ref content_type) = x.content_type {
record.push("content_type", Value::string(content_type, head));
}
}
Ok(Value::record(record, head).into_pipeline_data())
Ok(
build_metadata_record_value(&val, input.metadata().as_ref(), head)
.into_pipeline_data(),
)
}
None => Ok(
Value::record(build_metadata_record(input.metadata().as_ref(), head), head)
.into_pipeline_data(),
),
}
}
@ -125,7 +110,11 @@ impl Command for Metadata {
}
}
fn build_metadata_record(arg: &Value, metadata: Option<&PipelineMetadata>, head: Span) -> Value {
fn build_metadata_record_value(
arg: &Value,
metadata: Option<&PipelineMetadata>,
head: Span,
) -> Value {
let mut record = Record::new();
let span = arg.span();
@ -140,31 +129,7 @@ fn build_metadata_record(arg: &Value, metadata: Option<&PipelineMetadata>, head:
),
);
if let Some(x) = metadata {
match x {
PipelineMetadata {
data_source: DataSource::Ls,
..
} => record.push("source", Value::string("ls", head)),
PipelineMetadata {
data_source: DataSource::HtmlThemes,
..
} => record.push("source", Value::string("into html --list", head)),
PipelineMetadata {
data_source: DataSource::FilePath(path),
..
} => record.push(
"source",
Value::string(path.to_string_lossy().to_string(), head),
),
_ => {}
}
if let Some(ref content_type) = x.content_type {
record.push("content_type", Value::string(content_type, head));
}
}
Value::record(record, head)
Value::record(extend_record_with_metadata(record, metadata, head), head)
}
#[cfg(test)]

View File

@ -1,9 +1,11 @@
use nu_engine::{command_prelude::*, get_eval_block_with_early_return};
use nu_protocol::{
DataSource, PipelineData, PipelineMetadata, ShellError, Signature, SyntaxShape, Type, Value,
PipelineData, ShellError, Signature, SyntaxShape, Type, Value,
engine::{Call, Closure, Command, EngineState, Stack},
};
use super::util::build_metadata_record;
#[derive(Clone)]
pub struct MetadataAccess;
@ -40,7 +42,10 @@ impl Command for MetadataAccess {
// `ClosureEvalOnce` is not used as it uses `Stack::captures_to_stack` rather than
// `Stack::captures_to_stack_preserve_out_dest`. This command shouldn't collect streams
let mut callee_stack = caller_stack.captures_to_stack_preserve_out_dest(closure.captures);
let metadata_record = build_metadata_record(input.metadata().as_ref(), call.head);
let metadata_record = Value::record(
build_metadata_record(input.metadata().as_ref(), call.head),
call.head,
);
if let Some(var_id) = block.signature.get_positional(0).and_then(|var| var.var_id) {
callee_stack.add_var(var_id, metadata_record)
@ -64,36 +69,6 @@ impl Command for MetadataAccess {
}
}
fn build_metadata_record(metadata: Option<&PipelineMetadata>, head: Span) -> Value {
let mut record = Record::new();
if let Some(x) = metadata {
match x {
PipelineMetadata {
data_source: DataSource::Ls,
..
} => record.push("source", Value::string("ls", head)),
PipelineMetadata {
data_source: DataSource::HtmlThemes,
..
} => record.push("source", Value::string("into html --list", head)),
PipelineMetadata {
data_source: DataSource::FilePath(path),
..
} => record.push(
"source",
Value::string(path.to_string_lossy().to_string(), head),
),
_ => {}
}
if let Some(ref content_type) = x.content_type {
record.push("content_type", Value::string(content_type, head));
}
}
Value::record(record, head)
}
#[cfg(test)]
mod test {
use crate::ToJson;

View File

@ -9,6 +9,7 @@ mod metadata_access;
mod metadata_set;
mod profile;
mod timeit;
mod util;
mod view;
mod view_blocks;
mod view_files;

View File

@ -0,0 +1,34 @@
use nu_protocol::{DataSource, PipelineMetadata, Record, Span, Value};
pub fn extend_record_with_metadata(
mut record: Record,
metadata: Option<&PipelineMetadata>,
head: Span,
) -> Record {
if let Some(PipelineMetadata {
data_source,
content_type,
}) = metadata
{
match data_source {
DataSource::Ls => record.push("source", Value::string("ls", head)),
DataSource::HtmlThemes => {
record.push("source", Value::string("into html --list", head))
}
DataSource::FilePath(path) => record.push(
"source",
Value::string(path.to_string_lossy().to_string(), head),
),
DataSource::None => {}
}
if let Some(content_type) = content_type {
record.push("content_type", Value::string(content_type, head));
}
};
record
}
pub fn build_metadata_record(metadata: Option<&PipelineMetadata>, head: Span) -> Record {
extend_record_with_metadata(Record::new(), metadata, head)
}

View File

@ -61,12 +61,14 @@ impl PluginCommand for ExprAggGroups {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuExpression(expr) => command_expr(plugin, engine, call, expr),
_ => Err(cant_convert_err(&value, &[PolarsPluginType::NuExpression])),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -127,6 +127,7 @@ impl PluginCommand for LazyAggregate {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let vals: Vec<Value> = call.rest(0)?;
let value = Value::list(vals, call.head);
let expressions = NuExpression::extract_exprs(plugin, value)?;
@ -153,6 +154,7 @@ impl PluginCommand for LazyAggregate {
let lazy = NuLazyFrame::new(false, polars.agg(&expressions));
lazy.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -56,12 +56,14 @@ impl PluginCommand for ExprCount {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuExpression(expr) => command_expr(plugin, engine, call, expr),
_ => Err(cant_convert_err(&value, &[PolarsPluginType::NuExpression])),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -156,6 +156,7 @@ impl PluginCommand for Cumulative {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
let cum_type: Spanned<String> = call.req(0)?;
let cum_type = CumulativeType::from_str(&cum_type.item, cum_type.span)?;
@ -177,6 +178,7 @@ impl PluginCommand for Cumulative {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -100,6 +100,7 @@ impl PluginCommand for ToLazyGroupBy {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let vals: Vec<Value> = call.rest(0)?;
let expr_value = Value::list(vals, call.head);
let expressions = NuExpression::extract_exprs(plugin, expr_value)?;
@ -117,7 +118,9 @@ impl PluginCommand for ToLazyGroupBy {
let pipeline_value = input.into_value(call.head)?;
let lazy = NuLazyFrame::try_from_value_coerce(plugin, &pipeline_value)?;
command(plugin, engine, call, lazy, expressions).map_err(LabeledError::from)
command(plugin, engine, call, lazy, expressions)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -56,12 +56,14 @@ impl PluginCommand for ExprImplode {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuExpression(expr) => command_expr(plugin, engine, call, expr),
_ => Err(cant_convert_err(&value, &[PolarsPluginType::NuExpression])),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -90,6 +90,7 @@ impl PluginCommand for ExprMax {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_lazy(plugin, engine, call, df.lazy()),
@ -105,6 +106,7 @@ impl PluginCommand for ExprMax {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -90,6 +90,7 @@ impl PluginCommand for ExprMean {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_lazy(plugin, engine, call, df.lazy()),
@ -105,6 +106,7 @@ impl PluginCommand for ExprMean {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -91,6 +91,7 @@ impl PluginCommand for LazyMedian {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command(plugin, engine, call, df.lazy()),
@ -109,6 +110,7 @@ impl PluginCommand for LazyMedian {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -90,6 +90,7 @@ impl PluginCommand for ExprMin {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_lazy(plugin, engine, call, df.lazy()),
@ -105,6 +106,7 @@ impl PluginCommand for ExprMin {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -56,7 +56,10 @@ impl PluginCommand for NNull {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -70,6 +70,7 @@ impl PluginCommand for NUnique {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command(plugin, engine, call, df),
@ -90,6 +91,7 @@ impl PluginCommand for NUnique {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -83,6 +83,7 @@ impl PluginCommand for Over {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let vals: Vec<Value> = call.rest(0)?;
let expr_value = Value::list(vals, call.head);
let expressions = NuExpression::extract_exprs(plugin, expr_value)?;
@ -103,6 +104,7 @@ impl PluginCommand for Over {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -99,6 +99,7 @@ impl PluginCommand for LazyQuantile {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
let quantile: f64 = call.req(0)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
@ -123,6 +124,7 @@ impl PluginCommand for LazyQuantile {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -119,7 +119,10 @@ impl PluginCommand for Rolling {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -83,6 +83,7 @@ impl PluginCommand for ExprStd {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_lazy(plugin, engine, call, df.lazy()),
@ -98,6 +99,7 @@ impl PluginCommand for ExprStd {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -90,6 +90,7 @@ impl PluginCommand for ExprSum {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_lazy(plugin, engine, call, df.lazy()),
@ -105,6 +106,7 @@ impl PluginCommand for ExprSum {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -74,7 +74,10 @@ impl PluginCommand for ValueCount {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,6 +84,7 @@ impl PluginCommand for ExprVar {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_lazy(plugin, engine, call, df.lazy()),
@ -99,6 +100,7 @@ impl PluginCommand for ExprVar {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -73,7 +73,10 @@ impl PluginCommand for AllFalse {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -73,7 +73,10 @@ impl PluginCommand for AllTrue {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -60,7 +60,10 @@ impl PluginCommand for ArgTrue {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -67,12 +67,14 @@ impl PluginCommand for ExprNot {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuExpression(expr) => command_expr(plugin, engine, call, expr),
_ => Err(cant_convert_err(&value, &[PolarsPluginType::NuExpression])),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -87,7 +87,10 @@ impl PluginCommand for IsDuplicated {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -114,6 +114,7 @@ impl PluginCommand for ExprIsIn {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_df(plugin, engine, call, df),
@ -131,6 +132,7 @@ impl PluginCommand for ExprIsIn {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -78,6 +78,7 @@ impl PluginCommand for IsNotNull {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command(plugin, engine, call, df),
@ -98,6 +99,7 @@ impl PluginCommand for IsNotNull {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -80,6 +80,7 @@ impl PluginCommand for IsNull {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command(plugin, engine, call, df),
@ -100,6 +101,7 @@ impl PluginCommand for IsNull {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -87,7 +87,10 @@ impl PluginCommand for IsUnique {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -61,8 +61,11 @@ impl PluginCommand for NotSeries {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let df = NuDataFrame::try_from_pipeline_coerce(plugin, input, call.head)?;
command(plugin, engine, call, df).map_err(LabeledError::from)
command(plugin, engine, call, df)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -95,6 +95,7 @@ impl PluginCommand for ExprOtherwise {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let otherwise_predicate: Value = call.req(0)?;
let otherwise_predicate = NuExpression::try_from_value(plugin, &otherwise_predicate)?;
@ -108,6 +109,7 @@ impl PluginCommand for ExprOtherwise {
complete
.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -72,7 +72,10 @@ impl PluginCommand for SetSeries {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -111,6 +111,7 @@ impl PluginCommand for ExprWhen {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let when_predicate: Value = call.req(0)?;
let when_predicate = NuExpression::try_from_value(plugin, &when_predicate)?;
@ -137,6 +138,7 @@ impl PluginCommand for ExprWhen {
when_then
.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -56,11 +56,13 @@ impl PluginCommand for LazyCache {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let lazy = NuLazyFrame::try_from_pipeline_coerce(plugin, input, call.head)
.map_err(LabeledError::from)?;
let lazy = NuLazyFrame::new(lazy.from_eager, lazy.to_polars().cache());
lazy.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -44,7 +44,10 @@ impl PluginCommand for ColumnsDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, call, input).map_err(|e| e.into())
let metadata = input.metadata();
command(plugin, call, input)
.map_err(|e| e.into())
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -66,6 +66,7 @@ impl PluginCommand for LazyFetch {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let rows: i64 = call.req(0)?;
let value = input.into_value(call.head)?;
let lazy = NuLazyFrame::try_from_value_coerce(plugin, &value)?;
@ -87,6 +88,7 @@ impl PluginCommand for LazyFetch {
eager
.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -9,8 +9,8 @@ use nu_utils::perf;
use nu_plugin::{EvaluatedCall, PluginCommand};
use nu_protocol::{
Category, Example, LabeledError, PipelineData, ShellError, Signature, Span, Spanned,
SyntaxShape, Type, Value,
Category, DataSource, Example, LabeledError, PipelineData, PipelineMetadata, ShellError,
Signature, Span, Spanned, SyntaxShape, Type, Value,
shell_error::{self, io::IoError},
};
@ -131,8 +131,8 @@ impl PluginCommand for OpenDataFrame {
plugin: &Self::Plugin,
engine: &nu_plugin::EngineInterface,
call: &nu_plugin::EvaluatedCall,
_input: nu_protocol::PipelineData,
) -> Result<nu_protocol::PipelineData, LabeledError> {
_input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call).map_err(|e| e.into())
}
}
@ -166,6 +166,11 @@ fn command(
let hive_options = build_hive_options(plugin, call)?;
let uri = spanned_file.item.clone();
let data_source = DataSource::FilePath(uri.into());
let metadata = PipelineMetadata::default().with_data_source(data_source);
match type_option {
Some((ext, blamed)) => match PolarsFileType::from(ext.as_str()) {
PolarsFileType::Csv | PolarsFileType::Tsv => {
@ -200,7 +205,7 @@ fn command(
"File without extension",
))),
}
.map(|value| PipelineData::Value(value, None))
.map(|value| PipelineData::Value(value, Some(metadata)))
}
fn from_parquet(

View File

@ -63,6 +63,7 @@ The units of the timings are microseconds."#
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_lazy(plugin, engine, call, df.lazy()),
@ -73,6 +74,7 @@ The units of the timings are microseconds."#
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -15,8 +15,8 @@ use crate::{
use log::debug;
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
use nu_protocol::{
Category, Example, LabeledError, PipelineData, ShellError, Signature, Span, Spanned,
SyntaxShape, Type,
Category, DataSource, Example, LabeledError, PipelineData, PipelineMetadata, ShellError,
Signature, Span, Spanned, SyntaxShape, Type,
shell_error::{self, io::IoError},
};
use polars::error::PolarsError;
@ -112,11 +112,20 @@ impl PluginCommand for SaveDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let spanned_file: Spanned<String> = call.req(0)?;
debug!("file: {}", spanned_file.item);
let metadata = input.metadata();
let value = input.into_value(call.head)?;
check_writing_into_source_file(
metadata.as_ref(),
&spanned_file.as_ref().map(PathBuf::from),
)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
po @ PolarsPluginObject::NuDataFrame(_) | po @ PolarsPluginObject::NuLazyFrame(_) => {
command(plugin, engine, call, po)
command(plugin, engine, call, po, spanned_file)
}
_ => Err(cant_convert_err(
&value,
@ -132,10 +141,8 @@ fn command(
engine: &EngineInterface,
call: &EvaluatedCall,
polars_object: PolarsPluginObject,
spanned_file: Spanned<String>,
) -> Result<PipelineData, ShellError> {
let spanned_file: Spanned<String> = call.req(0)?;
debug!("file: {}", spanned_file.item);
let resource = Resource::new(plugin, engine, &spanned_file)?;
let type_option: Option<(String, Span)> = call
.get_flag("type")?
@ -223,6 +230,28 @@ fn command(
Ok(PipelineData::empty())
}
fn check_writing_into_source_file(
metadata: Option<&PipelineMetadata>,
dest: &Spanned<PathBuf>,
) -> Result<(), ShellError> {
let Some(DataSource::FilePath(source)) = metadata.map(|meta| &meta.data_source) else {
return Ok(());
};
if &dest.item == source {
return Err(write_into_source_error(dest.span));
}
Ok(())
}
fn write_into_source_error(span: Span) -> ShellError {
polars_file_save_error(
PolarsError::InvalidOperation("attempted to save into source".into()),
span,
)
}
pub(crate) fn polars_file_save_error(e: PolarsError, span: Span) -> ShellError {
ShellError::GenericError {
error: format!("Error saving file: {e}"),
@ -247,17 +276,13 @@ pub fn unknown_file_save_error(span: Span) -> ShellError {
pub(crate) mod test {
use nu_plugin_test_support::PluginTest;
use nu_protocol::{Span, Value};
use tempfile::TempDir;
use uuid::Uuid;
use crate::PolarsPlugin;
fn test_save(cmd: &'static str, extension: &str) -> Result<(), Box<dyn std::error::Error>> {
fn tmp_dir_sandbox() -> Result<(TempDir, PluginTest), Box<dyn std::error::Error>> {
let tmp_dir = tempfile::tempdir()?;
let mut tmp_file = tmp_dir.path().to_owned();
tmp_file.push(format!("{}.{}", Uuid::new_v4(), extension));
let tmp_file_str = tmp_file.to_str().expect("should be able to get file path");
let cmd = format!("{cmd} {tmp_file_str}");
let mut plugin_test = PluginTest::new("polars", PolarsPlugin::new()?.into())?;
plugin_test.engine_state_mut().add_env_var(
"PWD".to_string(),
@ -270,6 +295,17 @@ pub(crate) mod test {
Span::test_data(),
),
);
Ok((tmp_dir, plugin_test))
}
fn test_save(cmd: &'static str, extension: &str) -> Result<(), Box<dyn std::error::Error>> {
let (tmp_dir, mut plugin_test) = tmp_dir_sandbox()?;
let mut tmp_file = tmp_dir.path().to_owned();
tmp_file.push(format!("{}.{}", Uuid::new_v4(), extension));
let tmp_file_str = tmp_file.to_str().expect("should be able to get file path");
let cmd = format!("{cmd} {tmp_file_str}");
let _pipeline_data = plugin_test.eval(&cmd)?;
assert!(tmp_file.exists());
@ -290,4 +326,28 @@ pub(crate) mod test {
extension,
)
}
#[test]
fn test_write_to_source_guard() -> Result<(), Box<dyn std::error::Error>> {
let (tmp_dir, mut plugin_test) = tmp_dir_sandbox()?;
let mut tmp_file = tmp_dir.path().to_owned();
dbg!(&tmp_dir);
tmp_file.push(format!("{}.{}", Uuid::new_v4(), "parquet"));
let tmp_file_str = tmp_file.to_str().expect("Should be able to get file path");
let _setup = plugin_test.eval(&format!(
"[1 2 3] | polars into-df | polars save {tmp_file_str}",
))?;
let output = plugin_test.eval(&format!(
"polars open {tmp_file_str} | polars save {tmp_file_str}"
));
assert!(output.is_err_and(|e| {
e.to_string()
.contains("Error saving file: attempted to save into source")
}));
Ok(())
}
}

View File

@ -112,7 +112,10 @@ impl PluginCommand for Summary {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -251,6 +251,7 @@ impl PluginCommand for ToDataFrame {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let maybe_schema = call
.get_flag("schema")?
.map(|schema| NuSchema::try_from_value(plugin, &schema))
@ -301,6 +302,7 @@ impl PluginCommand for ToDataFrame {
df.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -75,6 +75,7 @@ impl PluginCommand for ToLazyFrame {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let maybe_schema = call
.get_flag("schema")?
.map(|schema| NuSchema::try_from_value(plugin, &schema))
@ -88,6 +89,7 @@ impl PluginCommand for ToLazyFrame {
lazy.cache(plugin, engine, call.head)?.into_value(call.head),
None,
))
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -64,6 +64,7 @@ impl PluginCommand for ExprAlias {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let alias: String = call.req(0)?;
let expr = NuExpression::try_from_pipeline(plugin, input, call.head)?;
@ -71,6 +72,7 @@ impl PluginCommand for ExprAlias {
expr.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -58,13 +58,15 @@ impl PluginCommand for ExprArgWhere {
plugin: &Self::Plugin,
engine: &EngineInterface,
call: &EvaluatedCall,
_input: PipelineData,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value: Value = call.req(0)?;
let expr = NuExpression::try_from_value(plugin, &value)?;
let expr: NuExpression = arg_where(expr.into_polars()).into();
expr.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -90,6 +90,7 @@ impl PluginCommand for CastDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuLazyFrame(lazy) => {
@ -116,6 +117,7 @@ impl PluginCommand for CastDF {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -119,8 +119,9 @@ impl PluginCommand for ExprCol {
plugin: &Self::Plugin,
engine: &EngineInterface,
call: &EvaluatedCall,
_input: PipelineData,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let mut names: Vec<String> = vec![call.req(0)?];
names.extend(call.rest(1)?);
@ -144,6 +145,7 @@ impl PluginCommand for ExprCol {
expr.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -98,8 +98,11 @@ impl PluginCommand for ConcatDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let maybe_df = NuLazyFrame::try_from_pipeline_coerce(plugin, input, call.head).ok();
command_lazy(plugin, engine, call, maybe_df).map_err(LabeledError::from)
command_lazy(plugin, engine, call, maybe_df)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -52,7 +52,10 @@ impl PluginCommand for CutSeries {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, nu_protocol::LabeledError> {
command(plugin, engine, call, input).map_err(|e| e.into())
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(|e| e.into())
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -59,7 +59,10 @@ impl PluginCommand for DropDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -72,7 +72,10 @@ impl PluginCommand for DropDuplicates {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -99,7 +99,10 @@ impl PluginCommand for DropNulls {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -119,7 +119,10 @@ impl PluginCommand for LazyExplode {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
explode(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
explode(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -91,6 +91,7 @@ impl PluginCommand for LazyFillNA {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let fill: Value = call.req(0)?;
let value = input.into_value(call.head)?;
@ -119,6 +120,7 @@ impl PluginCommand for LazyFillNA {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -68,6 +68,7 @@ impl PluginCommand for LazyFillNull {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let fill: Value = call.req(0)?;
let value = input.into_value(call.head)?;
@ -85,6 +86,7 @@ impl PluginCommand for LazyFillNull {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -109,11 +109,14 @@ impl PluginCommand for LazyFilter {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let expr_value: Value = call.req(0)?;
let filter_expr = NuExpression::try_from_value(plugin, &expr_value)?;
let pipeline_value = input.into_value(call.head)?;
let lazy = NuLazyFrame::try_from_value_coerce(plugin, &pipeline_value)?;
command(plugin, engine, call, lazy, filter_expr).map_err(LabeledError::from)
command(plugin, engine, call, lazy, filter_expr)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,6 +84,7 @@ impl PluginCommand for FilterWith {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_eager(plugin, engine, call, df),
@ -94,6 +95,7 @@ impl PluginCommand for FilterWith {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -97,6 +97,7 @@ impl PluginCommand for FirstDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => {
@ -113,6 +114,7 @@ impl PluginCommand for FirstDF {
.map_err(LabeledError::from)
}
}
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -117,7 +117,10 @@ impl PluginCommand for LazyFlatten {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
explode(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
explode(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -59,7 +59,10 @@ impl PluginCommand for GetDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -241,6 +241,7 @@ impl PluginCommand for LazyJoin {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let left = call.has_flag("left")?;
let full = call.has_flag("full")?;
let cross = call.has_flag("cross")?;
@ -333,6 +334,7 @@ impl PluginCommand for LazyJoin {
let lazy = NuLazyFrame::new(from_eager, lazy);
lazy.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -72,6 +72,7 @@ impl PluginCommand for LastDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => {
@ -88,6 +89,7 @@ impl PluginCommand for LastDF {
.map_err(LabeledError::from)
}
}
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -53,11 +53,13 @@ impl PluginCommand for ExprLen {
plugin: &Self::Plugin,
engine: &EngineInterface,
call: &EvaluatedCall,
_input: PipelineData,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let res: NuExpression = polars::prelude::len().into();
res.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -193,6 +193,7 @@ impl PluginCommand for PivotDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
match PolarsPluginObject::try_from_pipeline(plugin, input, call.head)? {
PolarsPluginObject::NuDataFrame(df) => command_eager(plugin, engine, call, df),
PolarsPluginObject::NuLazyFrame(lazy) => {
@ -207,6 +208,7 @@ impl PluginCommand for PivotDF {
}),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -53,7 +53,10 @@ impl PluginCommand for QCutSeries {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, nu_protocol::LabeledError> {
command(plugin, engine, call, input).map_err(|e| e.into())
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(|e| e.into())
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -63,12 +63,15 @@ impl PluginCommand for QueryDf {
fn run(
&self,
plugin: &PolarsPlugin,
plugin: &Self::Plugin,
engine: &EngineInterface,
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -119,6 +119,7 @@ impl PluginCommand for RenameDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value).map_err(LabeledError::from)? {
PolarsPluginObject::NuDataFrame(df) => {
@ -130,6 +131,7 @@ impl PluginCommand for RenameDF {
_ => Err(LabeledError::new(format!("Unsupported type: {value:?}"))
.with_label("Unsupported Type", call.head)),
}
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -59,11 +59,13 @@ impl PluginCommand for LazyReverse {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let lazy = NuLazyFrame::try_from_pipeline_coerce(plugin, input, call.head)
.map_err(LabeledError::from)?;
let lazy = NuLazyFrame::new(lazy.from_eager, lazy.to_polars().reverse());
lazy.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -103,6 +103,7 @@ impl PluginCommand for LazySelect {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let vals: Vec<Value> = call.rest(0)?;
let expr_value = Value::list(vals, call.head);
let expressions = NuExpression::extract_exprs(plugin, expr_value)?;
@ -112,6 +113,7 @@ impl PluginCommand for LazySelect {
let lazy: NuLazyFrame = lazy.to_polars().select(&expressions).into();
lazy.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -92,6 +92,7 @@ impl PluginCommand for Shift {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
@ -106,6 +107,7 @@ impl PluginCommand for Shift {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -58,7 +58,10 @@ impl PluginCommand for SliceDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -115,6 +115,7 @@ impl PluginCommand for LazySortBy {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let vals: Vec<Value> = call.rest(0)?;
let expr_value = Value::list(vals, call.head);
let expressions = NuExpression::extract_exprs(plugin, expr_value)?;
@ -160,6 +161,7 @@ impl PluginCommand for LazySortBy {
);
lazy.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -89,7 +89,10 @@ impl PluginCommand for TakeDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -176,6 +176,7 @@ impl PluginCommand for Unique {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
@ -200,6 +201,7 @@ impl PluginCommand for Unique {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -83,6 +83,7 @@ impl PluginCommand for UnnestDF {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
match PolarsPluginObject::try_from_pipeline(plugin, input, call.head)? {
PolarsPluginObject::NuDataFrame(df) => command_eager(plugin, engine, call, df),
PolarsPluginObject::NuLazyFrame(lazy) => command_lazy(plugin, engine, call, lazy),
@ -95,6 +96,7 @@ impl PluginCommand for UnnestDF {
}),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -187,6 +187,7 @@ impl PluginCommand for Unpivot {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
match PolarsPluginObject::try_from_pipeline(plugin, input, call.head)? {
PolarsPluginObject::NuDataFrame(df) => command_eager(plugin, engine, call, df),
PolarsPluginObject::NuLazyFrame(lazy) => command_lazy(plugin, engine, call, lazy),
@ -199,6 +200,7 @@ impl PluginCommand for Unpivot {
}),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -148,6 +148,7 @@ impl PluginCommand for WithColumn {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_eager(plugin, engine, call, df),
@ -160,6 +161,7 @@ impl PluginCommand for WithColumn {
}),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -183,7 +183,10 @@ impl PluginCommand for AsDate {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -236,7 +236,10 @@ impl PluginCommand for AsDateTime {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -137,6 +137,7 @@ impl PluginCommand for ConvertTimeZone {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
@ -152,6 +153,7 @@ impl PluginCommand for ConvertTimeZone {
_ => Err(cant_convert_err(&value, &[PolarsPluginType::NuExpression])),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -131,6 +131,7 @@ impl PluginCommand for ExprDatePart {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let part: Spanned<String> = call.req(0)?;
let expr = NuExpression::try_from_pipeline(plugin, input, call.head)?;
@ -158,6 +159,7 @@ impl PluginCommand for ExprDatePart {
}.into();
expr.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -77,6 +77,14 @@ impl PluginCommand for GetDay {
]
}
fn extra_description(&self) -> &str {
""
}
fn search_terms(&self) -> Vec<&str> {
vec![]
}
fn run(
&self,
plugin: &Self::Plugin,
@ -84,15 +92,10 @@ impl PluginCommand for GetDay {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
}
fn extra_description(&self) -> &str {
""
}
fn search_terms(&self) -> Vec<&str> {
vec![]
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -100,7 +100,10 @@ impl PluginCommand for GetHour {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,7 +84,10 @@ impl PluginCommand for GetMinute {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,7 +84,10 @@ impl PluginCommand for GetMonth {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,7 +84,10 @@ impl PluginCommand for GetNanosecond {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,7 +84,10 @@ impl PluginCommand for GetOrdinal {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,7 +84,10 @@ impl PluginCommand for GetSecond {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,7 +84,10 @@ impl PluginCommand for GetWeek {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,7 +84,10 @@ impl PluginCommand for GetWeekDay {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,7 +84,10 @@ impl PluginCommand for GetYear {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -216,6 +216,7 @@ impl PluginCommand for ReplaceTimeZone {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
let ambiguous = match call.get_flag::<Value>("ambiguous")? {
@ -269,6 +270,7 @@ impl PluginCommand for ReplaceTimeZone {
_ => Err(cant_convert_err(&value, &[PolarsPluginType::NuExpression])),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -94,6 +94,7 @@ impl PluginCommand for StrFTime {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuDataFrame(df) => command_df(plugin, engine, call, df),
@ -111,6 +112,7 @@ impl PluginCommand for StrFTime {
)),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -150,7 +150,10 @@ impl PluginCommand for Truncate {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
command(plugin, engine, call, input).map_err(LabeledError::from)
let metadata = input.metadata();
command(plugin, engine, call, input)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
fn extra_description(&self) -> &str {

View File

@ -67,12 +67,14 @@ impl PluginCommand for ToDecimal {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuExpression(expr) => command(plugin, engine, call, expr),
_ => Err(cant_convert_err(&value, &[PolarsPluginType::NuExpression])),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -61,12 +61,14 @@ impl PluginCommand for ToInteger {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuExpression(expr) => command(plugin, engine, call, expr),
_ => Err(cant_convert_err(&value, &[PolarsPluginType::NuExpression])),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -116,12 +116,14 @@ impl PluginCommand for ListContains {
call: &EvaluatedCall,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let value = input.into_value(call.head)?;
match PolarsPluginObject::try_from_value(plugin, &value)? {
PolarsPluginObject::NuExpression(expr) => command_expr(plugin, engine, call, expr),
_ => Err(cant_convert_err(&value, &[PolarsPluginType::NuExpression])),
}
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

View File

@ -84,8 +84,9 @@ impl PluginCommand for ExprConcatStr {
plugin: &Self::Plugin,
engine: &EngineInterface,
call: &EvaluatedCall,
_input: PipelineData,
input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let metadata = input.metadata();
let separator: String = call.req(0)?;
let value: Value = call.req(1)?;
@ -94,6 +95,7 @@ impl PluginCommand for ExprConcatStr {
expr.to_pipeline_data(plugin, engine, call.head)
.map_err(LabeledError::from)
.map(|pd| pd.set_metadata(metadata))
}
}

Some files were not shown because too many files have changed in this diff Show More