keelson_psql/statement/
values.rs1use keelson_core::clause::{
2 Combines, Fetch, HasCombines, HasFetch, HasLimit, HasOffset, HasOrderBy, HasValues, HasWith,
3 Limit, Offset, OrderBy, Values, With,
4};
5use keelson_core::expr::{Expr, IntoExpr, IntoExprList};
6use keelson_core::{Dialect, Error, Expression, Mod, Query, QueryExtensions, QueryType, SqlWriter};
7
8use crate::Psql;
9
10#[derive(Debug, Clone, Default)]
36pub struct ValuesQuery {
37 pub with: With,
39 pub values: Values,
41 pub order_by: OrderBy,
43 pub limit: Limit,
45 pub offset: Offset,
47 pub fetch: Fetch,
49 pub combines: Combines,
51}
52
53impl ValuesQuery {
54 pub fn new() -> ValuesQuery {
56 ValuesQuery::default()
57 }
58
59 pub fn apply(&mut self, mods: impl Mod<ValuesQuery>) {
61 mods.apply(self);
62 }
63
64 fn has_tail_clauses(&self) -> bool {
68 !self.order_by.is_empty()
69 || !self.limit.is_empty()
70 || !self.offset.is_empty()
71 || !self.fetch.is_empty()
72 }
73}
74
75impl Expression for ValuesQuery {
76 fn write_sql(&self, w: &mut SqlWriter<'_>) {
77 if !self.limit.is_empty() && !self.fetch.is_empty() {
79 w.record_error(Error::conflicting_clauses("LIMIT", "FETCH"));
80 return;
81 }
82 if self.values.query.is_some() {
86 w.record_error(Error::other(
87 "a standalone VALUES statement takes rows; a source query belongs to INSERT",
88 ));
89 return;
90 }
91 if self.values.rows.is_empty() {
92 w.record_error(Error::Incomplete("the rows of a VALUES statement"));
93 return;
94 }
95
96 w.write_if(!self.with.is_empty(), "", &self.with, " ");
97
98 let parens = self
99 .combines
100 .parenthesises_leading_query(self.has_tail_clauses());
101 if parens {
102 w.push_str("(");
103 }
104
105 w.write_expr(&self.values);
106
107 w.write_if(!self.order_by.is_empty(), " ", &self.order_by, "");
108 w.write_if(!self.limit.is_empty(), " ", &self.limit, "");
109 w.write_if(!self.offset.is_empty(), " ", &self.offset, "");
110 w.write_if(!self.fetch.is_empty(), " ", &self.fetch, "");
111
112 if parens {
113 w.push_str(")");
114 }
115
116 w.write_if(!self.combines.is_empty(), " ", &self.combines, "");
117 }
118}
119
120impl Query for ValuesQuery {
121 fn query_type(&self) -> QueryType {
122 QueryType::Select
125 }
126
127 fn dialect(&self) -> &dyn Dialect {
128 &Psql
129 }
130}
131
132impl<H, L, M> QueryExtensions<H, L, M> for ValuesQuery {}
133
134impl IntoExpr for ValuesQuery {
135 fn into_expr(self) -> Expr {
136 crate::query(self)
137 }
138}
139
140impl IntoExprList for ValuesQuery {
141 fn into_expr_list(self) -> Vec<Expr> {
142 vec![self.into_expr()]
143 }
144}
145
146impl HasWith for ValuesQuery {
147 fn with_mut(&mut self) -> &mut With {
148 &mut self.with
149 }
150}
151
152impl HasValues for ValuesQuery {
153 fn values_mut(&mut self) -> &mut Values {
154 &mut self.values
155 }
156}
157
158impl HasOrderBy for ValuesQuery {
159 fn order_by_mut(&mut self) -> &mut OrderBy {
160 &mut self.order_by
161 }
162}
163
164impl HasLimit for ValuesQuery {
165 fn limit_mut(&mut self) -> &mut Limit {
166 &mut self.limit
167 }
168}
169
170impl HasOffset for ValuesQuery {
171 fn offset_mut(&mut self) -> &mut Offset {
172 &mut self.offset
173 }
174}
175
176impl HasFetch for ValuesQuery {
177 fn fetch_mut(&mut self) -> &mut Fetch {
178 &mut self.fetch
179 }
180}
181
182impl HasCombines for ValuesQuery {
183 fn combines_mut(&mut self) -> &mut Combines {
184 &mut self.combines
185 }
186}