Skip to main content

sql_fun_sqlast/sem/scalar_expr/
const_expr.rs

1use 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/// constant expression
14#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
15pub enum ScalarConstExpr {
16    /// integer value constant
17    Integer(i32),
18    /// floating numeric value constant
19    Float(String),
20    /// boolean constant value
21    Bool(bool),
22    /// string constant value
23    String(String),
24    /// bit-string constant
25    BitString(String),
26    /// NULL constant
27    Null,
28}
29
30impl ScalarConstExpr {
31    /// create a NULL
32    #[must_use]
33    pub fn null() -> SemScalarExpr {
34        SemScalarExpr::Const(Self::Null)
35    }
36
37    /// create integer constant value
38    #[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}