rust_query/
value.rs

1pub mod aggregate;
2mod operations;
3pub mod optional;
4pub mod trivial;
5
6use std::{cell::OnceCell, fmt::Debug, marker::PhantomData, ops::Deref, rc::Rc};
7
8use sea_query::{Alias, JoinType, Nullable, SelectStatement};
9
10use crate::{
11    IntoSelect, Lazy, Select, Table, Transaction,
12    alias::{Field, JoinableTable, MyAlias, Scope},
13    ast::{MySelect, Source},
14    db::{TableRow, TableRowInner},
15    mutable::Mutable,
16    mymap::MyMap,
17    private::IntoJoinable,
18    schema::canonical,
19};
20
21#[derive(Default)]
22pub struct ValueBuilder {
23    pub(crate) from: Rc<MySelect>,
24    // only used for tables
25    pub(super) scope: Scope,
26    // implicit joins
27    pub(super) extra: MyMap<Source, MyAlias>,
28    // calculating these results
29    pub(super) forwarded: MyMap<MyTableRef, MyAlias>,
30}
31
32impl ValueBuilder {
33    pub(crate) fn get_aggr(
34        &mut self,
35        aggr: Rc<SelectStatement>,
36        conds: Vec<MyTableRef>,
37    ) -> MyAlias {
38        let source = Source {
39            kind: crate::ast::SourceKind::Aggregate(aggr),
40            conds: conds
41                .into_iter()
42                .enumerate()
43                .map(|(idx, join)| {
44                    (
45                        Field::U64(MyAlias::new(idx)),
46                        sea_query::Expr::col((self.get_table(join), Alias::new("id"))),
47                    )
48                })
49                .collect(),
50        };
51        let new_alias = || self.scope.new_alias();
52        *self.extra.get_or_init(source, new_alias)
53    }
54
55    pub(crate) fn get_join<T: Table>(
56        &mut self,
57        expr: sea_query::Expr,
58        possible_null: bool,
59    ) -> MyAlias {
60        let join_type = if possible_null {
61            JoinType::LeftJoin
62        } else {
63            JoinType::Join
64        };
65        let source = Source {
66            kind: crate::ast::SourceKind::Implicit(T::NAME.to_owned(), join_type),
67            conds: vec![(Field::Str(T::ID), expr)],
68        };
69        let new_alias = || self.scope.new_alias();
70
71        // TODO: possible optimization to unify the join_type?
72        // e.g. join + left join = join
73        *self.extra.get_or_init(source, new_alias)
74    }
75
76    pub fn get_unique<T: Table>(
77        &mut self,
78        conds: Box<[(&'static str, sea_query::Expr)]>,
79    ) -> sea_query::Expr {
80        let source = Source {
81            kind: crate::ast::SourceKind::Implicit(T::NAME.to_owned(), JoinType::LeftJoin),
82            conds: conds.into_iter().map(|x| (Field::Str(x.0), x.1)).collect(),
83        };
84
85        let new_alias = || self.scope.new_alias();
86        let table = self.extra.get_or_init(source, new_alias);
87        sea_query::Expr::col((*table, Alias::new(T::ID))).into()
88    }
89
90    pub fn get_table(&mut self, table: MyTableRef) -> MyAlias {
91        if Rc::ptr_eq(&self.from.scope_rc, &table.scope_rc) {
92            MyAlias::new(table.idx)
93        } else {
94            *self.forwarded.get_or_init(table, || self.scope.new_alias())
95        }
96    }
97}
98
99/// This references a particular user specified join,
100/// so not any of the forwarded joins.
101/// We use this to know if the current scope has the original join or needs to forward it.
102#[derive(Clone)]
103pub struct MyTableRef {
104    // one Rc exists for each scope, so we can check if we have the right
105    // scope by comparing the Rc ptr.
106    pub(crate) scope_rc: Rc<()>,
107    pub(crate) idx: usize,
108    pub(crate) table_name: JoinableTable,
109}
110
111impl PartialEq for MyTableRef {
112    fn eq(&self, other: &Self) -> bool {
113        Rc::ptr_eq(&self.scope_rc, &other.scope_rc) && self.idx == other.idx
114    }
115}
116
117pub trait NumTyp: OrdTyp + Clone + Copy {
118    const ZERO: Self;
119    fn into_sea_value(self) -> sea_query::Value;
120}
121
122impl NumTyp for i64 {
123    const ZERO: Self = 0;
124    fn into_sea_value(self) -> sea_query::Value {
125        sea_query::Value::BigInt(Some(self))
126    }
127}
128impl NumTyp for f64 {
129    const ZERO: Self = 0.;
130    fn into_sea_value(self) -> sea_query::Value {
131        sea_query::Value::Double(Some(self))
132    }
133}
134
135pub trait OrdTyp: EqTyp {}
136impl OrdTyp for String {}
137impl OrdTyp for Vec<u8> {}
138impl OrdTyp for i64 {}
139impl OrdTyp for f64 {}
140impl OrdTyp for bool {}
141
142pub trait BuffTyp: MyTyp {}
143impl BuffTyp for String {}
144impl BuffTyp for Vec<u8> {}
145
146#[diagnostic::on_unimplemented(
147    message = "Columns with type `{Self}` can not be checked for equality",
148    note = "`EqTyp` is also implemented for all table types"
149)]
150pub trait EqTyp: MyTyp {}
151
152impl EqTyp for String {}
153impl EqTyp for Vec<u8> {}
154impl EqTyp for i64 {}
155impl EqTyp for f64 {}
156impl EqTyp for bool {}
157#[diagnostic::do_not_recommend]
158impl<T: Table> EqTyp for T {}
159
160/// Typ does not depend on scope, so it gets its own trait
161pub trait Typed {
162    type Typ;
163
164    fn build_expr(&self, b: &mut ValueBuilder) -> sea_query::Expr;
165    fn maybe_optional(&self) -> bool {
166        true
167    }
168
169    fn build_table(&self, b: &mut ValueBuilder) -> MyAlias
170    where
171        Self::Typ: Table,
172    {
173        let expr = self.build_expr(b);
174        b.get_join::<Self::Typ>(expr, self.maybe_optional())
175    }
176}
177
178/// Trait for all values that can be used as expressions in queries.
179///
180/// There is a hierarchy of types that can be used to build queries.
181/// - [TableRow], [i64], [f64], [bool], `&[u8]`, `&str`:
182///   These are the base types for building expressions. They all
183///   implement [IntoExpr] and are [Copy]. Note that [TableRow] is special
184///   because it refers to a table row that is guaranteed to exist.
185/// - [Expr] is the type that all [IntoExpr] values can be converted into.
186///   It has a lot of methods to combine expressions into more complicated expressions.
187///   Next to those, it implements [std::ops::Deref], if the expression is a table expression.
188///   This can be used to get access to the columns of the table, which can themselves be table expressions.
189///   Note that combinators like [crate::optional] and [crate::aggregate] also have [Expr] as return type.
190///
191/// Note that while [Expr] implements [IntoExpr], you may want to use `&Expr` instead.
192/// Using a reference lets you reuse [Expr] without calling [Clone] explicitly.
193pub trait IntoExpr<'column, S> {
194    /// The type of the expression.
195    type Typ: MyTyp;
196
197    /// Turn this value into an [Expr].
198    fn into_expr(self) -> Expr<'column, S, Self::Typ>;
199}
200
201impl<X: MyTyp<Sql: Nullable>> Typed for Option<Rc<dyn Typed<Typ = X>>> {
202    type Typ = Option<X>;
203
204    fn build_expr(&self, b: &mut ValueBuilder) -> sea_query::Expr {
205        self.as_ref()
206            .map(|x| x.build_expr(b))
207            .unwrap_or(X::Sql::null().into())
208    }
209}
210
211impl<'column, S, T: IntoExpr<'column, S, Typ = X>, X: MyTyp<Sql: Nullable>> IntoExpr<'column, S>
212    for Option<T>
213{
214    type Typ = Option<X>;
215    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
216        Expr::new(self.map(|x| x.into_expr().inner))
217    }
218}
219
220impl Typed for String {
221    type Typ = String;
222    fn build_expr(&self, _: &mut ValueBuilder) -> sea_query::Expr {
223        sea_query::Expr::from(self)
224    }
225}
226
227impl<'column, S> IntoExpr<'column, S> for String {
228    type Typ = String;
229    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
230        Expr::new(self)
231    }
232}
233
234impl<'column, S> IntoExpr<'column, S> for &str {
235    type Typ = String;
236    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
237        Expr::new(self.to_owned())
238    }
239}
240
241impl Typed for Vec<u8> {
242    type Typ = Vec<u8>;
243    fn build_expr(&self, _: &mut ValueBuilder) -> sea_query::Expr {
244        sea_query::Expr::from(self.to_owned())
245    }
246}
247
248impl<'column, S> IntoExpr<'column, S> for Vec<u8> {
249    type Typ = Vec<u8>;
250    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
251        Expr::new(self)
252    }
253}
254
255impl<'column, S> IntoExpr<'column, S> for &[u8] {
256    type Typ = Vec<u8>;
257    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
258        Expr::new(self.to_owned())
259    }
260}
261
262impl Typed for bool {
263    type Typ = bool;
264    fn build_expr(&self, _: &mut ValueBuilder) -> sea_query::Expr {
265        sea_query::Expr::from(*self)
266    }
267}
268
269impl<'column, S> IntoExpr<'column, S> for bool {
270    type Typ = bool;
271    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
272        Expr::new(self)
273    }
274}
275
276impl Typed for i64 {
277    type Typ = i64;
278    fn build_expr(&self, _: &mut ValueBuilder) -> sea_query::Expr {
279        sea_query::Expr::from(*self)
280    }
281}
282
283impl<'column, S> IntoExpr<'column, S> for i64 {
284    type Typ = i64;
285    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
286        Expr::new(self)
287    }
288}
289
290impl Typed for f64 {
291    type Typ = f64;
292    fn build_expr(&self, _: &mut ValueBuilder) -> sea_query::Expr {
293        sea_query::Expr::from(*self)
294    }
295}
296
297impl<'column, S> IntoExpr<'column, S> for f64 {
298    type Typ = f64;
299    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
300        Expr::new(self)
301    }
302}
303
304impl<'column, S, T> IntoExpr<'column, S> for &T
305where
306    T: IntoExpr<'column, S> + Clone,
307{
308    type Typ = T::Typ;
309    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
310        T::into_expr(self.clone())
311    }
312}
313
314/// Use this a value in a query to get the current datetime as a number of seconds.
315#[derive(Clone, Copy)]
316#[deprecated = "Use `Expr::unix_epoch` instead"]
317pub struct UnixEpoch;
318
319#[expect(deprecated)]
320impl Typed for UnixEpoch {
321    type Typ = i64;
322    fn build_expr(&self, _: &mut ValueBuilder) -> sea_query::Expr {
323        sea_query::Expr::cust("unixepoch('now')").into()
324    }
325}
326
327#[expect(deprecated)]
328impl<'column, S> IntoExpr<'column, S> for UnixEpoch {
329    type Typ = i64;
330    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
331        Expr::new(self)
332    }
333}
334
335pub trait OptTable: MyTyp {
336    type Schema;
337    type Select;
338    type Mutable<'t>;
339    fn select_opt_mutable(
340        val: Expr<'_, Self::Schema, Self>,
341    ) -> Select<'_, Self::Schema, Self::Select>;
342
343    fn into_mutable<'t>(val: Self::Select) -> Self::Mutable<'t>;
344}
345
346impl<T: Table> OptTable for T {
347    type Schema = T::Schema;
348    type Select = (T::Mutable, TableRow<T>);
349    type Mutable<'t> = Mutable<'t, T>;
350    fn select_opt_mutable(
351        val: Expr<'_, Self::Schema, Self>,
352    ) -> Select<'_, Self::Schema, Self::Select> {
353        (T::select_mutable(val.clone()), val).into_select()
354    }
355
356    fn into_mutable<'t>((inner, row_id): Self::Select) -> Self::Mutable<'t> {
357        Mutable::new(inner, row_id)
358    }
359}
360
361impl<T: Table> OptTable for Option<T> {
362    type Schema = T::Schema;
363    type Select = Option<(T::Mutable, TableRow<T>)>;
364    type Mutable<'t> = Option<Mutable<'t, T>>;
365    fn select_opt_mutable(
366        val: Expr<'_, Self::Schema, Self>,
367    ) -> Select<'_, Self::Schema, Self::Select> {
368        crate::optional(|row| {
369            let val = row.and(val);
370            row.then_select((T::select_mutable(val.clone()), val))
371        })
372    }
373
374    fn into_mutable<'t>(val: Self::Select) -> Self::Mutable<'t> {
375        val.map(T::into_mutable)
376    }
377}
378
379pub trait MyTyp: Sized + 'static {
380    type Prev: MyTyp;
381    const NULLABLE: bool = false;
382    const TYP: canonical::ColumnType;
383    const FK: Option<(&'static str, &'static str)> = None;
384    type Out: SecretFromSql;
385    type Lazy<'t>;
386    type Ext<'t>;
387    type Sql;
388    fn out_to_lazy<'t>(val: Self::Out) -> Self::Lazy<'t>;
389}
390
391pub(crate) trait SecretFromSql: Sized {
392    fn from_sql(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self>;
393}
394
395#[diagnostic::do_not_recommend]
396impl<T: Table> MyTyp for T {
397    type Prev = T::MigrateFrom;
398    const TYP: canonical::ColumnType = canonical::ColumnType::Integer;
399    const FK: Option<(&'static str, &'static str)> = Some((T::NAME, T::ID));
400    type Out = TableRow<T>;
401    type Lazy<'t> = Lazy<'t, T>;
402    type Ext<'t> = T::Ext2<'t>;
403    type Sql = i64;
404    fn out_to_lazy<'t>(val: Self::Out) -> Self::Lazy<'t> {
405        Lazy {
406            id: val,
407            lazy: OnceCell::new(),
408            txn: Transaction::new_ref(),
409        }
410    }
411}
412
413impl<T: Table> SecretFromSql for TableRow<T> {
414    fn from_sql(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
415        Ok(TableRow {
416            _local: PhantomData,
417            inner: TableRowInner {
418                _p: PhantomData,
419                idx: value.as_i64()?,
420            },
421        })
422    }
423}
424
425impl MyTyp for i64 {
426    type Prev = Self;
427    const TYP: canonical::ColumnType = canonical::ColumnType::Integer;
428    type Out = Self;
429    type Lazy<'t> = Self;
430    type Ext<'t> = ();
431    type Sql = i64;
432    fn out_to_lazy<'t>(val: Self::Out) -> Self::Lazy<'t> {
433        val
434    }
435}
436
437impl SecretFromSql for i64 {
438    fn from_sql(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
439        value.as_i64()
440    }
441}
442
443impl MyTyp for f64 {
444    type Prev = Self;
445    const TYP: canonical::ColumnType = canonical::ColumnType::Real;
446    type Out = Self;
447    type Lazy<'t> = Self;
448    type Ext<'t> = ();
449    type Sql = f64;
450    fn out_to_lazy<'t>(val: Self::Out) -> Self::Lazy<'t> {
451        val
452    }
453}
454
455impl SecretFromSql for f64 {
456    fn from_sql(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
457        value.as_f64()
458    }
459}
460
461impl MyTyp for bool {
462    type Prev = Self;
463    const TYP: canonical::ColumnType = canonical::ColumnType::Integer;
464    type Out = Self;
465    type Lazy<'t> = Self;
466    type Ext<'t> = ();
467    type Sql = bool;
468    fn out_to_lazy<'t>(val: Self::Out) -> Self::Lazy<'t> {
469        val
470    }
471}
472
473impl SecretFromSql for bool {
474    fn from_sql(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
475        Ok(value.as_i64()? != 0)
476    }
477}
478
479impl MyTyp for String {
480    type Prev = Self;
481    const TYP: canonical::ColumnType = canonical::ColumnType::Text;
482    type Out = Self;
483    type Lazy<'t> = Self;
484    type Ext<'t> = ();
485    type Sql = String;
486    fn out_to_lazy<'t>(val: Self::Out) -> Self::Lazy<'t> {
487        val
488    }
489}
490assert_impl_all!(String: Nullable);
491
492impl SecretFromSql for String {
493    fn from_sql(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
494        Ok(value.as_str()?.to_owned())
495    }
496}
497
498impl MyTyp for Vec<u8> {
499    type Prev = Self;
500    const TYP: canonical::ColumnType = canonical::ColumnType::Blob;
501    type Out = Self;
502    type Lazy<'t> = Self;
503    type Ext<'t> = ();
504    type Sql = Vec<u8>;
505    fn out_to_lazy<'t>(val: Self::Out) -> Self::Lazy<'t> {
506        val
507    }
508}
509assert_impl_all!(Vec<u8>: Nullable);
510
511impl SecretFromSql for Vec<u8> {
512    fn from_sql(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
513        Ok(value.as_blob()?.to_owned())
514    }
515}
516
517impl<T: MyTyp> MyTyp for Option<T> {
518    type Prev = Option<T::Prev>;
519    const TYP: canonical::ColumnType = T::TYP;
520    const NULLABLE: bool = true;
521    const FK: Option<(&'static str, &'static str)> = T::FK;
522    type Out = Option<T::Out>;
523    type Lazy<'t> = Option<T::Lazy<'t>>;
524    type Ext<'t> = ();
525    type Sql = T::Sql;
526    fn out_to_lazy<'t>(val: Self::Out) -> Self::Lazy<'t> {
527        val.map(T::out_to_lazy)
528    }
529}
530
531impl<T: SecretFromSql> SecretFromSql for Option<T> {
532    fn from_sql(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
533        if value.data_type() == rusqlite::types::Type::Null {
534            Ok(None)
535        } else {
536            Ok(Some(T::from_sql(value)?))
537        }
538    }
539}
540
541/// This is an expression that can be used in queries.
542///
543/// - The lifetime parameter `'column` specifies which columns need to be in scope.
544/// - The type parameter `S` specifies the expected schema of the query.
545/// - And finally the type paramter `T` specifies the type of the expression.
546///
547/// [Expr] implements [Deref] to have column fields in case the expression has a table type.
548pub struct Expr<'column, S, T: MyTyp> {
549    pub(crate) _local: PhantomData<*const ()>,
550    pub(crate) inner: Rc<dyn Typed<Typ = T>>,
551    pub(crate) _p: PhantomData<&'column ()>,
552    pub(crate) _p2: PhantomData<S>,
553    pub(crate) ext: OnceCell<Box<T::Ext<'static>>>,
554}
555
556impl<S, T: MyTyp> Debug for Expr<'_, S, T> {
557    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
558        write!(f, "Expr of type {}", std::any::type_name::<T>())
559    }
560}
561
562impl<'column, S, T: MyTyp> Expr<'column, S, T> {
563    /// Extremely easy to use API. Should only be used by the macro to implement migrations.
564    #[doc(hidden)]
565    pub fn _migrate<OldS>(prev: impl IntoExpr<'column, OldS>) -> Self {
566        Self::new(MigratedExpr {
567            prev: DynTypedExpr::erase(prev),
568            _p: PhantomData,
569        })
570    }
571}
572
573pub fn adhoc_expr<S, T: MyTyp>(
574    f: impl 'static + Fn(&mut ValueBuilder) -> sea_query::Expr,
575) -> Expr<'static, S, T> {
576    Expr::adhoc(f)
577}
578
579pub fn new_column<'x, S, C: MyTyp, T: Table>(
580    table: impl IntoExpr<'x, S, Typ = T>,
581    name: &'static str,
582) -> Expr<'x, S, C> {
583    let table = table.into_expr().inner;
584    let possible_null = table.maybe_optional();
585    Expr::adhoc_promise(
586        move |b| sea_query::Expr::col((table.build_table(b), Field::Str(name))).into(),
587        possible_null,
588    )
589}
590
591pub fn unique_from_joinable<'inner, T: Table>(
592    j: impl IntoJoinable<'inner, T::Schema, Typ = T>,
593) -> Expr<'inner, T::Schema, Option<T>> {
594    let list = j.into_joinable().conds;
595    ::rust_query::private::adhoc_expr(move |_b| {
596        let list = list
597            .iter()
598            .map(|(name, col)| (*name, (col.func)(_b)))
599            .collect();
600        _b.get_unique::<T>(list)
601    })
602}
603
604struct AdHoc<F, T> {
605    func: F,
606    maybe_optional: bool,
607    _p: PhantomData<T>,
608}
609impl<F: Fn(&mut ValueBuilder) -> sea_query::Expr, T> Typed for AdHoc<F, T> {
610    type Typ = T;
611
612    fn build_expr(&self, b: &mut ValueBuilder) -> sea_query::Expr {
613        (self.func)(b)
614    }
615    fn maybe_optional(&self) -> bool {
616        self.maybe_optional
617    }
618}
619
620impl<S, T: MyTyp> Expr<'_, S, T> {
621    pub(crate) fn adhoc(f: impl 'static + Fn(&mut ValueBuilder) -> sea_query::Expr) -> Self {
622        Self::new(AdHoc {
623            func: f,
624            maybe_optional: true,
625            _p: PhantomData,
626        })
627    }
628
629    /// Only set `maybe_optional` to `false` if you are absolutely sure that the
630    /// value is not null. The [crate::optional] combinator makes this more difficult.
631    /// There is no reason to use this for values that can not be foreign keys.
632    /// This is used to optimize implicit joins from LEFT JOIN to just JOIN.
633    pub(crate) fn adhoc_promise(
634        f: impl 'static + Fn(&mut ValueBuilder) -> sea_query::Expr,
635        maybe_optional: bool,
636    ) -> Self {
637        Self::new(AdHoc {
638            func: f,
639            maybe_optional,
640            _p: PhantomData,
641        })
642    }
643
644    pub(crate) fn new(val: impl Typed<Typ = T> + 'static) -> Self {
645        Self {
646            _local: PhantomData,
647            inner: Rc::new(val),
648            _p: PhantomData,
649            _p2: PhantomData,
650            ext: OnceCell::new(),
651        }
652    }
653}
654
655impl<S, T: MyTyp> Clone for Expr<'_, S, T> {
656    fn clone(&self) -> Self {
657        Self {
658            _local: PhantomData,
659            inner: self.inner.clone(),
660            _p: self._p,
661            _p2: self._p2,
662            ext: OnceCell::new(),
663        }
664    }
665}
666
667#[derive(Clone)]
668pub struct DynTypedExpr {
669    pub func: Rc<dyn Fn(&mut ValueBuilder) -> sea_query::Expr>,
670}
671
672impl DynTypedExpr {
673    pub fn new(f: impl 'static + Fn(&mut ValueBuilder) -> sea_query::Expr) -> Self {
674        Self { func: Rc::new(f) }
675    }
676    pub fn erase<'x, S>(expr: impl IntoExpr<'x, S>) -> Self {
677        let typed = expr.into_expr().inner;
678        Self::new(move |b| typed.build_expr(b))
679    }
680}
681
682pub struct MigratedExpr<Typ> {
683    prev: DynTypedExpr,
684    _p: PhantomData<Typ>,
685}
686
687impl<Typ> Typed for MigratedExpr<Typ> {
688    type Typ = Typ;
689    fn build_expr(&self, b: &mut ValueBuilder) -> sea_query::Expr {
690        (self.prev.func)(b)
691    }
692}
693
694impl<'column, S, T: MyTyp> IntoExpr<'column, S> for Expr<'column, S, T> {
695    type Typ = T;
696    fn into_expr(self) -> Expr<'column, S, Self::Typ> {
697        self
698    }
699}
700
701impl<'t, T: Table> Deref for Expr<'t, T::Schema, T> {
702    type Target = T::Ext2<'t>;
703
704    fn deref(&self) -> &Self::Target {
705        T::covariant_ext(self.ext.get_or_init(|| {
706            let expr = Expr {
707                _local: PhantomData,
708                inner: self.inner.clone(),
709                _p: PhantomData::<&'static ()>,
710                _p2: PhantomData,
711                ext: OnceCell::new(),
712            };
713            Box::new(T::build_ext2(&expr))
714        }))
715    }
716}