1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//! Shared macro for dialect CTE view types.
/// Generate dialect-specific `CTEDefinition` and `CTEView` types.
#[macro_export]
macro_rules! impl_cte_types {
(value_type: $ValueType:ty $(,)?) => {
/// Trait for types that can provide a CTE definition for WITH clauses.
pub trait CTEDefinition<'a> {
/// Returns the SQL for the CTE definition (e.g., `cte_name AS (SELECT ...)`).
fn cte_definition(&self) -> $crate::SQL<'a, $ValueType>;
}
/// A CTE (Common Table Expression) view with typed table projection.
#[derive(Clone, Debug)]
pub struct CTEView<'a, Table, Query> {
/// The aliased table for typed field access.
pub table: Table,
/// The CTE name.
name: &'static str,
/// The defining query.
query: Query,
_phantom: ::core::marker::PhantomData<$ValueType>,
}
impl<'a, Table, Query> CTEView<'a, Table, Query>
where
Query: $crate::ToSQL<'a, $ValueType>,
{
/// Creates a new `CTEView`.
pub const fn new(table: Table, name: &'static str, query: Query) -> Self {
Self {
table,
name,
query,
_phantom: ::core::marker::PhantomData,
}
}
/// Returns the CTE name.
pub const fn cte_name(&self) -> &'static str {
self.name
}
/// Returns a reference to the underlying query.
pub const fn query(&self) -> &Query {
&self.query
}
}
impl<'a, Table, Query> CTEDefinition<'a> for CTEView<'a, Table, Query>
where
Query: $crate::ToSQL<'a, $ValueType>,
{
fn cte_definition(&self) -> $crate::SQL<'a, $ValueType> {
$crate::SQL::raw(self.name)
.push($crate::Token::AS)
.append(self.query.to_sql().parens())
}
}
impl<'a, Table, Query> CTEDefinition<'a> for &CTEView<'a, Table, Query>
where
Query: $crate::ToSQL<'a, $ValueType>,
{
fn cte_definition(&self) -> $crate::SQL<'a, $ValueType> {
$crate::SQL::raw(self.name)
.push($crate::Token::AS)
.append(self.query.to_sql().parens())
}
}
impl<'a, Table, Query> ::core::ops::Deref for CTEView<'a, Table, Query> {
type Target = Table;
fn deref(&self) -> &Self::Target {
&self.table
}
}
impl<'a, Table, Query> $crate::ToSQL<'a, $ValueType> for CTEView<'a, Table, Query>
where
Query: $crate::ToSQL<'a, $ValueType>,
{
fn to_sql(&self) -> $crate::SQL<'a, $ValueType> {
$crate::SQL::ident(self.name)
}
}
};
}