Skip to main content

databend_driver_core/value/
string_decoder.rs

1// Copyright 2021 Datafuse Labs
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 super::{NumberValue, Value, DAYS_FROM_CE, TIMESTAMP_FORMAT, TIMESTAMP_TIMEZONE_FORMAT};
16use crate::_macro_internal::Error;
17use crate::cursor_ext::{
18    collect_binary_number, collect_number, BufferReadStringExt, ReadBytesExt, ReadCheckPointExt,
19    ReadNumberExt,
20};
21use crate::error::{ConvertError, Result};
22use crate::value::base::GeoValue;
23use chrono::{Datelike, NaiveDate};
24use databend_client::schema::{DataType, DecimalDataType, DecimalSize, NumberDataType};
25use databend_client::ResultFormatSettings;
26use ethnum::i256;
27use hex;
28use jiff::{civil::DateTime as JiffDateTime, tz::TimeZone, Zoned};
29use serde::Deserialize;
30use serde_json::{value::RawValue, Deserializer};
31use std::io::{BufRead, Cursor};
32use std::str::FromStr;
33
34const NULL_VALUE: &str = "NULL";
35const TRUE_VALUE: &str = "1";
36const FALSE_VALUE: &str = "0";
37
38impl TryFrom<(&DataType, Option<String>, &ResultFormatSettings)> for Value {
39    type Error = Error;
40
41    fn try_from(
42        (t, v, settings): (&DataType, Option<String>, &ResultFormatSettings),
43    ) -> Result<Self> {
44        match v {
45            Some(v) => Self::try_from((t, v, settings)),
46            None => match t {
47                DataType::Null => Ok(Self::Null),
48                DataType::Nullable(_) => Ok(Self::Null),
49                _ => Err(Error::InvalidResponse(
50                    "NULL value for non-nullable field".to_string(),
51                )),
52            },
53        }
54    }
55}
56
57impl TryFrom<(&DataType, String, &ResultFormatSettings)> for Value {
58    type Error = Error;
59
60    fn try_from((t, v, settings): (&DataType, String, &ResultFormatSettings)) -> Result<Self> {
61        match t {
62            DataType::Null => Ok(Self::Null),
63            DataType::EmptyArray => Ok(Self::EmptyArray),
64            DataType::EmptyMap => Ok(Self::EmptyMap),
65            DataType::Boolean => Ok(Self::Boolean(v == "1")),
66            DataType::Binary => Ok(Self::Binary(hex::decode(v)?)),
67            DataType::String => Ok(Self::String(v)),
68            DataType::Number(NumberDataType::Int8) => {
69                Ok(Self::Number(NumberValue::Int8(v.parse()?)))
70            }
71            DataType::Number(NumberDataType::Int16) => {
72                Ok(Self::Number(NumberValue::Int16(v.parse()?)))
73            }
74            DataType::Number(NumberDataType::Int32) => {
75                Ok(Self::Number(NumberValue::Int32(v.parse()?)))
76            }
77            DataType::Number(NumberDataType::Int64) => {
78                Ok(Self::Number(NumberValue::Int64(v.parse()?)))
79            }
80            DataType::Number(NumberDataType::UInt8) => {
81                Ok(Self::Number(NumberValue::UInt8(v.parse()?)))
82            }
83            DataType::Number(NumberDataType::UInt16) => {
84                Ok(Self::Number(NumberValue::UInt16(v.parse()?)))
85            }
86            DataType::Number(NumberDataType::UInt32) => {
87                Ok(Self::Number(NumberValue::UInt32(v.parse()?)))
88            }
89            DataType::Number(NumberDataType::UInt64) => {
90                Ok(Self::Number(NumberValue::UInt64(v.parse()?)))
91            }
92            DataType::Number(NumberDataType::Float32) => {
93                Ok(Self::Number(NumberValue::Float32(v.parse()?)))
94            }
95            DataType::Number(NumberDataType::Float64) => {
96                Ok(Self::Number(NumberValue::Float64(v.parse()?)))
97            }
98            DataType::Decimal(DecimalDataType::Decimal64(size)) => {
99                let d = parse_decimal(v.as_str(), *size)?;
100                Ok(Self::Number(d))
101            }
102            DataType::Decimal(DecimalDataType::Decimal128(size)) => {
103                let d = parse_decimal(v.as_str(), *size)?;
104                Ok(Self::Number(d))
105            }
106            DataType::Decimal(DecimalDataType::Decimal256(size)) => {
107                let d = parse_decimal(v.as_str(), *size)?;
108                Ok(Self::Number(d))
109            }
110            DataType::Timestamp => parse_timestamp(v.as_str(), &settings.timezone),
111            DataType::TimestampTz => {
112                let t = Zoned::strptime(TIMESTAMP_TIMEZONE_FORMAT, v.as_str())?;
113                Ok(Self::TimestampTz(t))
114            }
115            DataType::Date => Ok(Self::Date(
116                NaiveDate::parse_from_str(v.as_str(), "%Y-%m-%d")?.num_days_from_ce()
117                    - DAYS_FROM_CE,
118            )),
119            DataType::Bitmap => Ok(Self::Bitmap(v)),
120            DataType::Variant => Ok(Self::Variant(v)),
121            DataType::Geometry => Ok(Self::Geometry(GeoValue::from_string(
122                v,
123                settings.geometry_output_format,
124            )?)),
125            DataType::Geography => Ok(Self::Geography(GeoValue::from_string(
126                v,
127                settings.geometry_output_format,
128            )?)),
129            DataType::Interval => Ok(Self::Interval(v)),
130            DataType::Array(_) | DataType::Map(_) | DataType::Tuple(_) | DataType::Vector(_) => {
131                let mut reader = Cursor::new(v.as_str());
132                let decoder = ValueDecoder {
133                    settings: settings.clone(),
134                };
135                decoder.read_field(t, &mut reader)
136            }
137            DataType::Nullable(inner) => match inner.as_ref() {
138                DataType::String => Ok(Self::String(v.to_string())),
139                _ => {
140                    // not string type, try to check if it is NULL
141                    // for compatible with old version server
142                    if v == NULL_VALUE {
143                        Ok(Self::Null)
144                    } else {
145                        Self::try_from((inner.as_ref(), v, settings))
146                    }
147                }
148            },
149        }
150    }
151}
152
153struct ValueDecoder {
154    pub settings: ResultFormatSettings,
155}
156
157impl ValueDecoder {
158    pub(super) fn read_field<R: AsRef<[u8]>>(
159        &self,
160        ty: &DataType,
161        reader: &mut Cursor<R>,
162    ) -> Result<Value> {
163        match ty {
164            DataType::Null => self.read_null(reader),
165            DataType::EmptyArray => self.read_empty_array(reader),
166            DataType::EmptyMap => self.read_empty_map(reader),
167            DataType::Boolean => self.read_bool(reader),
168            DataType::Number(NumberDataType::Int8) => self.read_int8(reader),
169            DataType::Number(NumberDataType::Int16) => self.read_int16(reader),
170            DataType::Number(NumberDataType::Int32) => self.read_int32(reader),
171            DataType::Number(NumberDataType::Int64) => self.read_int64(reader),
172            DataType::Number(NumberDataType::UInt8) => self.read_uint8(reader),
173            DataType::Number(NumberDataType::UInt16) => self.read_uint16(reader),
174            DataType::Number(NumberDataType::UInt32) => self.read_uint32(reader),
175            DataType::Number(NumberDataType::UInt64) => self.read_uint64(reader),
176            DataType::Number(NumberDataType::Float32) => self.read_float32(reader),
177            DataType::Number(NumberDataType::Float64) => self.read_float64(reader),
178            DataType::Decimal(DecimalDataType::Decimal64(size)) => self.read_decimal(size, reader),
179            DataType::Decimal(DecimalDataType::Decimal128(size)) => self.read_decimal(size, reader),
180            DataType::Decimal(DecimalDataType::Decimal256(size)) => self.read_decimal(size, reader),
181            DataType::String => self.read_string(reader),
182            DataType::Binary => self.read_binary(reader),
183            DataType::Timestamp => self.read_timestamp(reader),
184            DataType::TimestampTz => self.read_timestamp_tz(reader),
185            DataType::Date => self.read_date(reader),
186            DataType::Bitmap => self.read_bitmap(reader),
187            DataType::Variant => self.read_variant(reader),
188            DataType::Geometry => self.read_geometry(reader),
189            DataType::Interval => self.read_interval(reader),
190            DataType::Geography => self.read_geography(reader),
191            DataType::Array(inner_ty) => self.read_array(inner_ty.as_ref(), reader),
192            DataType::Map(inner_ty) => self.read_map(inner_ty.as_ref(), reader),
193            DataType::Tuple(inner_tys) => self.read_tuple(inner_tys.as_ref(), reader),
194            DataType::Vector(dimension) => self.read_vector(*dimension as usize, reader),
195            DataType::Nullable(inner_ty) => self.read_nullable(inner_ty.as_ref(), reader),
196        }
197    }
198
199    fn match_bytes<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>, bs: &[u8]) -> bool {
200        let pos = reader.checkpoint();
201        if reader.ignore_bytes(bs) {
202            true
203        } else {
204            reader.rollback(pos);
205            false
206        }
207    }
208
209    fn read_null<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
210        if self.match_bytes(reader, NULL_VALUE.as_bytes()) {
211            Ok(Value::Null)
212        } else {
213            let buf = reader.fill_buf()?;
214            Err(ConvertError::new("null", String::from_utf8_lossy(buf).to_string()).into())
215        }
216    }
217
218    fn read_bool<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
219        if self.match_bytes(reader, TRUE_VALUE.as_bytes()) {
220            Ok(Value::Boolean(true))
221        } else if self.match_bytes(reader, FALSE_VALUE.as_bytes()) {
222            Ok(Value::Boolean(false))
223        } else {
224            let buf = reader.fill_buf()?;
225            Err(ConvertError::new("boolean", String::from_utf8_lossy(buf).to_string()).into())
226        }
227    }
228
229    fn read_int8<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
230        let v: i8 = reader.read_int_text()?;
231        Ok(Value::Number(NumberValue::Int8(v)))
232    }
233
234    fn read_int16<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
235        let v: i16 = reader.read_int_text()?;
236        Ok(Value::Number(NumberValue::Int16(v)))
237    }
238
239    fn read_int32<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
240        let v: i32 = reader.read_int_text()?;
241        Ok(Value::Number(NumberValue::Int32(v)))
242    }
243
244    fn read_int64<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
245        let v: i64 = reader.read_int_text()?;
246        Ok(Value::Number(NumberValue::Int64(v)))
247    }
248
249    fn read_uint8<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
250        let v: u8 = reader.read_int_text()?;
251        Ok(Value::Number(NumberValue::UInt8(v)))
252    }
253
254    fn read_uint16<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
255        let v: u16 = reader.read_int_text()?;
256        Ok(Value::Number(NumberValue::UInt16(v)))
257    }
258
259    fn read_uint32<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
260        let v: u32 = reader.read_int_text()?;
261        Ok(Value::Number(NumberValue::UInt32(v)))
262    }
263
264    fn read_uint64<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
265        let v: u64 = reader.read_int_text()?;
266        Ok(Value::Number(NumberValue::UInt64(v)))
267    }
268
269    fn read_float32<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
270        let v: f32 = reader.read_float_text()?;
271        Ok(Value::Number(NumberValue::Float32(v)))
272    }
273
274    fn read_float64<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
275        let v: f64 = reader.read_float_text()?;
276        Ok(Value::Number(NumberValue::Float64(v)))
277    }
278
279    fn read_decimal<R: AsRef<[u8]>>(
280        &self,
281        size: &DecimalSize,
282        reader: &mut Cursor<R>,
283    ) -> Result<Value> {
284        let buf = reader.fill_buf()?;
285        // parser decimal need fractional part.
286        // 10.00 and 10 is different value.
287        let (n_in, _) = collect_number(buf);
288        let v = unsafe { std::str::from_utf8_unchecked(&buf[..n_in]) };
289        let d = parse_decimal(v, *size)?;
290        reader.consume(n_in);
291        Ok(Value::Number(d))
292    }
293
294    fn read_string<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
295        let mut buf = Vec::new();
296        if reader.read_quoted_text(&mut buf, b'"').is_err() {
297            reader.read_quoted_text(&mut buf, b'\'')?;
298        }
299        Ok(Value::String(unsafe { String::from_utf8_unchecked(buf) }))
300    }
301
302    fn read_binary<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
303        let buf = reader.fill_buf()?;
304        let n = collect_binary_number(buf);
305        let v = buf[..n].to_vec();
306        reader.consume(n);
307        Ok(Value::Binary(hex::decode(v)?))
308    }
309
310    fn read_date<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
311        let mut buf = Vec::new();
312        if reader.read_quoted_text(&mut buf, b'"').is_err() {
313            reader.read_quoted_text(&mut buf, b'\'')?;
314        }
315        let v = unsafe { std::str::from_utf8_unchecked(&buf) };
316        let days = NaiveDate::parse_from_str(v, "%Y-%m-%d")?.num_days_from_ce() - DAYS_FROM_CE;
317        Ok(Value::Date(days))
318    }
319
320    fn read_timestamp<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
321        let mut buf = Vec::new();
322        if reader.read_quoted_text(&mut buf, b'"').is_err() {
323            reader.read_quoted_text(&mut buf, b'\'')?;
324        }
325        let v = unsafe { std::str::from_utf8_unchecked(&buf) };
326        parse_timestamp(v, &self.settings.timezone)
327    }
328
329    fn read_timestamp_tz<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
330        let mut buf = Vec::new();
331        if reader.read_quoted_text(&mut buf, b'"').is_err() {
332            reader.read_quoted_text(&mut buf, b'\'')?;
333        }
334        let v = unsafe { std::str::from_utf8_unchecked(&buf) };
335        let t = Zoned::strptime(TIMESTAMP_TIMEZONE_FORMAT, v)?;
336        Ok(Value::TimestampTz(t))
337    }
338
339    fn read_interval<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
340        let mut buf = Vec::new();
341        if reader.read_quoted_text(&mut buf, b'"').is_err() {
342            reader.read_quoted_text(&mut buf, b'\'')?;
343        }
344        Ok(Value::Interval(unsafe { String::from_utf8_unchecked(buf) }))
345    }
346
347    fn read_bitmap<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
348        let mut buf = Vec::new();
349        if reader.read_quoted_text(&mut buf, b'"').is_err() {
350            reader.read_quoted_text(&mut buf, b'\'')?;
351        }
352        Ok(Value::Bitmap(unsafe { String::from_utf8_unchecked(buf) }))
353    }
354
355    fn read_variant<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
356        if let Ok(val) = self.read_json(reader) {
357            Ok(Value::Variant(val))
358        } else {
359            let mut buf = Vec::new();
360            reader.read_quoted_text(&mut buf, b'\'')?;
361            Ok(Value::Variant(unsafe { String::from_utf8_unchecked(buf) }))
362        }
363    }
364
365    fn read_geometry<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
366        Ok(Value::Geometry(self.read_geo(reader)?))
367    }
368
369    fn read_geo<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<GeoValue> {
370        let mut buf = Vec::new();
371        if reader.read_quoted_text(&mut buf, b'"').is_ok()
372            || reader.read_quoted_text(&mut buf, b'\'').is_ok()
373        {
374            let s = unsafe { String::from_utf8_unchecked(buf) };
375            GeoValue::from_string(s, self.settings.geometry_output_format)
376        } else {
377            let val = self.read_json(reader)?;
378            Ok(GeoValue::String(val))
379        }
380    }
381    fn read_geography<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
382        Ok(Value::Geography(self.read_geo(reader)?))
383    }
384
385    fn read_nullable<R: AsRef<[u8]>>(
386        &self,
387        ty: &DataType,
388        reader: &mut Cursor<R>,
389    ) -> Result<Value> {
390        match self.read_null(reader) {
391            Ok(val) => Ok(val),
392            Err(_) => self.read_field(ty, reader),
393        }
394    }
395
396    fn read_empty_array<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
397        reader.must_ignore_byte(b'[')?;
398        reader.must_ignore_byte(b']')?;
399        Ok(Value::EmptyArray)
400    }
401
402    fn read_empty_map<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
403        reader.must_ignore_byte(b'{')?;
404        reader.must_ignore_byte(b'}')?;
405        Ok(Value::EmptyArray)
406    }
407
408    fn read_array<R: AsRef<[u8]>>(&self, ty: &DataType, reader: &mut Cursor<R>) -> Result<Value> {
409        let mut vals = Vec::new();
410        reader.must_ignore_byte(b'[')?;
411        for idx in 0.. {
412            let _ = reader.ignore_white_spaces();
413            if reader.ignore_byte(b']') {
414                break;
415            }
416            if idx != 0 {
417                reader.must_ignore_byte(b',')?;
418            }
419            let _ = reader.ignore_white_spaces();
420            let val = self.read_field(ty, reader)?;
421            vals.push(val);
422        }
423        Ok(Value::Array(vals))
424    }
425
426    fn read_vector<R: AsRef<[u8]>>(
427        &self,
428        dimension: usize,
429        reader: &mut Cursor<R>,
430    ) -> Result<Value> {
431        let mut vals = Vec::with_capacity(dimension);
432        reader.must_ignore_byte(b'[')?;
433        for idx in 0..dimension {
434            let _ = reader.ignore_white_spaces();
435            if idx > 0 {
436                reader.must_ignore_byte(b',')?;
437            }
438            let _ = reader.ignore_white_spaces();
439            let val: f32 = reader.read_float_text()?;
440            vals.push(val);
441        }
442        reader.must_ignore_byte(b']')?;
443        Ok(Value::Vector(vals))
444    }
445
446    fn read_map<R: AsRef<[u8]>>(&self, ty: &DataType, reader: &mut Cursor<R>) -> Result<Value> {
447        const KEY: usize = 0;
448        const VALUE: usize = 1;
449        let mut kvs = Vec::new();
450        reader.must_ignore_byte(b'{')?;
451        match ty {
452            DataType::Tuple(inner_tys) => {
453                for idx in 0.. {
454                    let _ = reader.ignore_white_spaces();
455                    if reader.ignore_byte(b'}') {
456                        break;
457                    }
458                    if idx != 0 {
459                        reader.must_ignore_byte(b',')?;
460                    }
461                    let _ = reader.ignore_white_spaces();
462                    let key = self.read_field(&inner_tys[KEY], reader)?;
463                    let _ = reader.ignore_white_spaces();
464                    reader.must_ignore_byte(b':')?;
465                    let _ = reader.ignore_white_spaces();
466                    let val = self.read_field(&inner_tys[VALUE], reader)?;
467                    kvs.push((key, val));
468                }
469                Ok(Value::Map(kvs))
470            }
471            _ => unreachable!(),
472        }
473    }
474
475    fn read_tuple<R: AsRef<[u8]>>(
476        &self,
477        tys: &[DataType],
478        reader: &mut Cursor<R>,
479    ) -> Result<Value> {
480        let mut vals = Vec::new();
481        reader.must_ignore_byte(b'(')?;
482        for (idx, ty) in tys.iter().enumerate() {
483            let _ = reader.ignore_white_spaces();
484            if idx != 0 {
485                reader.must_ignore_byte(b',')?;
486            }
487            let _ = reader.ignore_white_spaces();
488            let val = self.read_field(ty, reader)?;
489            vals.push(val);
490        }
491        reader.must_ignore_byte(b')')?;
492        Ok(Value::Tuple(vals))
493    }
494
495    fn read_json<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<String> {
496        let start = reader.position() as usize;
497        let data = reader.get_ref().as_ref();
498        let mut deserializer = Deserializer::from_slice(&data[start..]);
499        let raw: Box<RawValue> = Box::<RawValue>::deserialize(&mut deserializer)?;
500        reader.set_position((start + raw.get().len()) as u64);
501        Ok(raw.to_string())
502    }
503}
504
505fn parse_timestamp(ts_string: &str, tz: &TimeZone) -> Result<Value> {
506    let local = JiffDateTime::strptime(TIMESTAMP_FORMAT, ts_string)?;
507    let dt_with_tz = local.to_zoned(tz.clone()).map_err(|e| {
508        Error::Parsing(format!(
509            "time {ts_string} not exists in timezone {tz:?}: {e}"
510        ))
511    })?;
512    Ok(Value::Timestamp(dt_with_tz))
513}
514
515fn parse_decimal(text: &str, size: DecimalSize) -> Result<NumberValue> {
516    let mut start = 0;
517    let bytes = text.as_bytes();
518    let mut is_negative = false;
519
520    // Check if the number is negative
521    if bytes[start] == b'-' {
522        is_negative = true;
523        start += 1;
524    }
525
526    while start < text.len() && bytes[start] == b'0' {
527        start += 1
528    }
529    let text = &text[start..];
530    let point_pos = text.find('.');
531    let e_pos = text.find(|c| ['E', 'e'].contains(&c));
532    let (i_part, f_part, e_part) = match (point_pos, e_pos) {
533        (Some(p1), Some(p2)) => (&text[..p1], &text[(p1 + 1)..p2], Some(&text[(p2 + 1)..])),
534        (Some(p), None) => (&text[..p], &text[(p + 1)..], None),
535        (None, Some(p)) => (&text[..p], "", Some(&text[(p + 1)..])),
536        (None, None) => (text, "", None),
537    };
538    let exp = match e_part {
539        Some(s) => s.parse::<i32>()?,
540        None => 0,
541    };
542    if i_part.len() as i32 + exp > 76 {
543        Err(ConvertError::new("decimal", format!("{text:?}")).into())
544    } else {
545        let mut digits = Vec::with_capacity(76);
546        digits.extend_from_slice(i_part.as_bytes());
547        digits.extend_from_slice(f_part.as_bytes());
548        if digits.is_empty() {
549            digits.push(b'0')
550        }
551        let scale = f_part.len() as i32 - exp;
552        if scale < 0 {
553            // e.g 123.1e3
554            for _ in 0..(-scale) {
555                digits.push(b'0')
556            }
557        };
558
559        let precision = std::cmp::min(digits.len(), 76);
560        let digits = unsafe { std::str::from_utf8_unchecked(&digits[..precision]) };
561
562        let result = if size.precision > 38 {
563            NumberValue::Decimal256(i256::from_str(digits).unwrap(), size)
564        } else if size.precision > 19 {
565            NumberValue::Decimal128(digits.parse::<i128>()?, size)
566        } else {
567            NumberValue::Decimal64(digits.parse::<i64>()?, size)
568        };
569
570        // If the number was negative, negate the result
571        if is_negative {
572            match result {
573                NumberValue::Decimal256(val, size) => Ok(NumberValue::Decimal256(-val, size)),
574                NumberValue::Decimal128(val, size) => Ok(NumberValue::Decimal128(-val, size)),
575                NumberValue::Decimal64(val, size) => Ok(NumberValue::Decimal64(-val, size)),
576                _ => Ok(result),
577            }
578        } else {
579            Ok(result)
580        }
581    }
582}