1use crate::stmt::{ExprExists, Input};
2
3use super::{
4 expr_reference::ExprReference, Entry, EntryMut, EntryPath, ExprAnd, ExprAny, ExprArg,
5 ExprBinaryOp, ExprCast, ExprError, ExprFunc, ExprInList, ExprInSubquery, ExprIsNull,
6 ExprIsVariant, ExprLet, ExprList, ExprMap, ExprMatch, ExprNot, ExprOr, ExprProject, ExprRecord,
7 ExprStmt, Node, Projection, Substitute, Value, Visit, VisitMut,
8};
9use std::fmt;
10
11#[derive(Clone, PartialEq)]
13pub enum Expr {
14 And(ExprAnd),
16
17 Any(ExprAny),
19
20 Arg(ExprArg),
22
23 BinaryOp(ExprBinaryOp),
25
26 Cast(ExprCast),
28
29 Default,
32
33 Error(ExprError),
35
36 Exists(ExprExists),
39
40 Func(ExprFunc),
42
43 InList(ExprInList),
45
46 InSubquery(ExprInSubquery),
48
49 IsNull(ExprIsNull),
52
53 IsVariant(ExprIsVariant),
55
56 Let(ExprLet),
58
59 Map(ExprMap),
61
62 Match(ExprMatch),
64
65 Not(ExprNot),
67
68 Or(ExprOr),
70
71 Project(ExprProject),
73
74 Record(ExprRecord),
76
77 Reference(ExprReference),
80
81 List(ExprList),
83
84 Stmt(ExprStmt),
86
87 Value(Value),
89}
90
91impl Expr {
92 pub const TRUE: Expr = Expr::Value(Value::Bool(true));
93 pub const FALSE: Expr = Expr::Value(Value::Bool(false));
94 pub const DEFAULT: Expr = Expr::Default;
95
96 pub fn null() -> Self {
97 Self::Value(Value::Null)
98 }
99
100 pub fn is_value_null(&self) -> bool {
102 matches!(self, Self::Value(Value::Null))
103 }
104
105 pub fn is_true(&self) -> bool {
107 matches!(self, Self::Value(Value::Bool(true)))
108 }
109
110 pub fn is_false(&self) -> bool {
112 matches!(self, Self::Value(Value::Bool(false)))
113 }
114
115 pub fn is_unsatisfiable(&self) -> bool {
120 self.is_false() || self.is_value_null()
121 }
122
123 pub fn is_default(&self) -> bool {
125 matches!(self, Self::Default)
126 }
127
128 pub fn is_value(&self) -> bool {
130 matches!(self, Self::Value(..))
131 }
132
133 pub fn is_stmt(&self) -> bool {
134 matches!(self, Self::Stmt(..))
135 }
136
137 pub fn is_binary_op(&self) -> bool {
139 matches!(self, Self::BinaryOp(..))
140 }
141
142 pub fn is_arg(&self) -> bool {
143 matches!(self, Self::Arg(_))
144 }
145
146 pub fn is_always_non_nullable(&self) -> bool {
151 match self {
152 Self::Value(value) => !value.is_null(),
154 Self::And(_) | Self::Or(_) | Self::Not(_) => true,
156 Self::Any(_) => true,
158 Self::BinaryOp(_) => true,
160 Self::IsNull(_) => true,
162 Self::IsVariant(_) => true,
164 Self::Exists(_) => true,
166 Self::InList(_) | Self::InSubquery(_) => true,
168 _ => false,
170 }
171 }
172
173 pub fn into_value(self) -> Value {
174 match self {
175 Self::Value(value) => value,
176 _ => todo!(),
177 }
178 }
179
180 pub fn into_stmt(self) -> ExprStmt {
181 match self {
182 Self::Stmt(stmt) => stmt,
183 _ => todo!(),
184 }
185 }
186
187 pub fn is_stable(&self) -> bool {
191 match self {
192 Self::Value(_) => true,
194
195 Self::Default => false,
197
198 Self::Error(_) => true,
200
201 Self::Record(expr_record) => expr_record.iter().all(|expr| expr.is_stable()),
203 Self::List(expr_list) => expr_list.items.iter().all(|expr| expr.is_stable()),
204 Self::Cast(expr_cast) => expr_cast.expr.is_stable(),
205 Self::BinaryOp(expr_binary) => {
206 expr_binary.lhs.is_stable() && expr_binary.rhs.is_stable()
207 }
208 Self::And(expr_and) => expr_and.iter().all(|expr| expr.is_stable()),
209 Self::Any(expr_any) => expr_any.expr.is_stable(),
210 Self::Or(expr_or) => expr_or.iter().all(|expr| expr.is_stable()),
211 Self::IsNull(expr_is_null) => expr_is_null.expr.is_stable(),
212 Self::IsVariant(expr_is_variant) => expr_is_variant.expr.is_stable(),
213 Self::Not(expr_not) => expr_not.expr.is_stable(),
214 Self::InList(expr_in_list) => {
215 expr_in_list.expr.is_stable() && expr_in_list.list.is_stable()
216 }
217 Self::Project(expr_project) => expr_project.base.is_stable(),
218 Self::Let(expr_let) => {
219 expr_let.bindings.iter().all(|b| b.is_stable()) && expr_let.body.is_stable()
220 }
221 Self::Map(expr_map) => expr_map.base.is_stable() && expr_map.map.is_stable(),
222 Self::Match(expr_match) => {
223 expr_match.subject.is_stable()
224 && expr_match.arms.iter().all(|arm| arm.expr.is_stable())
225 }
226
227 Self::Reference(_) | Self::Arg(_) => true,
229
230 Self::Stmt(_) | Self::Func(_) | Self::InSubquery(_) | Self::Exists(_) => false,
233 }
234 }
235
236 pub fn is_const(&self) -> bool {
246 self.is_const_at_depth(0)
247 }
248
249 fn is_const_at_depth(&self, map_depth: usize) -> bool {
253 match self {
254 Self::Value(_) => true,
256
257 Self::Arg(arg) => arg.nesting < map_depth,
259
260 Self::Error(_) => true,
262
263 Self::Reference(_)
265 | Self::Stmt(_)
266 | Self::InSubquery(_)
267 | Self::Exists(_)
268 | Self::Default
269 | Self::Func(_) => false,
270
271 Self::Record(expr_record) => expr_record
273 .iter()
274 .all(|expr| expr.is_const_at_depth(map_depth)),
275 Self::List(expr_list) => expr_list
276 .items
277 .iter()
278 .all(|expr| expr.is_const_at_depth(map_depth)),
279 Self::Cast(expr_cast) => expr_cast.expr.is_const_at_depth(map_depth),
280 Self::BinaryOp(expr_binary) => {
281 expr_binary.lhs.is_const_at_depth(map_depth)
282 && expr_binary.rhs.is_const_at_depth(map_depth)
283 }
284 Self::And(expr_and) => expr_and
285 .iter()
286 .all(|expr| expr.is_const_at_depth(map_depth)),
287 Self::Any(expr_any) => expr_any.expr.is_const_at_depth(map_depth),
288 Self::Not(expr_not) => expr_not.expr.is_const_at_depth(map_depth),
289 Self::Or(expr_or) => expr_or.iter().all(|expr| expr.is_const_at_depth(map_depth)),
290 Self::IsNull(expr_is_null) => expr_is_null.expr.is_const_at_depth(map_depth),
291 Self::IsVariant(expr_is_variant) => expr_is_variant.expr.is_const_at_depth(map_depth),
292 Self::InList(expr_in_list) => {
293 expr_in_list.expr.is_const_at_depth(map_depth)
294 && expr_in_list.list.is_const_at_depth(map_depth)
295 }
296 Self::Project(expr_project) => expr_project.base.is_const_at_depth(map_depth),
297
298 Self::Let(expr_let) => {
301 expr_let
302 .bindings
303 .iter()
304 .all(|b| b.is_const_at_depth(map_depth))
305 && expr_let.body.is_const_at_depth(map_depth + 1)
306 }
307 Self::Map(expr_map) => {
310 expr_map.base.is_const_at_depth(map_depth)
311 && expr_map.map.is_const_at_depth(map_depth + 1)
312 }
313 Self::Match(expr_match) => {
314 expr_match.subject.is_const_at_depth(map_depth)
315 && expr_match
316 .arms
317 .iter()
318 .all(|arm| arm.expr.is_const_at_depth(map_depth))
319 }
320 }
321 }
322
323 pub fn is_eval(&self) -> bool {
329 match self {
330 Self::Value(_) => true,
332
333 Self::Arg(_) => true,
335
336 Self::Error(_) => true,
338
339 Self::Default
341 | Self::Reference(_)
342 | Self::Stmt(_)
343 | Self::InSubquery(_)
344 | Self::Exists(_) => false,
345
346 Self::Record(expr_record) => expr_record.iter().all(|expr| expr.is_eval()),
348 Self::List(expr_list) => expr_list.items.iter().all(|expr| expr.is_eval()),
349 Self::Cast(expr_cast) => expr_cast.expr.is_eval(),
350 Self::BinaryOp(expr_binary) => expr_binary.lhs.is_eval() && expr_binary.rhs.is_eval(),
351 Self::And(expr_and) => expr_and.iter().all(|expr| expr.is_eval()),
352 Self::Any(expr_any) => expr_any.expr.is_eval(),
353 Self::Or(expr_or) => expr_or.iter().all(|expr| expr.is_eval()),
354 Self::Not(expr_not) => expr_not.expr.is_eval(),
355 Self::IsNull(expr_is_null) => expr_is_null.expr.is_eval(),
356 Self::IsVariant(expr_is_variant) => expr_is_variant.expr.is_eval(),
357 Self::InList(expr_in_list) => {
358 expr_in_list.expr.is_eval() && expr_in_list.list.is_eval()
359 }
360 Self::Project(expr_project) => expr_project.base.is_eval(),
361 Self::Let(expr_let) => {
362 expr_let.bindings.iter().all(|b| b.is_eval()) && expr_let.body.is_eval()
363 }
364 Self::Map(expr_map) => expr_map.base.is_eval() && expr_map.map.is_eval(),
365 Self::Match(expr_match) => {
366 expr_match.subject.is_eval() && expr_match.arms.iter().all(|arm| arm.expr.is_eval())
367 }
368 Self::Func(_) => false,
369 }
370 }
371
372 pub fn map_projections(&self, f: impl FnMut(&Projection) -> Projection) -> Self {
373 struct MapProjections<T>(T);
374
375 impl<T: FnMut(&Projection) -> Projection> VisitMut for MapProjections<T> {
376 fn visit_projection_mut(&mut self, i: &mut Projection) {
377 *i = self.0(i);
378 }
379 }
380
381 let mut mapped = self.clone();
382 MapProjections(f).visit_expr_mut(&mut mapped);
383 mapped
384 }
385
386 #[track_caller]
387 pub fn entry(&self, path: impl EntryPath) -> Option<Entry<'_>> {
388 let mut ret = Entry::Expr(self);
389
390 for step in path.step_iter() {
391 ret = match ret {
392 Entry::Expr(Self::Record(expr)) => Entry::Expr(&expr[step]),
393 Entry::Expr(Self::List(expr)) => Entry::Expr(&expr.items[step]),
394 Entry::Value(Value::Record(record))
395 | Entry::Expr(Self::Value(Value::Record(record))) => Entry::Value(&record[step]),
396 Entry::Value(Value::List(items)) | Entry::Expr(Self::Value(Value::List(items))) => {
397 Entry::Value(&items[step])
398 }
399 _ => return None,
400 }
401 }
402
403 Some(ret)
404 }
405
406 #[track_caller]
407 pub fn entry_mut(&mut self, path: impl EntryPath) -> EntryMut<'_> {
408 let mut ret = EntryMut::Expr(self);
409
410 for step in path.step_iter() {
411 ret = match ret {
412 EntryMut::Expr(Self::Record(expr)) => EntryMut::Expr(&mut expr[step]),
413 EntryMut::Value(Value::Record(record))
414 | EntryMut::Expr(Self::Value(Value::Record(record))) => {
415 EntryMut::Value(&mut record[step])
416 }
417 _ => todo!("ret={ret:#?}; step={step:#?}"),
418 }
419 }
420
421 ret
422 }
423
424 pub fn take(&mut self) -> Self {
425 std::mem::replace(self, Self::Value(Value::Null))
426 }
427
428 pub fn substitute(&mut self, input: impl Input) {
429 Substitute::new(input).visit_expr_mut(self);
430 }
431}
432
433impl Node for Expr {
434 fn visit<V: Visit>(&self, mut visit: V) {
435 visit.visit_expr(self);
436 }
437
438 fn visit_mut<V: VisitMut>(&mut self, mut visit: V) {
439 visit.visit_expr_mut(self);
440 }
441}
442
443impl From<bool> for Expr {
446 fn from(value: bool) -> Self {
447 Self::Value(Value::from(value))
448 }
449}
450
451impl From<i64> for Expr {
452 fn from(value: i64) -> Self {
453 Self::Value(value.into())
454 }
455}
456
457impl From<&i64> for Expr {
458 fn from(value: &i64) -> Self {
459 Self::Value(value.into())
460 }
461}
462
463impl From<String> for Expr {
464 fn from(value: String) -> Self {
465 Self::Value(value.into())
466 }
467}
468
469impl From<&String> for Expr {
470 fn from(value: &String) -> Self {
471 Self::Value(value.into())
472 }
473}
474
475impl From<&str> for Expr {
476 fn from(value: &str) -> Self {
477 Self::Value(value.into())
478 }
479}
480
481impl From<Value> for Expr {
482 fn from(value: Value) -> Self {
483 Self::Value(value)
484 }
485}
486
487impl<E1, E2> From<(E1, E2)> for Expr
488where
489 E1: Into<Self>,
490 E2: Into<Self>,
491{
492 fn from(value: (E1, E2)) -> Self {
493 Self::Record(value.into())
494 }
495}
496
497impl fmt::Debug for Expr {
498 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
499 match self {
500 Self::And(e) => e.fmt(f),
501 Self::Any(e) => e.fmt(f),
502 Self::Arg(e) => e.fmt(f),
503 Self::BinaryOp(e) => e.fmt(f),
504 Self::Cast(e) => e.fmt(f),
505 Self::Default => write!(f, "Default"),
506 Self::Error(e) => e.fmt(f),
507 Self::Exists(e) => e.fmt(f),
508 Self::Func(e) => e.fmt(f),
509 Self::InList(e) => e.fmt(f),
510 Self::InSubquery(e) => e.fmt(f),
511 Self::IsNull(e) => e.fmt(f),
512 Self::IsVariant(e) => e.fmt(f),
513 Self::Let(e) => e.fmt(f),
514 Self::Map(e) => e.fmt(f),
515 Self::Match(e) => e.fmt(f),
516 Self::Not(e) => e.fmt(f),
517 Self::Or(e) => e.fmt(f),
518 Self::Project(e) => e.fmt(f),
519 Self::Record(e) => e.fmt(f),
520 Self::Reference(e) => e.fmt(f),
521 Self::List(e) => e.fmt(f),
522 Self::Stmt(e) => e.fmt(f),
523 Self::Value(e) => e.fmt(f),
524 }
525 }
526}