1use core::fmt;
19use std::ops::ControlFlow;
20
21use sqlparser::ast::helpers::attached_token::AttachedToken;
22use sqlparser::ast::{
23 self, LimitClause, OrderByKind, SelectFlavor, visit_expressions_mut,
24};
25
26#[derive(Clone)]
27pub struct QueryBuilder {
28 with: Option<ast::With>,
29 body: Option<Box<ast::SetExpr>>,
30 order_by_kind: Option<OrderByKind>,
31 limit: Option<ast::Expr>,
32 limit_by: Vec<ast::Expr>,
33 offset: Option<ast::Offset>,
34 fetch: Option<ast::Fetch>,
35 locks: Vec<ast::LockClause>,
36 for_clause: Option<ast::ForClause>,
37 distinct_union: bool,
39}
40
41impl QueryBuilder {
42 pub fn with(&mut self, value: Option<ast::With>) -> &mut Self {
43 self.with = value;
44 self
45 }
46 pub fn body(&mut self, value: Box<ast::SetExpr>) -> &mut Self {
47 self.body = Some(value);
48 self
49 }
50 pub fn take_body(&mut self) -> Option<Box<ast::SetExpr>> {
51 self.body.take()
52 }
53 pub fn order_by(&mut self, value: OrderByKind) -> &mut Self {
54 self.order_by_kind = Some(value);
55 self
56 }
57 pub fn limit(&mut self, value: Option<ast::Expr>) -> &mut Self {
58 self.limit = value;
59 self
60 }
61 pub fn limit_by(&mut self, value: Vec<ast::Expr>) -> &mut Self {
62 self.limit_by = value;
63 self
64 }
65 pub fn offset(&mut self, value: Option<ast::Offset>) -> &mut Self {
66 self.offset = value;
67 self
68 }
69 pub fn fetch(&mut self, value: Option<ast::Fetch>) -> &mut Self {
70 self.fetch = value;
71 self
72 }
73 pub fn locks(&mut self, value: Vec<ast::LockClause>) -> &mut Self {
74 self.locks = value;
75 self
76 }
77 pub fn for_clause(&mut self, value: Option<ast::ForClause>) -> &mut Self {
78 self.for_clause = value;
79 self
80 }
81 pub fn distinct_union(&mut self) -> &mut Self {
82 self.distinct_union = true;
83 self
84 }
85 pub fn is_distinct_union(&self) -> bool {
86 self.distinct_union
87 }
88 pub fn build(&self) -> Result<ast::Query, BuilderError> {
89 let order_by = self
90 .order_by_kind
91 .as_ref()
92 .map(|order_by_kind| ast::OrderBy {
93 kind: order_by_kind.clone(),
94 interpolate: None,
95 });
96
97 Ok(ast::Query {
98 with: self.with.clone(),
99 body: match self.body {
100 Some(ref value) => value.clone(),
101 None => return Err(Into::into(UninitializedFieldError::from("body"))),
102 },
103 order_by,
104 limit_clause: Some(LimitClause::LimitOffset {
105 limit: self.limit.clone(),
106 offset: self.offset.clone(),
107 limit_by: self.limit_by.clone(),
108 }),
109 fetch: self.fetch.clone(),
110 locks: self.locks.clone(),
111 for_clause: self.for_clause.clone(),
112 settings: None,
113 format_clause: None,
114 pipe_operators: vec![],
115 })
116 }
117 fn create_empty() -> Self {
118 Self {
119 with: Default::default(),
120 body: Default::default(),
121 order_by_kind: Default::default(),
122 limit: Default::default(),
123 limit_by: Default::default(),
124 offset: Default::default(),
125 fetch: Default::default(),
126 locks: Default::default(),
127 for_clause: Default::default(),
128 distinct_union: false,
129 }
130 }
131}
132impl Default for QueryBuilder {
133 fn default() -> Self {
134 Self::create_empty()
135 }
136}
137
138#[derive(Clone)]
139pub struct SelectBuilder {
140 distinct: Option<ast::Distinct>,
141 top: Option<ast::Top>,
142 projection: Option<Vec<ast::SelectItem>>,
152 into: Option<ast::SelectInto>,
153 from: Vec<TableWithJoinsBuilder>,
154 lateral_views: Vec<ast::LateralView>,
155 selection: Option<ast::Expr>,
156 group_by: Option<ast::GroupByExpr>,
157 cluster_by: Vec<ast::Expr>,
158 distribute_by: Vec<ast::Expr>,
159 sort_by: Vec<ast::OrderByExpr>,
160 having: Option<ast::Expr>,
161 named_window: Vec<ast::NamedWindowDefinition>,
162 qualify: Option<ast::Expr>,
163 value_table_mode: Option<ast::ValueTableMode>,
164 flavor: Option<SelectFlavor>,
165}
166
167impl SelectBuilder {
168 pub fn distinct(&mut self, value: Option<ast::Distinct>) -> &mut Self {
169 self.distinct = value;
170 self
171 }
172 pub fn top(&mut self, value: Option<ast::Top>) -> &mut Self {
173 self.top = value;
174 self
175 }
176 pub fn projection(&mut self, value: Vec<ast::SelectItem>) -> &mut Self {
177 self.projection = Some(value);
178 self
179 }
180 pub fn pop_projections(&mut self) -> Vec<ast::SelectItem> {
181 self.projection.take().unwrap_or_default()
182 }
183 pub fn already_projected(&self) -> bool {
207 self.projection.is_some()
208 }
209 pub fn into(&mut self, value: Option<ast::SelectInto>) -> &mut Self {
210 self.into = value;
211 self
212 }
213 pub fn from(&mut self, value: Vec<TableWithJoinsBuilder>) -> &mut Self {
214 self.from = value;
215 self
216 }
217 pub fn push_from(&mut self, value: TableWithJoinsBuilder) -> &mut Self {
218 self.from.push(value);
219 self
220 }
221 pub fn pop_from(&mut self) -> Option<TableWithJoinsBuilder> {
222 self.from.pop()
223 }
224 pub fn lateral_views(&mut self, value: Vec<ast::LateralView>) -> &mut Self {
225 self.lateral_views = value;
226 self
227 }
228
229 pub fn replace_mark(
244 &mut self,
245 existing_expr: &ast::Expr,
246 value: &ast::Expr,
247 ) -> &mut Self {
248 if let Some(selection) = &mut self.selection {
249 let _ = visit_expressions_mut(selection, |expr| {
250 if expr == existing_expr {
251 *expr = value.clone();
252 }
253 ControlFlow::<()>::Continue(())
254 });
255 }
256 self
257 }
258
259 pub fn selection(&mut self, value: Option<ast::Expr>) -> &mut Self {
260 match (&self.selection, value) {
269 (Some(existing_selection), Some(new_selection)) => {
270 self.selection = Some(ast::Expr::BinaryOp {
271 left: Box::new(existing_selection.clone()),
272 op: ast::BinaryOperator::And,
273 right: Box::new(new_selection),
274 });
275 }
276 (None, Some(new_selection)) => {
277 self.selection = Some(new_selection);
278 }
279 (_, None) => (),
280 }
281
282 self
283 }
284 pub fn group_by(&mut self, value: ast::GroupByExpr) -> &mut Self {
285 self.group_by = Some(value);
286 self
287 }
288 pub fn cluster_by(&mut self, value: Vec<ast::Expr>) -> &mut Self {
289 self.cluster_by = value;
290 self
291 }
292 pub fn distribute_by(&mut self, value: Vec<ast::Expr>) -> &mut Self {
293 self.distribute_by = value;
294 self
295 }
296 pub fn sort_by(&mut self, value: Vec<ast::OrderByExpr>) -> &mut Self {
297 self.sort_by = value;
298 self
299 }
300 pub fn having(&mut self, value: Option<ast::Expr>) -> &mut Self {
301 self.having = value;
302 self
303 }
304 pub fn named_window(&mut self, value: Vec<ast::NamedWindowDefinition>) -> &mut Self {
305 self.named_window = value;
306 self
307 }
308 pub fn qualify(&mut self, value: Option<ast::Expr>) -> &mut Self {
309 self.qualify = value;
310 self
311 }
312 pub fn value_table_mode(&mut self, value: Option<ast::ValueTableMode>) -> &mut Self {
313 self.value_table_mode = value;
314 self
315 }
316 pub fn build(&self) -> Result<ast::Select, BuilderError> {
317 Ok(ast::Select {
318 distinct: self.distinct.clone(),
319 top_before_distinct: false,
320 top: self.top.clone(),
321 projection: self.projection.clone().unwrap_or_default(),
322 into: self.into.clone(),
323 from: self
324 .from
325 .iter()
326 .filter_map(|b| b.build().transpose())
327 .collect::<Result<Vec<_>, BuilderError>>()?,
328 lateral_views: self.lateral_views.clone(),
329 selection: self.selection.clone(),
330 group_by: match self.group_by {
331 Some(ref value) => value.clone(),
332 None => {
333 return Err(Into::into(UninitializedFieldError::from("group_by")));
334 }
335 },
336 cluster_by: self.cluster_by.clone(),
337 distribute_by: self.distribute_by.clone(),
338 sort_by: self.sort_by.clone(),
339 having: self.having.clone(),
340 named_window: self.named_window.clone(),
341 qualify: self.qualify.clone(),
342 value_table_mode: self.value_table_mode,
343 connect_by: None,
344 window_before_qualify: false,
345 prewhere: None,
346 select_token: AttachedToken::empty(),
347 flavor: match self.flavor {
348 Some(ref value) => value.clone(),
349 None => return Err(Into::into(UninitializedFieldError::from("flavor"))),
350 },
351 exclude: None,
352 })
353 }
354 fn create_empty() -> Self {
355 Self {
356 distinct: Default::default(),
357 top: Default::default(),
358 projection: None,
359 into: Default::default(),
360 from: Default::default(),
361 lateral_views: Default::default(),
362 selection: Default::default(),
363 group_by: Some(ast::GroupByExpr::Expressions(Vec::new(), Vec::new())),
364 cluster_by: Default::default(),
365 distribute_by: Default::default(),
366 sort_by: Default::default(),
367 having: Default::default(),
368 named_window: Default::default(),
369 qualify: Default::default(),
370 value_table_mode: Default::default(),
371 flavor: Some(SelectFlavor::Standard),
372 }
373 }
374}
375impl Default for SelectBuilder {
376 fn default() -> Self {
377 Self::create_empty()
378 }
379}
380
381#[derive(Clone)]
382pub struct TableWithJoinsBuilder {
383 relation: Option<RelationBuilder>,
384 joins: Vec<ast::Join>,
385}
386
387impl TableWithJoinsBuilder {
388 pub fn relation(&mut self, value: RelationBuilder) -> &mut Self {
389 self.relation = Some(value);
390 self
391 }
392
393 pub fn joins(&mut self, value: Vec<ast::Join>) -> &mut Self {
394 self.joins = value;
395 self
396 }
397 pub fn push_join(&mut self, value: ast::Join) -> &mut Self {
398 self.joins.push(value);
399 self
400 }
401
402 pub fn build(&self) -> Result<Option<ast::TableWithJoins>, BuilderError> {
403 match self.relation {
404 Some(ref value) => match value.build()? {
405 Some(relation) => Ok(Some(ast::TableWithJoins {
406 relation,
407 joins: self.joins.clone(),
408 })),
409 None => Ok(None),
410 },
411 None => Err(Into::into(UninitializedFieldError::from("relation"))),
412 }
413 }
414 fn create_empty() -> Self {
415 Self {
416 relation: Default::default(),
417 joins: Default::default(),
418 }
419 }
420}
421impl Default for TableWithJoinsBuilder {
422 fn default() -> Self {
423 Self::create_empty()
424 }
425}
426
427#[derive(Clone)]
428pub struct RelationBuilder {
429 relation: Option<TableFactorBuilder>,
430}
431
432#[derive(Clone)]
433#[expect(clippy::large_enum_variant)]
434enum TableFactorBuilder {
435 Table(TableRelationBuilder),
436 Derived(DerivedRelationBuilder),
437 Unnest(UnnestRelationBuilder),
438 Empty,
439}
440
441impl RelationBuilder {
442 pub fn has_relation(&self) -> bool {
443 self.relation.is_some()
444 }
445 pub fn table(&mut self, value: TableRelationBuilder) -> &mut Self {
446 self.relation = Some(TableFactorBuilder::Table(value));
447 self
448 }
449 pub fn derived(&mut self, value: DerivedRelationBuilder) -> &mut Self {
450 self.relation = Some(TableFactorBuilder::Derived(value));
451 self
452 }
453
454 pub fn unnest(&mut self, value: UnnestRelationBuilder) -> &mut Self {
455 self.relation = Some(TableFactorBuilder::Unnest(value));
456 self
457 }
458
459 pub fn empty(&mut self) -> &mut Self {
460 self.relation = Some(TableFactorBuilder::Empty);
461 self
462 }
463 pub fn alias(&mut self, value: Option<ast::TableAlias>) -> &mut Self {
464 let new = self;
465 match new.relation {
466 Some(TableFactorBuilder::Table(ref mut rel_builder)) => {
467 rel_builder.alias = value;
468 }
469 Some(TableFactorBuilder::Derived(ref mut rel_builder)) => {
470 rel_builder.alias = value;
471 }
472 Some(TableFactorBuilder::Unnest(ref mut rel_builder)) => {
473 rel_builder.alias = value;
474 }
475 Some(TableFactorBuilder::Empty) => (),
476 None => (),
477 }
478 new
479 }
480 pub fn build(&self) -> Result<Option<ast::TableFactor>, BuilderError> {
481 Ok(match self.relation {
482 Some(TableFactorBuilder::Table(ref value)) => Some(value.build()?),
483 Some(TableFactorBuilder::Derived(ref value)) => Some(value.build()?),
484 Some(TableFactorBuilder::Unnest(ref value)) => Some(value.build()?),
485 Some(TableFactorBuilder::Empty) => None,
486 None => return Err(Into::into(UninitializedFieldError::from("relation"))),
487 })
488 }
489 fn create_empty() -> Self {
490 Self {
491 relation: Default::default(),
492 }
493 }
494}
495impl Default for RelationBuilder {
496 fn default() -> Self {
497 Self::create_empty()
498 }
499}
500
501#[derive(Clone)]
502pub struct TableRelationBuilder {
503 name: Option<ast::ObjectName>,
504 alias: Option<ast::TableAlias>,
505 args: Option<Vec<ast::FunctionArg>>,
506 with_hints: Vec<ast::Expr>,
507 version: Option<ast::TableVersion>,
508 partitions: Vec<ast::Ident>,
509 index_hints: Vec<ast::TableIndexHints>,
510}
511
512impl TableRelationBuilder {
513 pub fn name(&mut self, value: ast::ObjectName) -> &mut Self {
514 self.name = Some(value);
515 self
516 }
517 pub fn alias(&mut self, value: Option<ast::TableAlias>) -> &mut Self {
518 self.alias = value;
519 self
520 }
521 pub fn args(&mut self, value: Option<Vec<ast::FunctionArg>>) -> &mut Self {
522 self.args = value;
523 self
524 }
525 pub fn with_hints(&mut self, value: Vec<ast::Expr>) -> &mut Self {
526 self.with_hints = value;
527 self
528 }
529 pub fn version(&mut self, value: Option<ast::TableVersion>) -> &mut Self {
530 self.version = value;
531 self
532 }
533 pub fn partitions(&mut self, value: Vec<ast::Ident>) -> &mut Self {
534 self.partitions = value;
535 self
536 }
537 pub fn index_hints(&mut self, value: Vec<ast::TableIndexHints>) -> &mut Self {
538 self.index_hints = value;
539 self
540 }
541 pub fn build(&self) -> Result<ast::TableFactor, BuilderError> {
542 Ok(ast::TableFactor::Table {
543 name: match self.name {
544 Some(ref value) => value.clone(),
545 None => return Err(Into::into(UninitializedFieldError::from("name"))),
546 },
547 alias: self.alias.clone(),
548 args: self.args.clone().map(|args| ast::TableFunctionArgs {
549 args,
550 settings: None,
551 }),
552 with_hints: self.with_hints.clone(),
553 version: self.version.clone(),
554 partitions: self.partitions.clone(),
555 with_ordinality: false,
556 json_path: None,
557 sample: None,
558 index_hints: self.index_hints.clone(),
559 })
560 }
561 fn create_empty() -> Self {
562 Self {
563 name: Default::default(),
564 alias: Default::default(),
565 args: Default::default(),
566 with_hints: Default::default(),
567 version: Default::default(),
568 partitions: Default::default(),
569 index_hints: Default::default(),
570 }
571 }
572}
573impl Default for TableRelationBuilder {
574 fn default() -> Self {
575 Self::create_empty()
576 }
577}
578#[derive(Clone)]
579pub struct DerivedRelationBuilder {
580 lateral: Option<bool>,
581 subquery: Option<Box<ast::Query>>,
582 alias: Option<ast::TableAlias>,
583}
584
585impl DerivedRelationBuilder {
586 pub fn lateral(&mut self, value: bool) -> &mut Self {
587 self.lateral = Some(value);
588 self
589 }
590 pub fn subquery(&mut self, value: Box<ast::Query>) -> &mut Self {
591 self.subquery = Some(value);
592 self
593 }
594 pub fn alias(&mut self, value: Option<ast::TableAlias>) -> &mut Self {
595 self.alias = value;
596 self
597 }
598 fn build(&self) -> Result<ast::TableFactor, BuilderError> {
599 Ok(ast::TableFactor::Derived {
600 lateral: match self.lateral {
601 Some(ref value) => *value,
602 None => return Err(Into::into(UninitializedFieldError::from("lateral"))),
603 },
604 subquery: match self.subquery {
605 Some(ref value) => value.clone(),
606 None => {
607 return Err(Into::into(UninitializedFieldError::from("subquery")));
608 }
609 },
610 alias: self.alias.clone(),
611 })
612 }
613 fn create_empty() -> Self {
614 Self {
615 lateral: Default::default(),
616 subquery: Default::default(),
617 alias: Default::default(),
618 }
619 }
620}
621impl Default for DerivedRelationBuilder {
622 fn default() -> Self {
623 Self::create_empty()
624 }
625}
626
627#[derive(Clone)]
628pub struct UnnestRelationBuilder {
629 pub alias: Option<ast::TableAlias>,
630 pub array_exprs: Vec<ast::Expr>,
631 with_offset: bool,
632 with_offset_alias: Option<ast::Ident>,
633 with_ordinality: bool,
634}
635
636impl UnnestRelationBuilder {
637 pub fn alias(&mut self, value: Option<ast::TableAlias>) -> &mut Self {
638 self.alias = value;
639 self
640 }
641 pub fn array_exprs(&mut self, value: Vec<ast::Expr>) -> &mut Self {
642 self.array_exprs = value;
643 self
644 }
645
646 pub fn with_offset(&mut self, value: bool) -> &mut Self {
647 self.with_offset = value;
648 self
649 }
650
651 pub fn with_offset_alias(&mut self, value: Option<ast::Ident>) -> &mut Self {
652 self.with_offset_alias = value;
653 self
654 }
655
656 pub fn with_ordinality(&mut self, value: bool) -> &mut Self {
657 self.with_ordinality = value;
658 self
659 }
660
661 pub fn build(&self) -> Result<ast::TableFactor, BuilderError> {
662 Ok(ast::TableFactor::UNNEST {
663 alias: self.alias.clone(),
664 array_exprs: self.array_exprs.clone(),
665 with_offset: self.with_offset,
666 with_offset_alias: self.with_offset_alias.clone(),
667 with_ordinality: self.with_ordinality,
668 })
669 }
670
671 fn create_empty() -> Self {
672 Self {
673 alias: Default::default(),
674 array_exprs: Default::default(),
675 with_offset: Default::default(),
676 with_offset_alias: Default::default(),
677 with_ordinality: Default::default(),
678 }
679 }
680}
681
682impl Default for UnnestRelationBuilder {
683 fn default() -> Self {
684 Self::create_empty()
685 }
686}
687
688#[derive(Debug, Clone)]
691pub struct UninitializedFieldError(&'static str);
692
693impl UninitializedFieldError {
694 pub fn new(field_name: &'static str) -> Self {
696 UninitializedFieldError(field_name)
697 }
698
699 pub fn field_name(&self) -> &'static str {
701 self.0
702 }
703}
704
705impl fmt::Display for UninitializedFieldError {
706 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
707 write!(f, "Field not initialized: {}", self.0)
708 }
709}
710
711impl From<&'static str> for UninitializedFieldError {
712 fn from(field_name: &'static str) -> Self {
713 Self::new(field_name)
714 }
715}
716impl std::error::Error for UninitializedFieldError {}
717
718#[derive(Debug)]
719pub enum BuilderError {
720 UninitializedField(&'static str),
721 ValidationError(String),
722}
723impl From<UninitializedFieldError> for BuilderError {
724 fn from(s: UninitializedFieldError) -> Self {
725 Self::UninitializedField(s.field_name())
726 }
727}
728impl From<String> for BuilderError {
729 fn from(s: String) -> Self {
730 Self::ValidationError(s)
731 }
732}
733impl fmt::Display for BuilderError {
734 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
735 match self {
736 Self::UninitializedField(field) => {
737 write!(f, "`{field}` must be initialized")
738 }
739 Self::ValidationError(error) => write!(f, "{error}"),
740 }
741 }
742}
743impl std::error::Error for BuilderError {}