blob: 368f2c33022e18316457a6f3bd31d626eb746eca [file]
// Copyright 2022 The Blaze Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::sync::Arc;
use arrow::array::*;
use datafusion::{
common::{Result, ScalarValue},
physical_plan::ColumnarValue,
};
/// implements org.apache.spark.sql.catalyst.expressions.UnscaledValue
pub fn spark_unscaled_value(args: &[ColumnarValue]) -> Result<ColumnarValue> {
Ok(match &args[0] {
ColumnarValue::Scalar(scalar) => match scalar {
ScalarValue::Decimal128(Some(v), ..) => {
ColumnarValue::Scalar(ScalarValue::Int64(Some(*v as i64)))
}
_ => ColumnarValue::Scalar(ScalarValue::Int64(None)),
},
ColumnarValue::Array(array) => {
let array = array.as_any().downcast_ref::<Decimal128Array>().unwrap();
let mut output = Int64Builder::new();
for v in array.into_iter() {
output.append_option(v.map(|v| v as i64));
}
ColumnarValue::Array(Arc::new(output.finish()))
}
})
}
#[cfg(test)]
mod test {
use std::{error::Error, sync::Arc};
use arrow::array::{ArrayRef, Decimal128Array, Int64Array};
use datafusion::{common::ScalarValue, logical_expr::ColumnarValue};
use crate::spark_unscaled_value::spark_unscaled_value;
#[test]
fn test_unscaled_value_array() -> Result<(), Box<dyn Error>> {
let result = spark_unscaled_value(&vec![ColumnarValue::Array(Arc::new(
Decimal128Array::from(vec![
Some(1234567890987654321),
Some(9876543210),
Some(135792468109),
None,
Some(67898),
])
.with_precision_and_scale(10, 8)?,
))])?
.into_array(5)?;
let expected = Int64Array::from(vec![
Some(1234567890987654321),
Some(9876543210),
Some(135792468109),
None,
Some(67898),
]);
let expected: ArrayRef = Arc::new(expected);
assert_eq!(&result, &expected);
Ok(())
}
#[test]
fn test_unscaled_value_scalar() -> Result<(), Box<dyn Error>> {
let result = spark_unscaled_value(&vec![ColumnarValue::Scalar(ScalarValue::Decimal128(
Some(123),
3,
2,
))])?
.into_array(1)?;
let expected = Int64Array::from(vec![Some(123)]);
let expected: ArrayRef = Arc::new(expected);
assert_eq!(&result, &expected);
Ok(())
}
}