Fixing NuLazyFrame/NuDataFrame conversion issues (#12538)

# Description

@maxim-uvarov brought up another case where converting back and forth
between eager and lazy dataframes was not working correctly:

```
> [[a b]; [6 2] [1 4] [4 1]] | polars into-lazy | polars append -c ([[a b]; [6 2] [1 4] [4 1]] | polars into-df)
Error: nu:🐚:cant_convert

  × Can't convert to NuDataFrame.
   ╭─[entry #1:1:49]
 1 │ [[a b]; [6 2] [1 4] [4 1]] | polars into-lazy | polars append -c ([[a b]; [6 2] [1 4] [4 1]] | polars into-df)
   ·                                                 ──────┬──────
   ·                                                       ╰── can't convert NuLazyFrameCustomValue to NuDataFrame
   ╰────
```

This pull request fixes this case and glaringly obvious similar cases I
could find.

Co-authored-by: Jack Wright <jack.wright@disqo.com>
This commit is contained in:
Jack Wright 2024-04-16 09:16:37 -07:00 committed by GitHub
parent 48e4448e55
commit a7a5ec31be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 25 additions and 18 deletions

View file

@ -126,7 +126,7 @@ fn command(
}; };
let df_other = NuDataFrame::try_from_value_coerce(plugin, &other, call.head)?; let df_other = NuDataFrame::try_from_value_coerce(plugin, &other, call.head)?;
let df = NuDataFrame::try_from_pipeline(plugin, input, call.head)?; let df = NuDataFrame::try_from_pipeline_coerce(plugin, input, call.head)?;
let df = df.append_df(&df_other, axis, call.head)?; let df = df.append_df(&df_other, axis, call.head)?;
df.to_pipeline_data(plugin, engine, call.head) df.to_pipeline_data(plugin, engine, call.head)

View file

@ -1,5 +1,5 @@
use crate::{ use crate::{
values::{Column, CustomValueSupport}, values::{Column, CustomValueSupport, NuLazyFrame},
PolarsPlugin, PolarsPlugin,
}; };
@ -98,8 +98,8 @@ impl PluginCommand for FirstDF {
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, LabeledError> { ) -> Result<PipelineData, LabeledError> {
let value = input.into_value(call.head); let value = input.into_value(call.head);
if NuDataFrame::can_downcast(&value) { if NuDataFrame::can_downcast(&value) || NuLazyFrame::can_downcast(&value) {
let df = NuDataFrame::try_from_value(plugin, &value)?; let df = NuDataFrame::try_from_value_coerce(plugin, &value, call.head)?;
command(plugin, engine, call, df).map_err(|e| e.into()) command(plugin, engine, call, df).map_err(|e| e.into())
} else { } else {
let expr = NuExpression::try_from_value(plugin, &value)?; let expr = NuExpression::try_from_value(plugin, &value)?;

View file

@ -72,7 +72,7 @@ fn command(
let columns: Vec<Value> = call.rest(0)?; let columns: Vec<Value> = call.rest(0)?;
let (col_string, col_span) = convert_columns_string(columns, call.head)?; let (col_string, col_span) = convert_columns_string(columns, call.head)?;
let df = NuDataFrame::try_from_pipeline(plugin, input, call.head)?; let df = NuDataFrame::try_from_pipeline_coerce(plugin, input, call.head)?;
let df = df let df = df
.as_ref() .as_ref()

View file

@ -1,5 +1,5 @@
use crate::{ use crate::{
values::{Column, CustomValueSupport}, values::{Column, CustomValueSupport, NuLazyFrame},
PolarsPlugin, PolarsPlugin,
}; };
@ -73,8 +73,8 @@ impl PluginCommand for LastDF {
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, LabeledError> { ) -> Result<PipelineData, LabeledError> {
let value = input.into_value(call.head); let value = input.into_value(call.head);
if NuDataFrame::can_downcast(&value) { if NuDataFrame::can_downcast(&value) || NuLazyFrame::can_downcast(&value) {
let df = NuDataFrame::try_from_value(plugin, &value)?; let df = NuDataFrame::try_from_value_coerce(plugin, &value, call.head)?;
command(plugin, engine, call, df).map_err(|e| e.into()) command(plugin, engine, call, df).map_err(|e| e.into())
} else { } else {
let expr = NuExpression::try_from_value(plugin, &value)?; let expr = NuExpression::try_from_value(plugin, &value)?;

View file

@ -141,7 +141,7 @@ fn command(
let (id_col_string, id_col_span) = convert_columns_string(id_col, call.head)?; let (id_col_string, id_col_span) = convert_columns_string(id_col, call.head)?;
let (val_col_string, val_col_span) = convert_columns_string(val_col, call.head)?; let (val_col_string, val_col_span) = convert_columns_string(val_col, call.head)?;
let df = NuDataFrame::try_from_pipeline(plugin, input, call.head)?; let df = NuDataFrame::try_from_pipeline_coerce(plugin, input, call.head)?;
check_column_datatypes(df.as_ref(), &id_col_string, id_col_span)?; check_column_datatypes(df.as_ref(), &id_col_string, id_col_span)?;
check_column_datatypes(df.as_ref(), &val_col_string, val_col_span)?; check_column_datatypes(df.as_ref(), &val_col_string, val_col_span)?;

View file

@ -92,7 +92,7 @@ fn command(
let replace: bool = call.has_flag("replace")?; let replace: bool = call.has_flag("replace")?;
let shuffle: bool = call.has_flag("shuffle")?; let shuffle: bool = call.has_flag("shuffle")?;
let df = NuDataFrame::try_from_pipeline(plugin, input, call.head)?; let df = NuDataFrame::try_from_pipeline_coerce(plugin, input, call.head)?;
let df = match (rows, fraction) { let df = match (rows, fraction) {
(Some(rows), None) => df (Some(rows), None) => df

View file

@ -101,7 +101,8 @@ fn command(
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let index_value: Value = call.req(0)?; let index_value: Value = call.req(0)?;
let index_span = index_value.span(); let index_span = index_value.span();
let index = NuDataFrame::try_from_value(plugin, &index_value)?.as_series(index_span)?; let index = NuDataFrame::try_from_value_coerce(plugin, &index_value, call.head)?
.as_series(index_span)?;
let casted = match index.dtype() { let casted = match index.dtype() {
DataType::UInt32 | DataType::UInt64 | DataType::Int32 | DataType::Int64 => index DataType::UInt32 | DataType::UInt64 | DataType::Int32 | DataType::Int64 => index

View file

@ -4,7 +4,11 @@ use nu_protocol::{
SyntaxShape, Type, Value, SyntaxShape, Type, Value,
}; };
use crate::{dataframe::values::NuExpression, values::CustomValueSupport, PolarsPlugin}; use crate::{
dataframe::values::NuExpression,
values::{CustomValueSupport, NuLazyFrame},
PolarsPlugin,
};
use super::super::values::NuDataFrame; use super::super::values::NuDataFrame;
@ -86,7 +90,7 @@ impl PluginCommand for ToNu {
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, LabeledError> { ) -> Result<PipelineData, LabeledError> {
let value = input.into_value(call.head); let value = input.into_value(call.head);
if NuDataFrame::can_downcast(&value) { if NuDataFrame::can_downcast(&value) || NuLazyFrame::can_downcast(&value) {
dataframe_command(plugin, call, value) dataframe_command(plugin, call, value)
} else { } else {
expression_command(plugin, call, value) expression_command(plugin, call, value)
@ -103,7 +107,7 @@ fn dataframe_command(
let rows: Option<usize> = call.get_flag("rows")?; let rows: Option<usize> = call.get_flag("rows")?;
let tail: bool = call.has_flag("tail")?; let tail: bool = call.has_flag("tail")?;
let df = NuDataFrame::try_from_value(plugin, &input)?; let df = NuDataFrame::try_from_value_coerce(plugin, &input, call.head)?;
let values = if tail { let values = if tail {
df.tail(rows, call.head)? df.tail(rows, call.head)?

View file

@ -145,7 +145,8 @@ fn command_eager(
let df = lazy.collect(call.head)?; let df = lazy.collect(call.head)?;
df.to_pipeline_data(plugin, engine, call.head) df.to_pipeline_data(plugin, engine, call.head)
} else { } else {
let mut other = NuDataFrame::try_from_value(plugin, &new_column)?.as_series(column_span)?; let mut other = NuDataFrame::try_from_value_coerce(plugin, &new_column, call.head)?
.as_series(column_span)?;
let name = match call.get_flag::<String>("name")? { let name = match call.get_flag::<String>("name")? {
Some(name) => name, Some(name) => name,

View file

@ -165,7 +165,7 @@ fn command_df(
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let other_value: Value = call.req(0)?; let other_value: Value = call.req(0)?;
let other_span = other_value.span(); let other_span = other_value.span();
let other_df = NuDataFrame::try_from_value(plugin, &other_value)?; let other_df = NuDataFrame::try_from_value_coerce(plugin, &other_value, call.head)?;
let other = other_df.as_series(other_span)?; let other = other_df.as_series(other_span)?;
let series = df.as_series(call.head)?; let series = df.as_series(call.head)?;
@ -181,8 +181,9 @@ fn command_df(
res.rename("is_in"); res.rename("is_in");
let df = NuDataFrame::try_from_series_vec(vec![res.into_series()], call.head)?; let mut new_df = NuDataFrame::try_from_series_vec(vec![res.into_series()], call.head)?;
df.to_pipeline_data(plugin, engine, call.head) new_df.from_lazy = df.from_lazy;
new_df.to_pipeline_data(plugin, engine, call.head)
} }
#[cfg(test)] #[cfg(test)]