sql_fun_sqlast/sem/scalar_expr/
const_expr.rs1use sql_fun_core::IVec;
2
3use crate::{
4 sem::{
5 AnalysisError, FromClause, ParseContext, PgBuiltInType, SemScalarExpr, TypeReference,
6 WithClause,
7 },
8 syn::ScanToken,
9};
10
11use super::{AnalyzeScalarExpr, SemScalarExprNode};
12
13#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
15pub enum ScalarConstExpr {
16 Integer(i32),
18 Float(String),
20 Bool(bool),
22 String(String),
24 BitString(String),
26 Null,
28}
29
30impl ScalarConstExpr {
31 #[must_use]
33 pub fn null() -> SemScalarExpr {
34 SemScalarExpr::Const(Self::Null)
35 }
36
37 #[must_use]
39 pub fn new_integer(value: i32) -> Self {
40 Self::Integer(value)
41 }
42}
43
44impl<TParseContext> AnalyzeScalarExpr<TParseContext, crate::syn::AConst> for ScalarConstExpr
45where
46 TParseContext: ParseContext,
47{
48 fn analyze_scalar_expr(
49 context: TParseContext,
50 _with_clause: &WithClause,
51 _from_clause: &FromClause,
52 syn: crate::syn::AConst,
53 _tokens: &IVec<ScanToken>,
54 ) -> Result<(SemScalarExpr, TParseContext), AnalysisError> {
55 let cval = if let Some(ival) = syn.as_ival().get_ival() {
56 ScalarConstExpr::Integer(ival)
57 } else if let Some(fval) = syn.as_fval().get_fval() {
58 ScalarConstExpr::Float(fval)
59 } else if let Some(bval) = syn.as_boolval().get_boolval() {
60 ScalarConstExpr::Bool(bval)
61 } else if let Some(sval) = syn.as_sval().get_sval() {
62 ScalarConstExpr::String(sval)
63 } else if let Some(bsval) = syn.as_bsval().get_bsval() {
64 ScalarConstExpr::BitString(bsval)
65 } else {
66 AnalysisError::raise_unexpected_none("AConst: unknown variant")?
67 };
68 Ok((SemScalarExpr::Const(cval), context))
69 }
70}
71
72impl SemScalarExprNode for ScalarConstExpr {
73 fn get_type(&self) -> Option<TypeReference> {
74 match self {
75 ScalarConstExpr::Integer(_) => Some(PgBuiltInType::int4()),
76 ScalarConstExpr::Float(_) => Some(PgBuiltInType::numeric()),
77 ScalarConstExpr::Bool(_) => Some(PgBuiltInType::bool()),
78 ScalarConstExpr::String(_) => Some(PgBuiltInType::text()),
79 ScalarConstExpr::BitString(_) => Some(PgBuiltInType::varbit()),
80 ScalarConstExpr::Null => None,
81 }
82 }
83
84 fn is_not_null(&self) -> Option<bool> {
85 if matches!(self, Self::Null) {
86 Some(false)
87 } else {
88 Some(true)
89 }
90 }
91}