Skip to content

Commit d2b613f

Browse files
authored
feat(query): Introducing Decimal64 (#18010)
1 parent 33e614a commit d2b613f

File tree

96 files changed

+4526
-1917
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+4526
-1917
lines changed

src/common/io/src/decimal.rs

Lines changed: 73 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -12,65 +12,86 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::fmt::Write;
15+
use std::fmt::Debug;
16+
use std::fmt::Display;
17+
use std::fmt::Formatter;
18+
use std::fmt::Result;
1619

1720
use ethnum::i256;
1821

19-
pub fn display_decimal_128(num: i128, scale: u8) -> String {
20-
let mut buf = String::new();
21-
if scale == 0 {
22-
write!(buf, "{}", num).unwrap();
23-
} else {
24-
let pow_scale = 10_i128.pow(scale as u32);
25-
if num >= 0 {
26-
write!(
27-
buf,
28-
"{}.{:0>width$}",
29-
num / pow_scale,
30-
(num % pow_scale).abs(),
31-
width = scale as usize
32-
)
33-
.unwrap();
34-
} else {
35-
write!(
36-
buf,
37-
"-{}.{:0>width$}",
38-
-num / pow_scale,
39-
(num % pow_scale).abs(),
40-
width = scale as usize
41-
)
42-
.unwrap();
22+
pub fn display_decimal_128(num: i128, scale: u8) -> impl Display + Debug {
23+
struct Decimal {
24+
num: i128,
25+
scale: u8,
26+
}
27+
28+
impl Display for Decimal {
29+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
30+
if self.scale == 0 {
31+
write!(f, "{}", self.num)
32+
} else {
33+
let pow_scale = 10_i128.pow(self.scale as u32);
34+
let sign = if self.num.is_negative() { "-" } else { "" };
35+
let num = self.num.abs();
36+
write!(
37+
f,
38+
"{sign}{}.{:0>width$}",
39+
num / pow_scale,
40+
num % pow_scale,
41+
width = self.scale as usize
42+
)
43+
}
44+
}
45+
}
46+
47+
impl Debug for Decimal {
48+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
49+
f.write_str(&self.to_string())
4350
}
4451
}
45-
buf
52+
53+
Decimal { num, scale }
4654
}
4755

48-
pub fn display_decimal_256(num: i256, scale: u8) -> String {
49-
let mut buf = String::new();
50-
if scale == 0 {
51-
write!(buf, "{}", num).unwrap();
52-
} else {
53-
let pow_scale = i256::from(10).pow(scale as u32);
54-
// -1/10 = 0
55-
if num >= 0 {
56-
write!(
57-
buf,
58-
"{}.{:0>width$}",
59-
num / pow_scale,
60-
(num % pow_scale).abs(),
61-
width = scale as usize
62-
)
63-
.unwrap();
64-
} else {
65-
write!(
66-
buf,
67-
"-{}.{:0>width$}",
68-
-num / pow_scale,
69-
(num % pow_scale).abs(),
70-
width = scale as usize
71-
)
72-
.unwrap();
56+
pub fn display_decimal_256(num: i256, scale: u8) -> impl Display + Debug {
57+
struct Decimal256 {
58+
num: i256,
59+
scale: u8,
60+
}
61+
62+
impl Display for Decimal256 {
63+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
64+
if self.scale == 0 {
65+
write!(f, "{}", self.num)
66+
} else {
67+
let pow_scale = i256::from(10).pow(self.scale as u32);
68+
// -1/10 = 0
69+
if self.num >= 0 {
70+
write!(
71+
f,
72+
"{}.{:0>width$}",
73+
self.num / pow_scale,
74+
(self.num % pow_scale).abs(),
75+
width = self.scale as usize
76+
)
77+
} else {
78+
write!(
79+
f,
80+
"-{}.{:0>width$}",
81+
-self.num / pow_scale,
82+
(self.num % pow_scale).abs(),
83+
width = self.scale as usize
84+
)
85+
}
86+
}
87+
}
88+
}
89+
90+
impl Debug for Decimal256 {
91+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
92+
f.write_str(&self.to_string())
7393
}
7494
}
75-
buf
95+
96+
Decimal256 { num, scale }
7697
}

src/common/native/src/read/array/double.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ use std::io::Cursor;
1717
use std::marker::PhantomData;
1818

1919
use databend_common_column::buffer::Buffer;
20-
use databend_common_expression::types::AccessType;
2120
use databend_common_expression::types::Number;
2221
use databend_common_expression::types::NumberType;
22+
use databend_common_expression::types::ValueType;
2323
use databend_common_expression::Column;
2424
use databend_common_expression::TableDataType;
2525

src/common/native/src/read/array/interval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use std::io::Cursor;
1616

1717
use databend_common_column::buffer::Buffer;
1818
use databend_common_column::types::months_days_micros;
19-
use databend_common_expression::types::AccessType;
2019
use databend_common_expression::types::IntervalType;
20+
use databend_common_expression::types::ValueType;
2121
use databend_common_expression::Column;
2222
use databend_common_expression::TableDataType;
2323

src/meta/proto-conv/src/schema_from_to_protobuf_impl.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,9 @@ impl FromToProto for ex::types::DecimalDataType {
420420

421421
fn to_pb(&self) -> Result<pb::Decimal, Incompatible> {
422422
let x = match self {
423+
ex::types::DecimalDataType::Decimal64(x) => {
424+
pb::decimal::Decimal::Decimal128(ex::types::decimal::DecimalSize::to_pb(x)?)
425+
}
423426
ex::types::DecimalDataType::Decimal128(x) => {
424427
pb::decimal::Decimal::Decimal128(ex::types::decimal::DecimalSize::to_pb(x)?)
425428
}

src/query/ast/src/ast/common.rs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
use std::fmt::Display;
1616
use std::fmt::Formatter;
17-
use std::fmt::Write as _;
1817

1918
use derive_visitor::Drive;
2019
use derive_visitor::DriveMut;
@@ -291,32 +290,39 @@ pub(crate) fn write_space_separated_string_map(
291290
Ok(())
292291
}
293292

294-
pub fn display_decimal_256(num: i256, scale: u8) -> String {
295-
let mut buf = String::new();
296-
if scale == 0 {
297-
write!(buf, "{}", num).unwrap();
298-
} else {
299-
let pow_scale = i256::from(10).pow(scale as u32);
300-
// -1/10 = 0
301-
if num >= 0 {
302-
write!(
303-
buf,
304-
"{}.{:0>width$}",
305-
num / pow_scale,
306-
(num % pow_scale).abs(),
307-
width = scale as usize
308-
)
309-
.unwrap();
310-
} else {
311-
write!(
312-
buf,
313-
"-{}.{:0>width$}",
314-
-num / pow_scale,
315-
(num % pow_scale).abs(),
316-
width = scale as usize
317-
)
318-
.unwrap();
293+
pub(crate) fn display_decimal_256(num: i256, scale: u8) -> impl Display {
294+
struct Decimal256 {
295+
num: i256,
296+
scale: u8,
297+
}
298+
299+
impl Display for Decimal256 {
300+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
301+
if self.scale == 0 {
302+
write!(f, "{}", self.num)
303+
} else {
304+
let pow_scale = i256::from(10).pow(self.scale as u32);
305+
// -1/10 = 0
306+
if self.num >= 0 {
307+
write!(
308+
f,
309+
"{}.{:0>width$}",
310+
self.num / pow_scale,
311+
(self.num % pow_scale).abs(),
312+
width = self.scale as usize
313+
)
314+
} else {
315+
write!(
316+
f,
317+
"-{}.{:0>width$}",
318+
-self.num / pow_scale,
319+
(self.num % pow_scale).abs(),
320+
width = self.scale as usize
321+
)
322+
}
323+
}
319324
}
320325
}
321-
buf
326+
327+
Decimal256 { num, scale }
322328
}

src/query/expression/src/aggregate/group_hash.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ use databend_common_exception::Result;
2121

2222
use crate::types::i256;
2323
use crate::types::number::Number;
24+
use crate::types::AccessType;
2425
use crate::types::AnyType;
2526
use crate::types::BinaryColumn;
2627
use crate::types::BinaryType;
2728
use crate::types::BitmapType;
2829
use crate::types::BooleanType;
2930
use crate::types::DateType;
31+
use crate::types::Decimal64As128Type;
3032
use crate::types::DecimalColumn;
3133
use crate::types::DecimalScalar;
3234
use crate::types::DecimalType;
@@ -100,6 +102,9 @@ impl<const IS_FIRST: bool> ValueVisitor for HashVisitor<'_, IS_FIRST> {
100102

101103
fn visit_any_decimal(&mut self, column: DecimalColumn) -> Result<()> {
102104
match column {
105+
DecimalColumn::Decimal64(buffer, _) => {
106+
self.combine_group_hash_type_column::<Decimal64As128Type>(&buffer);
107+
}
103108
DecimalColumn::Decimal128(buffer, _) => {
104109
self.combine_group_hash_type_column::<DecimalType<i128>>(&buffer);
105110
}
@@ -198,7 +203,7 @@ impl<const IS_FIRST: bool> ValueVisitor for HashVisitor<'_, IS_FIRST> {
198203
impl<const IS_FIRST: bool> HashVisitor<'_, IS_FIRST> {
199204
fn combine_group_hash_type_column<T>(&mut self, col: &T::Column)
200205
where
201-
T: ValueType,
206+
T: AccessType,
202207
for<'a> T::ScalarRef<'a>: AggHash,
203208
{
204209
if IS_FIRST {
@@ -270,6 +275,7 @@ where I: Index
270275
NumberScalar::NUM_TYPE(v) => v.agg_hash(),
271276
}),
272277
Scalar::Decimal(v) => match v {
278+
DecimalScalar::Decimal64(v, _) => (v as i128).agg_hash(),
273279
DecimalScalar::Decimal128(v, _) => v.agg_hash(),
274280
DecimalScalar::Decimal256(v, _) => v.agg_hash(),
275281
},
@@ -539,7 +545,6 @@ mod tests {
539545
use databend_common_column::bitmap::Bitmap;
540546

541547
use super::*;
542-
use crate::types::AccessType;
543548
use crate::types::ArgType;
544549
use crate::types::Int32Type;
545550
use crate::types::NullableColumn;

src/query/expression/src/aggregate/payload_row.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ pub unsafe fn serialize_column_to_rowformat(
9090
}
9191
}),
9292
Column::Decimal(v) => match v {
93+
DecimalColumn::Decimal64(_, _) => unimplemented!(),
9394
DecimalColumn::Decimal128(buffer, size) => {
9495
if size.can_carried_by_128() {
9596
for index in select_vector.iter().take(rows).copied() {
@@ -264,6 +265,7 @@ pub unsafe fn row_match_column(
264265
}
265266
}),
266267
Column::Decimal(v) => match v {
268+
DecimalColumn::Decimal64(_, _) => unreachable!(),
267269
DecimalColumn::Decimal128(_, _) => row_match_column_type::<DecimalType<i128>>(
268270
col,
269271
validity,

src/query/expression/src/converts/arrow/to.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ impl From<&TableField> for Field {
113113
TableDataType::Number(ty) => with_number_type!(|TYPE| match ty {
114114
NumberDataType::TYPE => ArrowDataType::TYPE,
115115
}),
116+
TableDataType::Decimal(DecimalDataType::Decimal64(size)) => {
117+
ArrowDataType::Decimal128(size.precision(), size.scale() as i8)
118+
}
116119
TableDataType::Decimal(DecimalDataType::Decimal128(size)) => {
117120
ArrowDataType::Decimal128(size.precision(), size.scale() as i8)
118121
}
@@ -315,7 +318,7 @@ impl From<&Column> for ArrayData {
315318
Column::Decimal(c) => {
316319
let c = c.clone().strict_decimal_data_type();
317320
let arrow_type = match c {
318-
DecimalColumn::Decimal128(_, size) => {
321+
DecimalColumn::Decimal64(_, size) | DecimalColumn::Decimal128(_, size) => {
319322
ArrowDataType::Decimal128(size.precision(), size.scale() as _)
320323
}
321324
DecimalColumn::Decimal256(_, size) => {

0 commit comments

Comments
 (0)