sql_fun_sqlast/sem/scalar_expr/
cast_expr.rs1use sql_fun_core::IVec;
2
3use crate::{
4 sem::{
5 AnalysisError, AnalysisProblem, FromClause, FullName, ParseContext, SemScalarExpr,
6 TypeReference, WithClause, analyze_scaler_expr,
7 },
8 syn::{Opt, ScanToken},
9};
10
11use super::{AnalyzeScalarExpr, SemScalarExprNode};
12
13#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
15pub struct ImplicitCastExpr {
16 value: Box<SemScalarExpr>,
17 cast_target: TypeReference,
18}
19
20impl ImplicitCastExpr {
21 #[must_use]
23 pub fn new(value: &SemScalarExpr, cast_target: &TypeReference) -> Self {
24 Self {
25 value: Box::new(value.clone()),
26 cast_target: cast_target.clone(),
27 }
28 }
29}
30
31impl SemScalarExprNode for ImplicitCastExpr {
32 fn get_type(&self) -> Option<TypeReference> {
33 Some(self.cast_target.clone())
34 }
35
36 fn is_not_null(&self) -> Option<bool> {
37 self.value.is_not_null()
38 }
39}
40
41#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
43pub struct TypeCastExpr {
44 target_type: TypeReference,
45 arg: Box<SemScalarExpr>,
46}
47
48impl TypeCastExpr {
49 fn new(target_type: TypeReference, arg: SemScalarExpr) -> TypeCastExpr {
50 Self {
51 target_type,
52 arg: Box::new(arg),
53 }
54 }
55}
56
57impl SemScalarExprNode for TypeCastExpr {
58 fn get_type(&self) -> Option<TypeReference> {
59 Some(self.target_type.clone())
60 }
61
62 fn is_not_null(&self) -> Option<bool> {
63 self.arg.is_not_null()
64 }
65}
66
67impl<TParseContext> AnalyzeScalarExpr<TParseContext, crate::syn::TypeCast> for TypeCastExpr
68where
69 TParseContext: ParseContext,
70{
71 fn analyze_scalar_expr(
72 mut context: TParseContext,
73 with_clause: &WithClause,
74 from_clause: &FromClause,
75 syn: crate::syn::TypeCast,
76 tokens: &IVec<ScanToken>,
77 ) -> Result<(SemScalarExpr, TParseContext), AnalysisError> {
78 let Some(arg) = syn.get_arg().as_inner() else {
79 AnalysisError::raise_unexpected_none("typecast.arg")?
80 };
81 let Some(target_type) = syn.get_type_name().as_inner() else {
82 AnalysisError::raise_unexpected_none("typecast.type_name")?
83 };
84 let target_type = TypeReference::from_full_name(FullName::try_from(target_type)?);
85
86 let (arg, new_context) =
87 analyze_scaler_expr(context, with_clause, from_clause, arg, tokens)?;
88 context = new_context;
89
90 if let Some(from_type) = arg.get_type() {
91 let cast = context.get_explicit_cast(&from_type, &target_type);
92 if cast.is_none() {
93 context.report_problem(AnalysisProblem::explicit_cast_not_defined(
94 &from_type,
95 &target_type,
96 ))?;
97 }
98 }
99
100 Ok((
101 SemScalarExpr::TypeCast(Self::new(target_type, arg)),
102 context,
103 ))
104 }
105}