datatypes/types/
decimal_type.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use arrow_schema::DataType as ArrowDataType;
16use common_decimal::decimal128::DECIMAL128_MAX_PRECISION;
17use common_decimal::Decimal128;
18use serde::{Deserialize, Serialize};
19
20use crate::prelude::{DataType, ScalarVectorBuilder};
21use crate::type_id::LogicalTypeId;
22use crate::value::Value;
23use crate::vectors::{Decimal128VectorBuilder, MutableVector};
24
25/// Decimal type with precision and scale information.
26#[derive(
27    Debug, Default, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
28)]
29pub struct Decimal128Type {
30    precision: u8,
31    scale: i8,
32}
33
34impl Decimal128Type {
35    pub fn new(precision: u8, scale: i8) -> Self {
36        // assert precision and scale is valid
37        assert!(
38            precision > 0 && precision <= DECIMAL128_MAX_PRECISION,
39            "precision should be in [1, {}]",
40            DECIMAL128_MAX_PRECISION
41        );
42        assert!(
43            scale >= 0 && scale <= precision as i8,
44            "scale should be in [0, precision]"
45        );
46        Decimal128Type { precision, scale }
47    }
48
49    pub fn precision(&self) -> u8 {
50        self.precision
51    }
52
53    pub fn scale(&self) -> i8 {
54        self.scale
55    }
56}
57
58impl DataType for Decimal128Type {
59    fn name(&self) -> String {
60        format!("Decimal({}, {})", self.precision, self.scale)
61    }
62
63    fn logical_type_id(&self) -> LogicalTypeId {
64        LogicalTypeId::Decimal128
65    }
66
67    fn default_value(&self) -> Value {
68        Value::Decimal128(Decimal128::default())
69    }
70
71    fn as_arrow_type(&self) -> ArrowDataType {
72        ArrowDataType::Decimal128(self.precision, self.scale)
73    }
74
75    fn create_mutable_vector(&self, capacity: usize) -> Box<dyn MutableVector> {
76        Box::new(
77            Decimal128VectorBuilder::with_capacity(capacity)
78                .with_precision_and_scale(self.precision, self.scale)
79                // safe to unwrap because we have validated the precision and scale in new()
80                .unwrap(),
81        )
82    }
83
84    fn try_cast(&self, val: Value) -> Option<Value> {
85        match val {
86            Value::Null => Some(Value::Null),
87            Value::Decimal128(_) => Some(val),
88            _ => None,
89        }
90    }
91}