use alloc::string::String;
use alloc::vec::Vec;
use crate::parser::Literal;
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Int(i64),
Float(f32),
Text(String),
Vector(Vec<f32>),
Null,
}
impl Eq for Value {}
impl PartialOrd for Value {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Value {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
match (self, other) {
(Value::Int(a), Value::Int(b)) => a.cmp(b),
(Value::Float(a), Value::Float(b)) => a.total_cmp(b),
(Value::Text(a), Value::Text(b)) => a.cmp(b),
(Value::Vector(a), Value::Vector(b)) => a.len().cmp(&b.len()).then_with(|| {
a.iter()
.zip(b.iter())
.map(|(x, y)| x.to_bits().cmp(&y.to_bits()))
.find(|o| *o != core::cmp::Ordering::Equal)
.unwrap_or(core::cmp::Ordering::Equal)
}),
(Value::Null, Value::Null) => core::cmp::Ordering::Equal,
(Value::Null, _) => core::cmp::Ordering::Greater,
(_, Value::Null) => core::cmp::Ordering::Less,
(Value::Int(_), _) => core::cmp::Ordering::Less,
(_, Value::Int(_)) => core::cmp::Ordering::Greater,
(Value::Float(_), Value::Text(_)) | (Value::Float(_), Value::Vector(_)) => {
core::cmp::Ordering::Less
}
(Value::Text(_), Value::Float(_)) | (Value::Vector(_), Value::Float(_)) => {
core::cmp::Ordering::Greater
}
(Value::Text(_), Value::Vector(_)) => core::cmp::Ordering::Less,
(Value::Vector(_), Value::Text(_)) => core::cmp::Ordering::Greater,
}
}
}
pub type Row = Vec<Value>;
#[derive(Debug, Clone, Default)]
pub struct Table {
pub columns: Vec<String>,
pub rows: Vec<Row>,
}
impl Table {
pub fn new(columns: Vec<String>) -> Self {
Self {
columns,
rows: Vec::new(),
}
}
pub fn insert(&mut self, row: Row) {
self.rows.push(row);
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExecError {
UnknownColumn(String),
TypeMismatch,
GroupByColumnNotFound(String),
UnresolvedSubquery,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct ResultSet {
pub columns: Vec<String>,
pub rows: Vec<Row>,
pub affected: Option<u64>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CommandTag {
Select(u64),
Insert(u64),
Update(u64),
Delete(u64),
CreateTable,
CreateView,
DropView,
AlterTable,
Begin,
Commit,
Rollback,
Set,
Reset,
Empty,
}
impl CommandTag {
pub fn as_str(&self) -> &'static str {
match self {
CommandTag::Select(_) => "SELECT",
CommandTag::Insert(_) => "INSERT",
CommandTag::Update(_) => "UPDATE",
CommandTag::Delete(_) => "DELETE",
CommandTag::CreateTable => "CREATE TABLE",
CommandTag::CreateView => "CREATE VIEW",
CommandTag::DropView => "DROP VIEW",
CommandTag::AlterTable => "ALTER TABLE",
CommandTag::Begin => "BEGIN",
CommandTag::Commit => "COMMIT",
CommandTag::Rollback => "ROLLBACK",
CommandTag::Set => "SET",
CommandTag::Reset => "RESET",
CommandTag::Empty => "",
}
}
pub fn row_count(&self) -> Option<u64> {
match self {
CommandTag::Select(n)
| CommandTag::Insert(n)
| CommandTag::Update(n)
| CommandTag::Delete(n) => Some(*n),
_ => None,
}
}
}
pub fn literal_to_value(lit: &Literal) -> Value {
match lit {
Literal::Int(v) => Value::Int(*v),
Literal::Float(v) => Value::Float(*v),
Literal::Text(s) => Value::Text(s.clone()),
Literal::Vector(v) => Value::Vector(v.clone()),
Literal::Null => Value::Null,
}
}