Skip to main content

keelson_mysql/statement/
table.rs

1use keelson_core::clause::{
2    HasLimit, HasOffset, HasOrderBy, HasTableRef, Limit, Offset, OrderBy, TableRef,
3};
4use keelson_core::expr::{Expr, IntoExpr, IntoExprList};
5use keelson_core::{Dialect, Error, Expression, Mod, Query, QueryExtensions, QueryType, SqlWriter};
6
7use crate::Mysql;
8
9/// The MySQL `TABLE` statement (MySQL 8.0.19+) — `TABLE t` is
10/// `SELECT * FROM t`.
11///
12/// From <https://dev.mysql.com/doc/refman/8.4/en/table.html>:
13///
14/// ```text
15/// TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]
16/// ```
17///
18/// The struct is that line and nothing more: a bare table name — no alias, no
19/// index hints, no `PARTITION` — and the three tail clauses. `WHERE` does not
20/// exist here and does not compile.
21#[derive(Debug, Clone, Default)]
22pub struct TableQuery {
23    /// The table. Grammar takes a bare name only.
24    pub table: TableRef,
25    /// `ORDER BY column_name`.
26    pub order_by: OrderBy,
27    /// `LIMIT number`.
28    pub limit: Limit,
29    /// `OFFSET number` — part of the `LIMIT` production, as in a `SELECT`.
30    pub offset: Offset,
31}
32
33impl TableQuery {
34    /// A `TABLE` with no table yet — which does not build until it has one.
35    pub fn new() -> TableQuery {
36        TableQuery::default()
37    }
38
39    /// Apply more mods to an existing query.
40    pub fn apply(&mut self, mods: impl Mod<TableQuery>) {
41        mods.apply(self);
42    }
43}
44
45impl Expression for TableQuery {
46    fn write_sql(&self, w: &mut SqlWriter<'_>) {
47        if self.table.is_empty() {
48            w.record_error(Error::Incomplete("the table of a TABLE statement"));
49            return;
50        }
51
52        w.push_str("TABLE ");
53        w.write_expr(&self.table);
54
55        w.write_if(!self.order_by.is_empty(), " ", &self.order_by, "");
56        w.write_if(!self.limit.is_empty(), " ", &self.limit, "");
57        w.write_if(!self.offset.is_empty(), " ", &self.offset, "");
58    }
59}
60
61impl Query for TableQuery {
62    fn query_type(&self) -> QueryType {
63        // `TABLE t` is `SELECT * FROM t`, rows and all.
64        QueryType::Select
65    }
66
67    fn dialect(&self) -> &dyn Dialect {
68        &Mysql
69    }
70}
71
72impl<H, L, M> QueryExtensions<H, L, M> for TableQuery {}
73
74impl IntoExpr for TableQuery {
75    fn into_expr(self) -> Expr {
76        crate::query(self)
77    }
78}
79
80impl IntoExprList for TableQuery {
81    fn into_expr_list(self) -> Vec<Expr> {
82        vec![self.into_expr()]
83    }
84}
85
86impl HasTableRef for TableQuery {
87    fn table_ref_mut(&mut self) -> &mut TableRef {
88        &mut self.table
89    }
90}
91
92impl HasOrderBy for TableQuery {
93    fn order_by_mut(&mut self) -> &mut OrderBy {
94        &mut self.order_by
95    }
96}
97
98impl HasLimit for TableQuery {
99    fn limit_mut(&mut self) -> &mut Limit {
100        &mut self.limit
101    }
102}
103
104impl HasOffset for TableQuery {
105    fn offset_mut(&mut self) -> &mut Offset {
106        &mut self.offset
107    }
108}