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 optimizer_hint: None,
319 distinct: self.distinct.clone(),
320 select_modifiers: None,
321 top_before_distinct: false,
322 top: self.top.clone(),
323 projection: self.projection.clone().unwrap_or_default(),
324 into: self.into.clone(),
325 from: self
326 .from
327 .iter()
328 .filter_map(|b| b.build().transpose())
329 .collect::<Result<Vec<_>, BuilderError>>()?,
330 lateral_views: self.lateral_views.clone(),
331 selection: self.selection.clone(),
332 group_by: match self.group_by {
333 Some(ref value) => value.clone(),
334 None => {
335 return Err(Into::into(UninitializedFieldError::from("group_by")));
336 }
337 },
338 cluster_by: self.cluster_by.clone(),
339 distribute_by: self.distribute_by.clone(),
340 sort_by: self.sort_by.clone(),
341 having: self.having.clone(),
342 named_window: self.named_window.clone(),
343 qualify: self.qualify.clone(),
344 value_table_mode: self.value_table_mode,
345 connect_by: Vec::new(),
346 window_before_qualify: false,
347 prewhere: None,
348 select_token: AttachedToken::empty(),
349 flavor: match self.flavor {
350 Some(ref value) => *value,
351 None => return Err(Into::into(UninitializedFieldError::from("flavor"))),
352 },
353 exclude: None,
354 })
355 }
356 fn create_empty() -> Self {
357 Self {
358 distinct: Default::default(),
359 top: Default::default(),
360 projection: None,
361 into: Default::default(),
362 from: Default::default(),
363 lateral_views: Default::default(),
364 selection: Default::default(),
365 group_by: Some(ast::GroupByExpr::Expressions(Vec::new(), Vec::new())),
366 cluster_by: Default::default(),
367 distribute_by: Default::default(),
368 sort_by: Default::default(),
369 having: Default::default(),
370 named_window: Default::default(),
371 qualify: Default::default(),
372 value_table_mode: Default::default(),
373 flavor: Some(SelectFlavor::Standard),
374 }
375 }
376}
377impl Default for SelectBuilder {
378 fn default() -> Self {
379 Self::create_empty()
380 }
381}
382
383#[derive(Clone)]
384pub struct TableWithJoinsBuilder {
385 relation: Option<RelationBuilder>,
386 joins: Vec<ast::Join>,
387}
388
389impl TableWithJoinsBuilder {
390 pub fn relation(&mut self, value: RelationBuilder) -> &mut Self {
391 self.relation = Some(value);
392 self
393 }
394
395 pub fn joins(&mut self, value: Vec<ast::Join>) -> &mut Self {
396 self.joins = value;
397 self
398 }
399 pub fn push_join(&mut self, value: ast::Join) -> &mut Self {
400 self.joins.push(value);
401 self
402 }
403
404 pub fn build(&self) -> Result<Option<ast::TableWithJoins>, BuilderError> {
405 match self.relation {
406 Some(ref value) => match value.build()? {
407 Some(relation) => Ok(Some(ast::TableWithJoins {
408 relation,
409 joins: self.joins.clone(),
410 })),
411 None => Ok(None),
412 },
413 None => Err(Into::into(UninitializedFieldError::from("relation"))),
414 }
415 }
416 fn create_empty() -> Self {
417 Self {
418 relation: Default::default(),
419 joins: Default::default(),
420 }
421 }
422}
423impl Default for TableWithJoinsBuilder {
424 fn default() -> Self {
425 Self::create_empty()
426 }
427}
428
429#[derive(Clone)]
430pub struct RelationBuilder {
431 relation: Option<TableFactorBuilder>,
432}
433
434#[derive(Clone)]
435#[expect(clippy::large_enum_variant)]
436enum TableFactorBuilder {
437 Table(TableRelationBuilder),
438 Derived(DerivedRelationBuilder),
439 Unnest(UnnestRelationBuilder),
440 Empty,
441}
442
443impl RelationBuilder {
444 pub fn has_relation(&self) -> bool {
445 self.relation.is_some()
446 }
447 pub fn table(&mut self, value: TableRelationBuilder) -> &mut Self {
448 self.relation = Some(TableFactorBuilder::Table(value));
449 self
450 }
451 pub fn derived(&mut self, value: DerivedRelationBuilder) -> &mut Self {
452 self.relation = Some(TableFactorBuilder::Derived(value));
453 self
454 }
455
456 pub fn unnest(&mut self, value: UnnestRelationBuilder) -> &mut Self {
457 self.relation = Some(TableFactorBuilder::Unnest(value));
458 self
459 }
460
461 pub fn empty(&mut self) -> &mut Self {
462 self.relation = Some(TableFactorBuilder::Empty);
463 self
464 }
465 pub fn alias(&mut self, value: Option<ast::TableAlias>) -> &mut Self {
466 let new = self;
467 match new.relation {
468 Some(TableFactorBuilder::Table(ref mut rel_builder)) => {
469 rel_builder.alias = value;
470 }
471 Some(TableFactorBuilder::Derived(ref mut rel_builder)) => {
472 rel_builder.alias = value;
473 }
474 Some(TableFactorBuilder::Unnest(ref mut rel_builder)) => {
475 rel_builder.alias = value;
476 }
477 Some(TableFactorBuilder::Empty) => (),
478 None => (),
479 }
480 new
481 }
482 pub fn build(&self) -> Result<Option<ast::TableFactor>, BuilderError> {
483 Ok(match self.relation {
484 Some(TableFactorBuilder::Table(ref value)) => Some(value.build()?),
485 Some(TableFactorBuilder::Derived(ref value)) => Some(value.build()?),
486 Some(TableFactorBuilder::Unnest(ref value)) => Some(value.build()?),
487 Some(TableFactorBuilder::Empty) => None,
488 None => return Err(Into::into(UninitializedFieldError::from("relation"))),
489 })
490 }
491 fn create_empty() -> Self {
492 Self {
493 relation: Default::default(),
494 }
495 }
496}
497impl Default for RelationBuilder {
498 fn default() -> Self {
499 Self::create_empty()
500 }
501}
502
503#[derive(Clone)]
504pub struct TableRelationBuilder {
505 name: Option<ast::ObjectName>,
506 alias: Option<ast::TableAlias>,
507 args: Option<Vec<ast::FunctionArg>>,
508 with_hints: Vec<ast::Expr>,
509 version: Option<ast::TableVersion>,
510 partitions: Vec<ast::Ident>,
511 index_hints: Vec<ast::TableIndexHints>,
512}
513
514impl TableRelationBuilder {
515 pub fn name(&mut self, value: ast::ObjectName) -> &mut Self {
516 self.name = Some(value);
517 self
518 }
519 pub fn alias(&mut self, value: Option<ast::TableAlias>) -> &mut Self {
520 self.alias = value;
521 self
522 }
523 pub fn args(&mut self, value: Option<Vec<ast::FunctionArg>>) -> &mut Self {
524 self.args = value;
525 self
526 }
527 pub fn with_hints(&mut self, value: Vec<ast::Expr>) -> &mut Self {
528 self.with_hints = value;
529 self
530 }
531 pub fn version(&mut self, value: Option<ast::TableVersion>) -> &mut Self {
532 self.version = value;
533 self
534 }
535 pub fn partitions(&mut self, value: Vec<ast::Ident>) -> &mut Self {
536 self.partitions = value;
537 self
538 }
539 pub fn index_hints(&mut self, value: Vec<ast::TableIndexHints>) -> &mut Self {
540 self.index_hints = value;
541 self
542 }
543 pub fn build(&self) -> Result<ast::TableFactor, BuilderError> {
544 Ok(ast::TableFactor::Table {
545 name: match self.name {
546 Some(ref value) => value.clone(),
547 None => return Err(Into::into(UninitializedFieldError::from("name"))),
548 },
549 alias: self.alias.clone(),
550 args: self.args.clone().map(|args| ast::TableFunctionArgs {
551 args,
552 settings: None,
553 }),
554 with_hints: self.with_hints.clone(),
555 version: self.version.clone(),
556 partitions: self.partitions.clone(),
557 with_ordinality: false,
558 json_path: None,
559 sample: None,
560 index_hints: self.index_hints.clone(),
561 })
562 }
563 fn create_empty() -> Self {
564 Self {
565 name: Default::default(),
566 alias: Default::default(),
567 args: Default::default(),
568 with_hints: Default::default(),
569 version: Default::default(),
570 partitions: Default::default(),
571 index_hints: Default::default(),
572 }
573 }
574}
575impl Default for TableRelationBuilder {
576 fn default() -> Self {
577 Self::create_empty()
578 }
579}
580#[derive(Clone)]
581pub struct DerivedRelationBuilder {
582 lateral: Option<bool>,
583 subquery: Option<Box<ast::Query>>,
584 alias: Option<ast::TableAlias>,
585}
586
587impl DerivedRelationBuilder {
588 pub fn lateral(&mut self, value: bool) -> &mut Self {
589 self.lateral = Some(value);
590 self
591 }
592 pub fn subquery(&mut self, value: Box<ast::Query>) -> &mut Self {
593 self.subquery = Some(value);
594 self
595 }
596 pub fn alias(&mut self, value: Option<ast::TableAlias>) -> &mut Self {
597 self.alias = value;
598 self
599 }
600 fn build(&self) -> Result<ast::TableFactor, BuilderError> {
601 Ok(ast::TableFactor::Derived {
602 lateral: match self.lateral {
603 Some(ref value) => *value,
604 None => return Err(Into::into(UninitializedFieldError::from("lateral"))),
605 },
606 subquery: match self.subquery {
607 Some(ref value) => value.clone(),
608 None => {
609 return Err(Into::into(UninitializedFieldError::from("subquery")));
610 }
611 },
612 alias: self.alias.clone(),
613 sample: None,
614 })
615 }
616 fn create_empty() -> Self {
617 Self {
618 lateral: Default::default(),
619 subquery: Default::default(),
620 alias: Default::default(),
621 }
622 }
623}
624impl Default for DerivedRelationBuilder {
625 fn default() -> Self {
626 Self::create_empty()
627 }
628}
629
630#[derive(Clone)]
631pub struct UnnestRelationBuilder {
632 pub alias: Option<ast::TableAlias>,
633 pub array_exprs: Vec<ast::Expr>,
634 with_offset: bool,
635 with_offset_alias: Option<ast::Ident>,
636 with_ordinality: bool,
637}
638
639impl UnnestRelationBuilder {
640 pub fn alias(&mut self, value: Option<ast::TableAlias>) -> &mut Self {
641 self.alias = value;
642 self
643 }
644 pub fn array_exprs(&mut self, value: Vec<ast::Expr>) -> &mut Self {
645 self.array_exprs = value;
646 self
647 }
648
649 pub fn with_offset(&mut self, value: bool) -> &mut Self {
650 self.with_offset = value;
651 self
652 }
653
654 pub fn with_offset_alias(&mut self, value: Option<ast::Ident>) -> &mut Self {
655 self.with_offset_alias = value;
656 self
657 }
658
659 pub fn with_ordinality(&mut self, value: bool) -> &mut Self {
660 self.with_ordinality = value;
661 self
662 }
663
664 pub fn build(&self) -> Result<ast::TableFactor, BuilderError> {
665 Ok(ast::TableFactor::UNNEST {
666 alias: self.alias.clone(),
667 array_exprs: self.array_exprs.clone(),
668 with_offset: self.with_offset,
669 with_offset_alias: self.with_offset_alias.clone(),
670 with_ordinality: self.with_ordinality,
671 })
672 }
673
674 fn create_empty() -> Self {
675 Self {
676 alias: Default::default(),
677 array_exprs: Default::default(),
678 with_offset: Default::default(),
679 with_offset_alias: Default::default(),
680 with_ordinality: Default::default(),
681 }
682 }
683}
684
685impl Default for UnnestRelationBuilder {
686 fn default() -> Self {
687 Self::create_empty()
688 }
689}
690
691#[derive(Debug, Clone)]
694pub struct UninitializedFieldError(&'static str);
695
696impl UninitializedFieldError {
697 pub fn new(field_name: &'static str) -> Self {
699 UninitializedFieldError(field_name)
700 }
701
702 pub fn field_name(&self) -> &'static str {
704 self.0
705 }
706}
707
708impl fmt::Display for UninitializedFieldError {
709 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
710 write!(f, "Field not initialized: {}", self.0)
711 }
712}
713
714impl From<&'static str> for UninitializedFieldError {
715 fn from(field_name: &'static str) -> Self {
716 Self::new(field_name)
717 }
718}
719impl std::error::Error for UninitializedFieldError {}
720
721#[derive(Debug)]
722pub enum BuilderError {
723 UninitializedField(&'static str),
724 ValidationError(String),
725}
726impl From<UninitializedFieldError> for BuilderError {
727 fn from(s: UninitializedFieldError) -> Self {
728 Self::UninitializedField(s.field_name())
729 }
730}
731impl From<String> for BuilderError {
732 fn from(s: String) -> Self {
733 Self::ValidationError(s)
734 }
735}
736impl fmt::Display for BuilderError {
737 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
738 match self {
739 Self::UninitializedField(field) => {
740 write!(f, "`{field}` must be initialized")
741 }
742 Self::ValidationError(error) => write!(f, "{error}"),
743 }
744 }
745}
746impl std::error::Error for BuilderError {}