proof_of_sql/base/database/
literal_value.rs1use crate::base::{
2 database::ColumnType,
3 math::{decimal::Precision, i256::I256},
4 posql_time::{PoSQLTimeUnit, PoSQLTimeZone},
5 scalar::{Scalar, ScalarExt},
6 standard_serializations::limbs::{deserialize_to_limbs, serialize_limbs},
7};
8use alloc::{string::String, vec::Vec};
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
17#[non_exhaustive]
18pub enum LiteralValue {
19 Boolean(bool),
21 Uint8(u8),
23 TinyInt(i8),
25 SmallInt(i16),
27 Int(i32),
29 BigInt(i64),
31 Int128(i128),
33
34 VarChar(String),
38 Decimal75(Precision, i8, I256),
41 TimeStampTZ(PoSQLTimeUnit, PoSQLTimeZone, i64),
44 #[serde(
46 serialize_with = "serialize_limbs",
47 deserialize_with = "deserialize_to_limbs"
48 )]
49 Scalar([u64; 4]),
50 VarBinary(Vec<u8>),
53}
54
55impl LiteralValue {
56 #[must_use]
58 pub fn column_type(&self) -> ColumnType {
59 match self {
60 Self::Boolean(_) => ColumnType::Boolean,
61 Self::Uint8(_) => ColumnType::Uint8,
62 Self::TinyInt(_) => ColumnType::TinyInt,
63 Self::SmallInt(_) => ColumnType::SmallInt,
64 Self::Int(_) => ColumnType::Int,
65 Self::BigInt(_) => ColumnType::BigInt,
66 Self::VarChar(_) => ColumnType::VarChar,
67 Self::VarBinary(_) => ColumnType::VarBinary,
68 Self::Int128(_) => ColumnType::Int128,
69 Self::Scalar(_) => ColumnType::Scalar,
70 Self::Decimal75(precision, scale, _) => ColumnType::Decimal75(*precision, *scale),
71 Self::TimeStampTZ(tu, tz, _) => ColumnType::TimestampTZ(*tu, *tz),
72 }
73 }
74
75 pub(crate) fn to_scalar<S: Scalar>(&self) -> S {
77 match self {
78 Self::Boolean(b) => b.into(),
79 Self::Uint8(i) => i.into(),
80 Self::TinyInt(i) => i.into(),
81 Self::SmallInt(i) => i.into(),
82 Self::Int(i) => i.into(),
83 Self::BigInt(i) => i.into(),
84 Self::VarChar(str) => str.into(),
85 Self::VarBinary(bytes) => S::from_byte_slice_via_hash(bytes),
86 Self::Decimal75(_, _, i) => i.into_scalar(),
87 Self::Int128(i) => i.into(),
88 Self::Scalar(limbs) => (*limbs).into(),
89 Self::TimeStampTZ(_, _, time) => time.into(),
90 }
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use crate::base::{
97 database::LiteralValue,
98 math::decimal::Precision,
99 posql_time::{PoSQLTimeUnit, PoSQLTimeZone},
100 try_standard_binary_serialization,
101 };
102
103 #[test]
105 fn literal_value_and_column_type_varaints_should_have_same_data_type_serialization() {
106 let literal_values = vec![
107 LiteralValue::Boolean(true),
108 LiteralValue::Uint8(2),
109 LiteralValue::TinyInt(3),
110 LiteralValue::SmallInt(4),
111 LiteralValue::Int(5),
112 LiteralValue::BigInt(6),
113 LiteralValue::Int128(7),
114 LiteralValue::VarChar("test".to_string()),
115 LiteralValue::Decimal75(Precision::new(9).unwrap(), 2, 7010.into()),
116 LiteralValue::TimeStampTZ(PoSQLTimeUnit::Millisecond, PoSQLTimeZone::utc(), 10),
117 LiteralValue::Scalar([1; 4]),
118 LiteralValue::VarBinary(vec![1]),
119 ];
120 for literal_value in literal_values {
121 let column_type = literal_value.column_type();
122 let serialized_column_type =
123 hex::encode(try_standard_binary_serialization(column_type).unwrap());
124 let serialized_literal_value =
125 hex::encode(try_standard_binary_serialization(literal_value).unwrap());
126 assert!(serialized_literal_value.starts_with(&serialized_column_type));
127 }
128 }
129}