Skip to main content

uqa_sql/semantics/
sets.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Set-returning expression binding, validation, and dependency rewriting.
8
9use crate::ast::FunctionBinding;
10use crate::plan::{AggregateClassifier, ProjectionTarget, QueryBlockPlan};
11use crate::routines::RoutineResolution;
12use crate::{RowSchema, SQLError, SQLParam, ScalarExpr};
13
14/// Routine metadata and aggregate classification required by set-returning expression analysis.
15pub trait SetFunctionCatalog: RoutineResolution + AggregateClassifier {}
16impl<T: RoutineResolution + AggregateClassifier + ?Sized> SetFunctionCatalog for T {}
17
18pub type PhysicalProjection = (ProjectionTarget, ScalarExpr);
19
20pub mod rewrite;
21pub mod validation;
22use rewrite::rewrite_set_calls;
23
24#[derive(Clone)]
25pub struct SetFunctionCall {
26    pub placeholder: crate::ast::InternalColumnRef,
27    pub name: String,
28    pub binding: Option<FunctionBinding>,
29    pub args: Vec<ScalarExpr>,
30    pub level: usize,
31}
32
33pub struct SetProjectionPlan {
34    pub projections: Vec<PhysicalProjection>,
35    pub calls: Vec<SetFunctionCall>,
36}
37
38pub struct AggregateOutputProjectionPlan {
39    pub statement: QueryBlockPlan,
40    pub projections: Vec<PhysicalProjection>,
41}
42
43pub struct GroupSetProjectionPlan {
44    pub statement: QueryBlockPlan,
45    pub projections: Vec<PhysicalProjection>,
46}
47
48impl SetProjectionPlan {
49    pub fn new(
50        engine: &dyn SetFunctionCatalog,
51        resolver: &dyn crate::FunctionTypeResolver,
52        projections: Vec<PhysicalProjection>,
53        schema: &RowSchema,
54        params: &[SQLParam],
55    ) -> Result<Self, SQLError> {
56        let mut calls = Vec::new();
57        let call_relation = crate::ast::InternalRelationId::allocate();
58        let projections = projections
59            .into_iter()
60            .map(|(target, expression)| {
61                Ok((
62                    target,
63                    rewrite_set_calls(
64                        engine,
65                        resolver,
66                        expression,
67                        &mut calls,
68                        call_relation,
69                        schema,
70                        params,
71                    )?,
72                ))
73            })
74            .collect::<Result<Vec<_>, SQLError>>()?;
75        debug_assert!(!calls.is_empty());
76        Ok(Self { projections, calls })
77    }
78}
79
80pub mod static_setness;