Skip to content

Commit

Permalink
feat(query): support desc table with decimal type and support order bโ€ฆ
Browse files Browse the repository at this point in the history
โ€ฆy decmail type col
  • Loading branch information
TCeason committed Feb 21, 2023
1 parent 1b0bdd0 commit e790943
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/query/expression/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,12 @@ impl From<&DataType> for ArrowDataType {
Box::new(ArrowDataType::LargeBinary),
None,
),
DataType::Decimal(DecimalDataType::Decimal128(s)) => {
ArrowDataType::Decimal(s.precision as usize, s.scale as usize)
}
DataType::Decimal(DecimalDataType::Decimal256(s)) => {
ArrowDataType::Decimal256(s.precision as usize, s.scale as usize)
}

_ => unreachable!(),
}
Expand Down
8 changes: 8 additions & 0 deletions src/query/expression/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ use crate::deserializations::TimestampDeserializer;
use crate::deserializations::TupleDeserializer;
use crate::deserializations::VariantDeserializer;
use crate::property::Domain;
use crate::types::decimal::DecimalScalar;
use crate::values::Column;
use crate::values::Scalar;
use crate::ColumnBuilder;
Expand Down Expand Up @@ -288,6 +289,13 @@ impl DataType {
Scalar::Tuple(tys.iter().map(|ty| ty.default_value()).collect())
}
DataType::Variant => Scalar::Variant(vec![]),
DataType::Decimal(DecimalDataType::Decimal128(s)) => {
Scalar::Decimal(DecimalScalar::Decimal128(0.into(), *s))
}
DataType::Decimal(DecimalDataType::Decimal256(s)) => {
Scalar::Decimal(DecimalScalar::Decimal256(0.into(), *s))
}

_ => unimplemented!(),
}
}
Expand Down
61 changes: 61 additions & 0 deletions src/query/expression/src/types/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ use serde::Deserialize;
use serde::Serialize;

use super::SimpleDomain;
use crate::types::ArgType;
use crate::types::DataType;
use crate::types::GenericMap;
use crate::types::ValueType;
use crate::utils::arrow::buffer_into_mut;
use crate::Column;
Expand All @@ -38,6 +41,9 @@ use crate::ScalarRef;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DecimalType<T: Decimal>(PhantomData<T>);

pub type Decimal128Type = DecimalType<i128>;
pub type Decimal256Type = DecimalType<i256>;

impl<Num: Decimal> ValueType for DecimalType<Num> {
type Scalar = Num;
type ScalarRef<'a> = Num;
Expand Down Expand Up @@ -146,6 +152,38 @@ impl<Num: Decimal> ValueType for DecimalType<Num> {
}
}

impl<Num: Decimal> ArgType for DecimalType<Num> {
fn data_type() -> DataType {
Num::data_type()
}

fn full_domain() -> Self::Domain {
SimpleDomain {
min: Num::MIN,
max: Num::MAX,
}
}

fn create_builder(capacity: usize, _generics: &GenericMap) -> Self::ColumnBuilder {
Vec::with_capacity(capacity)
}

fn column_from_vec(vec: Vec<Self::Scalar>, _generics: &GenericMap) -> Self::Column {
vec.into()
}

fn column_from_iter(iter: impl Iterator<Item = Self::Scalar>, _: &GenericMap) -> Self::Column {
iter.collect()
}

fn column_from_ref_iter<'a>(
iter: impl Iterator<Item = Self::ScalarRef<'a>>,
_: &GenericMap,
) -> Self::Column {
iter.collect()
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, EnumAsInner)]
pub enum DecimalDataType {
Decimal128(DecimalSize),
Expand Down Expand Up @@ -227,6 +265,10 @@ pub trait Decimal:
fn to_column(value: Vec<Self>, size: DecimalSize) -> DecimalColumn {
Self::to_column_from_buffer(value.into(), size)
}

fn data_type() -> DataType;
const MIN: Self;
const MAX: Self;
}

impl Decimal for i128 {
Expand Down Expand Up @@ -326,6 +368,16 @@ impl Decimal for i128 {
fn to_column_from_buffer(value: Buffer<Self>, size: DecimalSize) -> DecimalColumn {
DecimalColumn::Decimal128(value, size)
}

fn data_type() -> DataType {
DataType::Decimal(DecimalDataType::Decimal128(DecimalSize {
precision: MAX_DECIMAL128_PRECISION,
scale: 0,
}))
}

const MIN: i128 = i128::MIN;
const MAX: i128 = i128::MAX;
}

impl Decimal for i256 {
Expand Down Expand Up @@ -424,6 +476,15 @@ impl Decimal for i256 {
fn to_column_from_buffer(value: Buffer<Self>, size: DecimalSize) -> DecimalColumn {
DecimalColumn::Decimal256(value, size)
}

fn data_type() -> DataType {
DataType::Decimal(DecimalDataType::Decimal128(DecimalSize {
precision: MAX_DECIMAL256_PRECISION,
scale: 0,
}))
}
const MIN: i256 = i256::MIN;
const MAX: i256 = i256::MAX;
}

pub static MAX_DECIMAL128_PRECISION: u8 = 38;
Expand Down
21 changes: 21 additions & 0 deletions src/query/expression/src/utils/column_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

use std::iter::Iterator;

use ethnum::i256;

use crate::types::decimal::*;
use crate::types::nullable::NullableColumn;
use crate::types::number::*;
use crate::types::*;
Expand Down Expand Up @@ -129,6 +132,24 @@ impl<D: AsRef<[f64]>> FromData<D, [Vec<f64>; 0]> for Float64Type {
}
}

impl<D: AsRef<[i128]>> FromData<D, [Vec<i128>; 0]> for Decimal128Type {
fn from_data(d: D) -> Column {
Decimal128Type::upcast_column(Decimal128Type::column_from_iter(
d.as_ref().iter().copied(),
&[],
))
}
}

impl<D: AsRef<[i256]>> FromData<D, [Vec<i256>; 0]> for Decimal256Type {
fn from_data(d: D) -> Column {
Decimal256Type::upcast_column(Decimal256Type::column_from_iter(
d.as_ref().iter().copied(),
&[],
))
}
}

#[cfg(test)]
mod test {

Expand Down
1 change: 1 addition & 0 deletions src/query/expression/src/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ impl PartialOrd for Column {
col1.partial_cmp(col2)
}
(Column::Number(col1), Column::Number(col2)) => col1.partial_cmp(col2),
(Column::Decimal(col1), Column::Decimal(col2)) => col1.partial_cmp(col2),
(Column::Boolean(col1), Column::Boolean(col2)) => col1.iter().partial_cmp(col2.iter()),
(Column::String(col1), Column::String(col2)) => col1.iter().partial_cmp(col2.iter()),
(Column::Timestamp(col1), Column::Timestamp(col2)) => {
Expand Down
82 changes: 82 additions & 0 deletions src/query/expression/tests/it/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::sync::Arc;
use std::vec;

use common_exception::Result;
use common_expression::types::decimal::*;
use common_expression::types::number::*;
use common_expression::types::StringType;
use common_expression::Column;
Expand Down Expand Up @@ -108,6 +109,87 @@ fn test_block_sort() -> Result<()> {
}
}

let decimal_block = new_block(&[
Decimal128Type::from_data(vec![6i128, 4, 3, 2, 1, 1, 7]),
StringType::from_data(vec!["b1", "b2", "b3", "b4", "b5", "b6", "b7"]),
]);

// test cast:
// - sort descriptions
// - limit
// - expected cols
let test_cases: Vec<(Vec<SortColumnDescription>, Option<usize>, Vec<Column>)> = vec![
(
vec![SortColumnDescription {
offset: 0,
asc: true,
nulls_first: false,
}],
None,
vec![
Decimal128Type::from_data(vec![1_i128, 1, 2, 3, 4, 6, 7]),
StringType::from_data(vec!["b5", "b6", "b4", "b3", "b2", "b1", "b7"]),
],
),
(
vec![SortColumnDescription {
offset: 0,
asc: true,
nulls_first: false,
}],
Some(4),
vec![
Decimal128Type::from_data(vec![1_i128, 1, 2, 3]),
StringType::from_data(vec!["b5", "b6", "b4", "b3"]),
],
),
(
vec![SortColumnDescription {
offset: 1,
asc: false,
nulls_first: false,
}],
None,
vec![
Decimal128Type::from_data(vec![7_i128, 1, 1, 2, 3, 4, 6]),
StringType::from_data(vec!["b7", "b6", "b5", "b4", "b3", "b2", "b1"]),
],
),
(
vec![
SortColumnDescription {
offset: 0,
asc: true,
nulls_first: false,
},
SortColumnDescription {
offset: 1,
asc: false,
nulls_first: false,
},
],
None,
vec![
Decimal128Type::from_data(vec![1_i128, 1, 2, 3, 4, 6, 7]),
StringType::from_data(vec!["b6", "b5", "b4", "b3", "b2", "b1", "b7"]),
],
),
];

for (sort_descs, limit, expected) in test_cases {
let res = DataBlock::sort(&decimal_block, &sort_descs, limit)?;

for (entry, expect) in res.columns().iter().zip(expected.iter()) {
assert_eq!(
entry.value.as_column().unwrap(),
expect,
"the column after sort is wrong, expect: {:?}, got: {:?}",
expect,
entry.value
);
}
}

Ok(())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,30 @@ query I
SELECT ANY(CAST(2.34 AS DECIMAL(6, 2)))
----
2.34

statement ok
drop table if exists t

statement ok
drop table if exists t1

statement ok
create table t(c1 decimal(38,2))

statement ok
create table t1(c0 int, c1 decimal(39,2))

statement ok
select * from t order by c1

## https://github.com/jorgecarleitao/parquet2/blob/main/src/schema/types/converted_type.rs#L25
## https://github.com/jorgecarleitao/arrow2/blob/main/src/io/parquet/write/schema.rs#L323
## the parquet2 and arrow2 not impl decimal256
statement error 1002
select * from t1 order by c1

statement ok
drop table if exists t

statement ok
drop table if exists t1

0 comments on commit e790943

Please sign in to comment.