mod comparison;
mod display;
mod hash;
use crate::{
temporal::{Date, Interval, IntervalField, Time, Timestamp},
DataType,
};
pub type StringValue = arcstr::ArcStr;
#[derive(Debug, Clone)]
pub enum SqlValue {
Integer(i64),
Smallint(i16),
Bigint(i64),
Unsigned(u64), Numeric(f64),
Float(f32),
Real(f64), Double(f64),
Character(StringValue),
Varchar(StringValue),
Boolean(bool),
Date(Date),
Time(Time),
Timestamp(Timestamp),
Interval(Interval),
Vector(Vec<f32>),
Blob(Vec<u8>),
Null,
}
impl SqlValue {
pub fn is_null(&self) -> bool {
matches!(self, SqlValue::Null)
}
pub fn type_name(&self) -> &'static str {
match self {
SqlValue::Integer(_) => "INTEGER",
SqlValue::Smallint(_) => "SMALLINT",
SqlValue::Bigint(_) => "BIGINT",
SqlValue::Unsigned(_) => "UNSIGNED",
SqlValue::Numeric(_) => "NUMERIC",
SqlValue::Float(_) => "FLOAT",
SqlValue::Real(_) => "REAL",
SqlValue::Double(_) => "DOUBLE PRECISION",
SqlValue::Character(_) => "CHAR",
SqlValue::Varchar(_) => "VARCHAR",
SqlValue::Boolean(_) => "BOOLEAN",
SqlValue::Date(_) => "DATE",
SqlValue::Time(_) => "TIME",
SqlValue::Timestamp(_) => "TIMESTAMP",
SqlValue::Interval(_) => "INTERVAL",
SqlValue::Vector(_) => "VECTOR",
SqlValue::Blob(_) => "BLOB",
SqlValue::Null => "NULL",
}
}
pub fn get_type(&self) -> DataType {
match self {
SqlValue::Integer(_) => DataType::Integer,
SqlValue::Smallint(_) => DataType::Smallint,
SqlValue::Bigint(_) => DataType::Bigint,
SqlValue::Unsigned(_) => DataType::Unsigned,
SqlValue::Numeric(_) => DataType::Numeric { precision: 38, scale: 0 }, SqlValue::Float(_) => DataType::Float { precision: 53 }, SqlValue::Real(_) => DataType::Real,
SqlValue::Double(_) => DataType::DoublePrecision,
SqlValue::Character(s) => DataType::Character { length: s.len() },
SqlValue::Varchar(_) => DataType::Varchar { max_length: None },
SqlValue::Boolean(_) => DataType::Boolean,
SqlValue::Date(_) => DataType::Date,
SqlValue::Time(_) => DataType::Time { with_timezone: false },
SqlValue::Timestamp(_) => DataType::Timestamp { with_timezone: false },
SqlValue::Interval(_) => DataType::Interval {
start_field: IntervalField::Day,
end_field: None,
},
SqlValue::Vector(v) => DataType::Vector { dimensions: v.len() as u32 },
SqlValue::Blob(_) => DataType::BinaryLargeObject,
SqlValue::Null => DataType::Null,
}
}
pub fn estimated_size_bytes(&self) -> usize {
use std::mem::size_of;
let base_size = size_of::<SqlValue>();
match self {
SqlValue::Character(s) | SqlValue::Varchar(s) => {
base_size + s.len()
}
SqlValue::Interval(i) => {
base_size + i.to_string().len()
}
SqlValue::Vector(v) => {
base_size + (v.capacity() * std::mem::size_of::<f32>())
}
SqlValue::Blob(b) => {
base_size + b.capacity()
}
SqlValue::Integer(_)
| SqlValue::Smallint(_)
| SqlValue::Bigint(_)
| SqlValue::Unsigned(_)
| SqlValue::Numeric(_)
| SqlValue::Float(_)
| SqlValue::Real(_)
| SqlValue::Double(_)
| SqlValue::Boolean(_)
| SqlValue::Date(_)
| SqlValue::Time(_)
| SqlValue::Timestamp(_)
| SqlValue::Null => base_size,
}
}
}