mirror of
https://github.com/nushell/nushell.git
synced 2025-08-16 05:57:51 +02:00
All is a DataFrame (#3812)
* nuframe in its own type in UntaggedValue * Removed eager dataframe from enum * Dataframe created from list of values * Corrected order in dataframe columns * Returned tag from stream collection * Removed series from dataframe commands * Arithmetic operators * forced push * forced push * Replace all command * String commands * appending operations with dfs * Testing suite for dataframes * Unit test for dataframe commands * improved equality for dataframes
This commit is contained in:
@ -131,7 +131,7 @@ impl InlineShape {
|
||||
UntaggedValue::Error(_) => InlineShape::Error,
|
||||
UntaggedValue::Block(_) => InlineShape::Block,
|
||||
#[cfg(feature = "dataframe")]
|
||||
UntaggedValue::DataFrame(_) => InlineShape::DataFrame,
|
||||
UntaggedValue::DataFrame(_) | UntaggedValue::FrameStruct(_) => InlineShape::DataFrame,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,9 @@ fn helper(v: &Value) -> Result<toml::Value, ShellError> {
|
||||
UntaggedValue::Error(e) => return Err(e.clone()),
|
||||
UntaggedValue::Block(_) => toml::Value::String("<Block>".to_string()),
|
||||
#[cfg(feature = "dataframe")]
|
||||
UntaggedValue::DataFrame(_) => toml::Value::String("<DataFrame>".to_string()),
|
||||
UntaggedValue::DataFrame(_) | UntaggedValue::FrameStruct(_) => {
|
||||
toml::Value::String("<DataFrame>".to_string())
|
||||
}
|
||||
UntaggedValue::Primitive(Primitive::Range(_)) => toml::Value::String("<Range>".to_string()),
|
||||
UntaggedValue::Primitive(Primitive::Binary(b)) => {
|
||||
toml::Value::Array(b.iter().map(|x| toml::Value::Integer(*x as i64)).collect())
|
||||
|
@ -1,218 +1,291 @@
|
||||
use bigdecimal::BigDecimal;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::dataframe::NuDataFrame;
|
||||
use nu_protocol::hir::Operator;
|
||||
use nu_protocol::{
|
||||
dataframe::{NuSeries, PolarsData},
|
||||
Primitive, ShellTypeName, UntaggedValue, Value,
|
||||
};
|
||||
use nu_protocol::{Primitive, ShellTypeName, UntaggedValue, Value};
|
||||
use nu_source::Span;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
use polars::prelude::{
|
||||
BooleanType, ChunkCompare, ChunkedArray, DataType, Float64Type, Int64Type, IntoSeries,
|
||||
NumOpsDispatchChecked, PolarsError, Series,
|
||||
BooleanType, ChunkCompare, ChunkedArray, DataFrame, DataType, Float64Type, Int64Type,
|
||||
IntoSeries, NumOpsDispatchChecked, PolarsError, Series,
|
||||
};
|
||||
use std::ops::{Add, BitAnd, BitOr, Div, Mul, Sub};
|
||||
|
||||
pub fn compute_between_series(
|
||||
pub fn compute_between_dataframes(
|
||||
operator: Operator,
|
||||
left: &Value,
|
||||
right: &Value,
|
||||
) -> Result<UntaggedValue, (&'static str, &'static str)> {
|
||||
if let (
|
||||
UntaggedValue::DataFrame(PolarsData::Series(lhs)),
|
||||
UntaggedValue::DataFrame(PolarsData::Series(rhs)),
|
||||
) = (&left.value, &right.value)
|
||||
if let (UntaggedValue::DataFrame(lhs), UntaggedValue::DataFrame(rhs)) =
|
||||
(&left.value, &right.value)
|
||||
{
|
||||
if lhs.as_ref().dtype() != rhs.as_ref().dtype() {
|
||||
return Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Mixed datatypes",
|
||||
"this datatype does not match the right hand side datatype",
|
||||
&left.tag.span,
|
||||
format!(
|
||||
"Perhaps you want to change this datatype to '{}'",
|
||||
lhs.as_ref().dtype()
|
||||
),
|
||||
&right.tag.span,
|
||||
),
|
||||
));
|
||||
}
|
||||
let operation_span = left.tag.span.until(right.tag.span);
|
||||
match (lhs.is_series(), rhs.is_series()) {
|
||||
(true, true) => {
|
||||
let lhs = &lhs
|
||||
.as_series(&left.tag.span)
|
||||
.expect("Already checked that is a series");
|
||||
let rhs = &rhs
|
||||
.as_series(&right.tag.span)
|
||||
.expect("Already checked that is a series");
|
||||
|
||||
if lhs.as_ref().len() != rhs.as_ref().len() {
|
||||
return Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Different length",
|
||||
"this column length does not match the right hand column length",
|
||||
&left.tag.span,
|
||||
)));
|
||||
}
|
||||
if lhs.dtype() != rhs.dtype() {
|
||||
return Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Mixed datatypes",
|
||||
"this datatype does not match the right hand side datatype",
|
||||
&left.tag.span,
|
||||
format!(
|
||||
"Perhaps you want to change this datatype to '{}'",
|
||||
lhs.as_ref().dtype()
|
||||
),
|
||||
&right.tag.span,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
match operator {
|
||||
Operator::Plus => {
|
||||
let mut res = lhs.as_ref() + rhs.as_ref();
|
||||
let name = format!("sum_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Operator::Minus => {
|
||||
let mut res = lhs.as_ref() - rhs.as_ref();
|
||||
let name = format!("sub_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Operator::Multiply => {
|
||||
let mut res = lhs.as_ref() * rhs.as_ref();
|
||||
let name = format!("mul_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Operator::Divide => {
|
||||
let res = lhs.as_ref().checked_div(rhs.as_ref());
|
||||
match res {
|
||||
Ok(mut res) => {
|
||||
let name = format!("div_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Err(e) => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Division error",
|
||||
format!("{}", e),
|
||||
if lhs.len() != rhs.len() {
|
||||
return Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Different length",
|
||||
"this column length does not match the right hand column length",
|
||||
&left.tag.span,
|
||||
))),
|
||||
)));
|
||||
}
|
||||
}
|
||||
Operator::Equal => {
|
||||
let mut res = Series::eq(lhs.as_ref(), rhs.as_ref()).into_series();
|
||||
let name = format!("eq_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Operator::NotEqual => {
|
||||
let mut res = Series::neq(lhs.as_ref(), rhs.as_ref()).into_series();
|
||||
let name = format!("neq_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Operator::LessThan => {
|
||||
let mut res = Series::lt(lhs.as_ref(), rhs.as_ref()).into_series();
|
||||
let name = format!("lt_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Operator::LessThanOrEqual => {
|
||||
let mut res = Series::lt_eq(lhs.as_ref(), rhs.as_ref()).into_series();
|
||||
let name = format!("lte_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Operator::GreaterThan => {
|
||||
let mut res = Series::gt(lhs.as_ref(), rhs.as_ref()).into_series();
|
||||
let name = format!("gt_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Operator::GreaterThanOrEqual => {
|
||||
let mut res = Series::gt_eq(lhs.as_ref(), rhs.as_ref()).into_series();
|
||||
let name = format!("gte_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
Operator::And => match lhs.as_ref().dtype() {
|
||||
DataType::Boolean => {
|
||||
let lhs_cast = lhs.as_ref().bool();
|
||||
let rhs_cast = rhs.as_ref().bool();
|
||||
|
||||
match (lhs_cast, rhs_cast) {
|
||||
(Ok(l), Ok(r)) => {
|
||||
let mut res = l.bitand(r).into_series();
|
||||
let name =
|
||||
format!("and_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Casting error",
|
||||
"unable to cast to boolean",
|
||||
&left.tag.span,
|
||||
"unable to cast to boolean",
|
||||
&right.tag.span,
|
||||
),
|
||||
)),
|
||||
}
|
||||
compute_between_series(operator, lhs, rhs, &operation_span)
|
||||
}
|
||||
_ => {
|
||||
if lhs.as_ref().height() != rhs.as_ref().height() {
|
||||
return Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Mixed datatypes",
|
||||
"this datatype size does not match the right hand side datatype",
|
||||
&left.tag.span,
|
||||
"Perhaps you want to select another dataframe with same number of rows",
|
||||
&right.tag.span,
|
||||
),
|
||||
));
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Incorrect datatype",
|
||||
"And operation can only be done with boolean values",
|
||||
&left.tag.span,
|
||||
))),
|
||||
},
|
||||
Operator::Or => match lhs.as_ref().dtype() {
|
||||
DataType::Boolean => {
|
||||
let lhs_cast = lhs.as_ref().bool();
|
||||
let rhs_cast = rhs.as_ref().bool();
|
||||
|
||||
match (lhs_cast, rhs_cast) {
|
||||
(Ok(l), Ok(r)) => {
|
||||
let mut res = l.bitor(r).into_series();
|
||||
let name =
|
||||
format!("or_{}_{}", lhs.as_ref().name(), rhs.as_ref().name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuSeries::series_to_untagged(res))
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Casting error",
|
||||
"unable to cast to boolean",
|
||||
&left.tag.span,
|
||||
"unable to cast to boolean",
|
||||
&right.tag.span,
|
||||
),
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Incorrect datatype",
|
||||
"And operation can only be done with boolean values",
|
||||
&left.tag.span,
|
||||
))),
|
||||
},
|
||||
_ => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Incorrect datatype",
|
||||
"unable to use this datatype for this operation",
|
||||
&left.tag.span,
|
||||
))),
|
||||
between_dataframes(operator, lhs, rhs, &operation_span)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Err((left.type_name(), right.type_name()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn between_dataframes(
|
||||
operator: Operator,
|
||||
lhs: &NuDataFrame,
|
||||
rhs: &NuDataFrame,
|
||||
operation_span: &Span,
|
||||
) -> Result<UntaggedValue, (&'static str, &'static str)> {
|
||||
match operator {
|
||||
Operator::Plus => {
|
||||
let mut columns: Vec<&str> = Vec::new();
|
||||
|
||||
let new = lhs
|
||||
.as_ref()
|
||||
.get_columns()
|
||||
.iter()
|
||||
.chain(rhs.as_ref().get_columns().iter())
|
||||
.map(|s| {
|
||||
let name = if columns.contains(&s.name()) {
|
||||
format!("{}_{}", s.name(), "x")
|
||||
} else {
|
||||
columns.push(s.name());
|
||||
s.name().to_string()
|
||||
};
|
||||
|
||||
let mut series = s.clone();
|
||||
series.rename(name.as_str());
|
||||
series
|
||||
})
|
||||
.collect::<Vec<Series>>();
|
||||
|
||||
match DataFrame::new(new) {
|
||||
Ok(df) => Ok(NuDataFrame::dataframe_to_untagged(df)),
|
||||
Err(e) => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Appending error",
|
||||
format!("{}", e),
|
||||
operation_span,
|
||||
))),
|
||||
}
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Incorrect datatype",
|
||||
"unable to use this datatype for this operation",
|
||||
operation_span,
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_between_series(
|
||||
operator: Operator,
|
||||
lhs: &Series,
|
||||
rhs: &Series,
|
||||
operation_span: &Span,
|
||||
) -> Result<UntaggedValue, (&'static str, &'static str)> {
|
||||
match operator {
|
||||
Operator::Plus => {
|
||||
let mut res = lhs + rhs;
|
||||
let name = format!("sum_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Operator::Minus => {
|
||||
let mut res = lhs - rhs;
|
||||
let name = format!("sub_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Operator::Multiply => {
|
||||
let mut res = lhs * rhs;
|
||||
let name = format!("mul_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Operator::Divide => {
|
||||
let res = lhs.checked_div(rhs);
|
||||
match res {
|
||||
Ok(mut res) => {
|
||||
let name = format!("div_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Err(e) => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Division error",
|
||||
format!("{}", e),
|
||||
operation_span,
|
||||
))),
|
||||
}
|
||||
}
|
||||
Operator::Equal => {
|
||||
let mut res = Series::eq(lhs, rhs).into_series();
|
||||
let name = format!("eq_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Operator::NotEqual => {
|
||||
let mut res = Series::neq(lhs, rhs).into_series();
|
||||
let name = format!("neq_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Operator::LessThan => {
|
||||
let mut res = Series::lt(lhs, rhs).into_series();
|
||||
let name = format!("lt_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Operator::LessThanOrEqual => {
|
||||
let mut res = Series::lt_eq(lhs, rhs).into_series();
|
||||
let name = format!("lte_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Operator::GreaterThan => {
|
||||
let mut res = Series::gt(lhs, rhs).into_series();
|
||||
let name = format!("gt_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Operator::GreaterThanOrEqual => {
|
||||
let mut res = Series::gt_eq(lhs, rhs).into_series();
|
||||
let name = format!("gte_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, operation_span))
|
||||
}
|
||||
Operator::And => match lhs.dtype() {
|
||||
DataType::Boolean => {
|
||||
let lhs_cast = lhs.bool();
|
||||
let rhs_cast = rhs.bool();
|
||||
|
||||
match (lhs_cast, rhs_cast) {
|
||||
(Ok(l), Ok(r)) => {
|
||||
let mut res = l.bitand(r).into_series();
|
||||
let name = format!("and_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, &operation_span))
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Casting error",
|
||||
"unable to cast to boolean",
|
||||
operation_span,
|
||||
))),
|
||||
}
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Incorrect datatype",
|
||||
"And operation can only be done with boolean values",
|
||||
operation_span,
|
||||
))),
|
||||
},
|
||||
Operator::Or => match lhs.dtype() {
|
||||
DataType::Boolean => {
|
||||
let lhs_cast = lhs.bool();
|
||||
let rhs_cast = rhs.bool();
|
||||
|
||||
match (lhs_cast, rhs_cast) {
|
||||
(Ok(l), Ok(r)) => {
|
||||
let mut res = l.bitor(r).into_series();
|
||||
let name = format!("or_{}_{}", lhs.name(), rhs.name());
|
||||
res.rename(name.as_ref());
|
||||
Ok(NuDataFrame::series_to_untagged(res, &operation_span))
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Casting error",
|
||||
"unable to cast to boolean",
|
||||
operation_span,
|
||||
))),
|
||||
}
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Incorrect datatype",
|
||||
"And operation can only be done with boolean values",
|
||||
operation_span,
|
||||
))),
|
||||
},
|
||||
_ => Ok(UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Incorrect datatype",
|
||||
"unable to use this datatype for this operation",
|
||||
operation_span,
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_series_single_value(
|
||||
operator: Operator,
|
||||
left: &Value,
|
||||
right: &Value,
|
||||
) -> Result<UntaggedValue, (&'static str, &'static str)> {
|
||||
if let (UntaggedValue::DataFrame(PolarsData::Series(lhs)), UntaggedValue::Primitive(_)) =
|
||||
if let (UntaggedValue::DataFrame(lhs), UntaggedValue::Primitive(_)) =
|
||||
(&left.value, &right.value)
|
||||
{
|
||||
let lhs = match lhs.as_series(&left.tag.span) {
|
||||
Ok(series) => series,
|
||||
Err(e) => return Ok(UntaggedValue::Error(e)),
|
||||
};
|
||||
|
||||
match operator {
|
||||
Operator::Plus => match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compute_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
<ChunkedArray<Int64Type>>::add,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compute_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
<ChunkedArray<Int64Type>>::add,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(compute_series_decimal(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
<ChunkedArray<Float64Type>>::add,
|
||||
&left.tag.span,
|
||||
@ -229,20 +302,20 @@ pub fn compute_series_single_value(
|
||||
},
|
||||
Operator::Minus => match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compute_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
<ChunkedArray<Int64Type>>::sub,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compute_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
<ChunkedArray<Int64Type>>::sub,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(compute_series_decimal(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
<ChunkedArray<Float64Type>>::sub,
|
||||
&left.tag.span,
|
||||
@ -259,20 +332,20 @@ pub fn compute_series_single_value(
|
||||
},
|
||||
Operator::Multiply => match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compute_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
<ChunkedArray<Int64Type>>::mul,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compute_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
<ChunkedArray<Int64Type>>::mul,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(compute_series_decimal(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
<ChunkedArray<Float64Type>>::mul,
|
||||
&left.tag.span,
|
||||
@ -297,7 +370,7 @@ pub fn compute_series_single_value(
|
||||
)))
|
||||
} else {
|
||||
Ok(compute_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
<ChunkedArray<Int64Type>>::div,
|
||||
&left.tag.span,
|
||||
@ -313,7 +386,7 @@ pub fn compute_series_single_value(
|
||||
)))
|
||||
} else {
|
||||
Ok(compute_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
<ChunkedArray<Int64Type>>::div,
|
||||
@ -330,7 +403,7 @@ pub fn compute_series_single_value(
|
||||
)))
|
||||
} else {
|
||||
Ok(compute_series_decimal(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
<ChunkedArray<Float64Type>>::div,
|
||||
&left.tag.span,
|
||||
@ -350,20 +423,20 @@ pub fn compute_series_single_value(
|
||||
Operator::Equal => {
|
||||
match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
ChunkedArray::eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
ChunkedArray::eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(
|
||||
compare_series_decimal(lhs.as_ref(), val, ChunkedArray::eq, &left.tag.span),
|
||||
compare_series_decimal(&lhs, val, ChunkedArray::eq, &left.tag.span),
|
||||
),
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
@ -376,53 +449,52 @@ pub fn compute_series_single_value(
|
||||
)),
|
||||
}
|
||||
}
|
||||
Operator::NotEqual => match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
val,
|
||||
ChunkedArray::neq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
ChunkedArray::neq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(compare_series_decimal(
|
||||
lhs.as_ref(),
|
||||
val,
|
||||
ChunkedArray::neq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Operation unavailable",
|
||||
"unable to compare this value to the series",
|
||||
&right.tag.span,
|
||||
"Only primary values are allowed",
|
||||
&right.tag.span,
|
||||
Operator::NotEqual => {
|
||||
match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compare_series_i64(
|
||||
&lhs,
|
||||
val,
|
||||
ChunkedArray::neq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compare_series_i64(
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
ChunkedArray::neq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(
|
||||
compare_series_decimal(&lhs, val, ChunkedArray::neq, &left.tag.span),
|
||||
),
|
||||
)),
|
||||
},
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Operation unavailable",
|
||||
"unable to compare this value to the series",
|
||||
&right.tag.span,
|
||||
"Only primary values are allowed",
|
||||
&right.tag.span,
|
||||
),
|
||||
)),
|
||||
}
|
||||
}
|
||||
Operator::LessThan => {
|
||||
match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
ChunkedArray::lt,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
ChunkedArray::lt,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(
|
||||
compare_series_decimal(lhs.as_ref(), val, ChunkedArray::lt, &left.tag.span),
|
||||
compare_series_decimal(&lhs, val, ChunkedArray::lt, &left.tag.span),
|
||||
),
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
@ -435,53 +507,52 @@ pub fn compute_series_single_value(
|
||||
)),
|
||||
}
|
||||
}
|
||||
Operator::LessThanOrEqual => match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
val,
|
||||
ChunkedArray::lt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
ChunkedArray::lt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(compare_series_decimal(
|
||||
lhs.as_ref(),
|
||||
val,
|
||||
ChunkedArray::lt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Operation unavailable",
|
||||
"unable to compare this value to the series",
|
||||
&right.tag.span,
|
||||
"Only primary values are allowed",
|
||||
&right.tag.span,
|
||||
Operator::LessThanOrEqual => {
|
||||
match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compare_series_i64(
|
||||
&lhs,
|
||||
val,
|
||||
ChunkedArray::lt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compare_series_i64(
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
ChunkedArray::lt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(
|
||||
compare_series_decimal(&lhs, val, ChunkedArray::lt_eq, &left.tag.span),
|
||||
),
|
||||
)),
|
||||
},
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Operation unavailable",
|
||||
"unable to compare this value to the series",
|
||||
&right.tag.span,
|
||||
"Only primary values are allowed",
|
||||
&right.tag.span,
|
||||
),
|
||||
)),
|
||||
}
|
||||
}
|
||||
Operator::GreaterThan => {
|
||||
match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
val,
|
||||
ChunkedArray::gt,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
ChunkedArray::gt,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(
|
||||
compare_series_decimal(lhs.as_ref(), val, ChunkedArray::gt, &left.tag.span),
|
||||
compare_series_decimal(&lhs, val, ChunkedArray::gt, &left.tag.span),
|
||||
),
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
@ -494,39 +565,38 @@ pub fn compute_series_single_value(
|
||||
)),
|
||||
}
|
||||
}
|
||||
Operator::GreaterThanOrEqual => match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
val,
|
||||
ChunkedArray::gt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compare_series_i64(
|
||||
lhs.as_ref(),
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
ChunkedArray::gt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(compare_series_decimal(
|
||||
lhs.as_ref(),
|
||||
val,
|
||||
ChunkedArray::gt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Operation unavailable",
|
||||
"unable to compare this value to the series",
|
||||
&right.tag.span,
|
||||
"Only primary values are allowed",
|
||||
&right.tag.span,
|
||||
Operator::GreaterThanOrEqual => {
|
||||
match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::Int(val)) => Ok(compare_series_i64(
|
||||
&lhs,
|
||||
val,
|
||||
ChunkedArray::gt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::BigInt(val)) => Ok(compare_series_i64(
|
||||
&lhs,
|
||||
&val.to_i64()
|
||||
.expect("Internal error: protocol did not use compatible decimal"),
|
||||
ChunkedArray::gt_eq,
|
||||
&left.tag.span,
|
||||
)),
|
||||
UntaggedValue::Primitive(Primitive::Decimal(val)) => Ok(
|
||||
compare_series_decimal(&lhs, val, ChunkedArray::gt_eq, &left.tag.span),
|
||||
),
|
||||
)),
|
||||
},
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Operation unavailable",
|
||||
"unable to compare this value to the series",
|
||||
&right.tag.span,
|
||||
"Only primary values are allowed",
|
||||
&right.tag.span,
|
||||
),
|
||||
)),
|
||||
}
|
||||
}
|
||||
Operator::Contains => match &right.value {
|
||||
UntaggedValue::Primitive(Primitive::String(val)) => {
|
||||
Ok(contains_series_pat(lhs.as_ref(), val, &left.tag.span))
|
||||
Ok(contains_series_pat(&lhs, val, &left.tag.span))
|
||||
}
|
||||
_ => Ok(UntaggedValue::Error(
|
||||
ShellError::labeled_error_with_secondary(
|
||||
@ -597,7 +667,7 @@ where
|
||||
Ok(casted) => {
|
||||
let res = f(casted.clone(), val);
|
||||
let res = res.into_series();
|
||||
NuSeries::series_to_untagged(res)
|
||||
NuDataFrame::series_to_untagged(res, span)
|
||||
}
|
||||
Err(e) => UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Casting error",
|
||||
@ -667,7 +737,7 @@ where
|
||||
Ok(casted) => {
|
||||
let res = f(casted.clone(), val);
|
||||
let res = res.into_series();
|
||||
NuSeries::series_to_untagged(res)
|
||||
NuDataFrame::series_to_untagged(res, span)
|
||||
}
|
||||
Err(e) => UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Casting error",
|
||||
@ -725,7 +795,7 @@ where
|
||||
Ok(casted) => {
|
||||
let res = f(casted, val);
|
||||
let res = res.into_series();
|
||||
NuSeries::series_to_untagged(res)
|
||||
NuDataFrame::series_to_untagged(res, span)
|
||||
}
|
||||
Err(e) => UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Casting error",
|
||||
@ -795,7 +865,7 @@ where
|
||||
Ok(casted) => {
|
||||
let res = f(casted, val);
|
||||
let res = res.into_series();
|
||||
NuSeries::series_to_untagged(res)
|
||||
NuDataFrame::series_to_untagged(res, span)
|
||||
}
|
||||
Err(e) => UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Casting error",
|
||||
@ -814,7 +884,7 @@ fn contains_series_pat(series: &Series, pat: &str, span: &Span) -> UntaggedValue
|
||||
match res {
|
||||
Ok(res) => {
|
||||
let res = res.into_series();
|
||||
NuSeries::series_to_untagged(res)
|
||||
NuDataFrame::series_to_untagged(res, span)
|
||||
}
|
||||
Err(e) => UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Search error",
|
||||
|
Reference in New Issue
Block a user