mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-07-19 10:25:03 +00:00
80 lines
2.1 KiB
Rust
80 lines
2.1 KiB
Rust
use std::fmt::Display;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::{model::table::SimValue, SimulatorEnv};
|
|
|
|
use super::predicate::Predicate;
|
|
|
|
/// `SELECT` distinctness
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
pub(crate) enum Distinctness {
|
|
/// `DISTINCT`
|
|
Distinct,
|
|
/// `ALL`
|
|
All,
|
|
}
|
|
|
|
/// `SELECT` or `RETURNING` result column
|
|
// https://sqlite.org/syntax/result-column.html
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
pub enum ResultColumn {
|
|
/// expression
|
|
Expr(Predicate),
|
|
/// `*`
|
|
Star,
|
|
/// column name
|
|
Column(String),
|
|
}
|
|
|
|
impl Display for ResultColumn {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
ResultColumn::Expr(expr) => write!(f, "({})", expr),
|
|
ResultColumn::Star => write!(f, "*"),
|
|
ResultColumn::Column(name) => write!(f, "{}", name),
|
|
}
|
|
}
|
|
}
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
pub(crate) struct Select {
|
|
pub(crate) table: String,
|
|
pub(crate) result_columns: Vec<ResultColumn>,
|
|
pub(crate) predicate: Predicate,
|
|
pub(crate) distinct: Distinctness,
|
|
pub(crate) limit: Option<usize>,
|
|
}
|
|
|
|
impl Select {
|
|
pub(crate) fn shadow(&self, env: &mut SimulatorEnv) -> Vec<Vec<SimValue>> {
|
|
let table = env.tables.iter().find(|t| t.name == self.table.as_str());
|
|
if let Some(table) = table {
|
|
table
|
|
.rows
|
|
.iter()
|
|
.filter(|row| self.predicate.test(row, table))
|
|
.cloned()
|
|
.collect()
|
|
} else {
|
|
vec![]
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for Select {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(
|
|
f,
|
|
"SELECT {} FROM {} WHERE {}{}",
|
|
self.result_columns
|
|
.iter()
|
|
.map(ResultColumn::to_string)
|
|
.collect::<Vec<_>>()
|
|
.join(", "),
|
|
self.table,
|
|
self.predicate,
|
|
self.limit
|
|
.map_or("".to_string(), |l| format!(" LIMIT {}", l))
|
|
)
|
|
}
|
|
}
|