Skip to main content

sql_fun_sqlast/sem/scalar_expr/
case_expr.rs

1use std::collections::{HashMap, HashSet};
2
3use sql_fun_core::IVec;
4
5use crate::{
6    sem::{
7        AnalysisError, AnalysisProblem, FromClause, ParseContext, SemScalarExpr, TypeReference,
8        WithClause, analyze_scaler_expr,
9        scalar_expr::{AnalyzeScalarExpr, SemScalarExprNode},
10    },
11    syn::{ListOpt as _, Opt, ScanToken},
12};
13
14pub struct CaseExprAnalysisContext<'a> {
15    with_clause: &'a WithClause,
16    from_clause: &'a FromClause,
17    case_arg: Option<SemScalarExpr>,
18    nullabilities: Vec<Option<bool>>,
19    when_exprs: Vec<CaseWhen>,
20    result_types: HashSet<TypeReference>,
21    default_expr: Option<SemScalarExpr>,
22}
23
24impl<'a> CaseExprAnalysisContext<'a> {
25    fn new(with_clause: &'a WithClause, from_clause: &'a FromClause) -> Self {
26        Self {
27            with_clause,
28            from_clause,
29            case_arg: None,
30            nullabilities: Default::default(),
31            when_exprs: Default::default(),
32            result_types: Default::default(),
33            default_expr: None,
34        }
35    }
36}
37
38#[cfg(test)]
39mod test_case_expr_analysis_context_new {
40    use crate::sem::{FromClause, WithClause};
41
42    #[test]
43    pub fn test_case_expr_analysis_context_new() {
44        let with_clause = WithClause::default();
45        let from_clause = FromClause::default();
46        let _ = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
47    }
48}
49
50impl CaseExprAnalysisContext<'_> {
51    fn analyze_case_arg<TParseContext>(
52        &mut self,
53        context: TParseContext,
54        syn: &crate::syn::CaseExpr,
55        tokens: &IVec<ScanToken>,
56    ) -> Result<TParseContext, AnalysisError>
57    where
58        TParseContext: ParseContext,
59    {
60        if let Some(arg) = syn.get_arg().as_inner() {
61            let (arg_expr, new_context) =
62                analyze_scaler_expr(context, self.with_clause, self.from_clause, arg, tokens)?;
63            self.case_arg = Some(arg_expr);
64            Ok(new_context)
65        } else {
66            Ok(context)
67        }
68    }
69}
70
71#[cfg(test)]
72mod test_case_expr_analysis_context_analyze_case_arg {
73    use sql_fun_core::IVec;
74    use testresult::TestResult;
75
76    use crate::{
77        sem::{FromClause, WithClause},
78        syn::{Node, NodeInner, NodeList},
79        test_helpers::{SynBuilder, TestParseContext, test_context},
80    };
81
82    #[rstest::rstest]
83    fn test_analyze_case_arg_none(test_context: TestParseContext) -> TestResult {
84        let with_clause = WithClause::default();
85        let from_clause = FromClause::default();
86        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
87
88        let builder = SynBuilder::new();
89        let case_expr = builder.case_expr(Node::none(), NodeList::default(), Node::none());
90        let tokens = IVec::default();
91        let _new_context = acontext.analyze_case_arg(test_context, &case_expr, &tokens)?;
92        assert!(acontext.case_arg.is_none());
93        Ok(())
94    }
95
96    #[rstest::rstest]
97    fn test_analyze_case_arg_some(test_context: TestParseContext) -> TestResult {
98        let with_clause = WithClause::default();
99        let from_clause = FromClause::default();
100        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
101
102        let builder = SynBuilder::new();
103        let arg_expr = NodeInner::AConst(builder.const_int4(10));
104        let case_expr = builder.case_expr(arg_expr.into(), NodeList::default(), Node::none());
105        let tokens = IVec::default();
106        let _new_context = acontext.analyze_case_arg(test_context, &case_expr, &tokens)?;
107        assert!(acontext.case_arg.is_some());
108        Ok(())
109    }
110}
111
112impl CaseExprAnalysisContext<'_> {
113    fn analyze_case_when<TParseContext>(
114        &self,
115        mut context: TParseContext,
116        syn: crate::syn::CaseWhen,
117        tokens: &IVec<ScanToken>,
118    ) -> Result<(CaseWhen, TParseContext), AnalysisError>
119    where
120        TParseContext: ParseContext,
121    {
122        let Some(when_value) = syn.get_expr().as_inner() else {
123            AnalysisError::raise_unexpected_none("casewhen.expr")?
124        };
125        let Some(result) = syn.get_result().as_inner() else {
126            AnalysisError::raise_unexpected_none("casewhen.result")?
127        };
128        let (when_value, new_context) = analyze_scaler_expr(
129            context,
130            self.with_clause,
131            self.from_clause,
132            when_value,
133            tokens,
134        )?;
135        context = new_context;
136        let (result, new_context) =
137            analyze_scaler_expr(context, self.with_clause, self.from_clause, result, tokens)?;
138        context = new_context;
139        Ok((CaseWhen::new(when_value, result), context))
140    }
141}
142
143#[cfg(test)]
144mod test_case_expr_analysis_context_analyze_case_when {
145    use sql_fun_core::IVec;
146    use testresult::TestResult;
147
148    use crate::{
149        sem::{FromClause, ScalarConstExpr, SemScalarExpr, WithClause},
150        syn::NodeInner,
151        test_helpers::{SynBuilder, TestParseContext, test_context},
152    };
153
154    #[rstest::rstest]
155    fn test_analyze_case_when(test_context: TestParseContext) -> TestResult {
156        let with_clause = WithClause::default();
157        let from_clause = FromClause::default();
158        let acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
159
160        let builder = SynBuilder::new();
161        let expr = NodeInner::AConst(builder.const_int4(10));
162        let result = NodeInner::AConst(builder.const_int4(20));
163        let case_when = builder.case_when(expr.into(), result.into());
164        let tokens = IVec::default();
165        let (sem_case_when, _) = acontext.analyze_case_when(test_context, case_when, &tokens)?;
166        let SemScalarExpr::Const(ScalarConstExpr::Integer(expr_value)) = sem_case_when.when_value
167        else {
168            panic!("unexpected when_value {sem_case_when:?}")
169        };
170        assert_eq!(10, expr_value);
171        let SemScalarExpr::Const(ScalarConstExpr::Integer(result_value)) = sem_case_when.result
172        else {
173            panic!("unexpected result {sem_case_when:?}")
174        };
175        assert_eq!(20, result_value);
176        Ok(())
177    }
178}
179
180impl CaseExprAnalysisContext<'_> {
181    fn analyze_case_when_list<TParseContext>(
182        &mut self,
183        mut context: TParseContext,
184        args: Vec<crate::syn::CaseWhen>,
185        tokens: &IVec<ScanToken>,
186    ) -> Result<TParseContext, AnalysisError>
187    where
188        TParseContext: ParseContext,
189    {
190        for arg in args {
191            let (when_expr, new_context) = self.analyze_case_when(context, arg, tokens)?;
192            context = new_context;
193
194            if let Some(result_type) = when_expr.result.get_type() {
195                if result_type.is_dynamic() {
196                    self.result_types.insert(result_type);
197                } else if let Some(result_type) = context.canonicalize_type_ref(&result_type) {
198                    self.result_types.insert(result_type);
199                } else {
200                    context.report_problem(AnalysisProblem::expression_type_not_known(
201                        &when_expr.result,
202                    ))?;
203                }
204            } else {
205                context.report_problem(AnalysisProblem::case_when_type_unknown(
206                    when_expr.result.clone(),
207                ))?;
208            }
209
210            self.nullabilities.push(when_expr.result.is_not_null());
211            self.when_exprs.push(when_expr);
212        }
213        Ok(context)
214    }
215}
216
217#[cfg(test)]
218mod test_case_expr_analysis_context_analyze_case_when_list {
219    use crate::{
220        sem::{FromClause, PgBuiltInType, WithClause},
221        syn::NodeInner,
222        test_helpers::{SynBuilder, TestParseContext, test_context},
223    };
224    use sql_fun_core::IVec;
225    use testresult::TestResult;
226
227    #[rstest::rstest]
228    fn test_analyze_case_when_list(mut test_context: TestParseContext) -> TestResult {
229        test_context.setup_type(PgBuiltInType::int4());
230        test_context.setup_type(PgBuiltInType::text());
231
232        let with_clause = WithClause::default();
233        let from_clause = FromClause::default();
234        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
235
236        let builder = SynBuilder::new();
237
238        let expr = NodeInner::AConst(builder.const_int4(10));
239        let result = NodeInner::AConst(builder.const_int4(20));
240        let case_when_int = builder.case_when(expr.into(), result.into());
241
242        let expr = NodeInner::AConst(builder.const_sval("a"));
243        let result = NodeInner::AConst(builder.const_sval("b"));
244        let case_when_sval = builder.case_when(expr.into(), result.into());
245
246        let when_values = vec![case_when_int, case_when_sval];
247        let tokens = IVec::default();
248
249        let _ = acontext.analyze_case_when_list(test_context, when_values, &tokens)?;
250        assert_eq!(acontext.result_types.len(), 2);
251        assert_eq!(acontext.nullabilities.len(), 2);
252        assert_eq!(acontext.when_exprs.len(), 2);
253        Ok(())
254    }
255}
256
257impl CaseExprAnalysisContext<'_> {
258    fn analyze_default_expr<TParseContext>(
259        &mut self,
260        mut context: TParseContext,
261        syn: crate::syn::CaseExpr,
262        tokens: &IVec<ScanToken>,
263    ) -> Result<TParseContext, AnalysisError>
264    where
265        TParseContext: ParseContext,
266    {
267        let Some(def_result) = syn.get_defresult().as_inner() else {
268            return Ok(context);
269        };
270
271        let (default_expr, new_context) = analyze_scaler_expr(
272            context,
273            self.with_clause,
274            self.from_clause,
275            def_result,
276            tokens,
277        )?;
278        context = new_context;
279
280        if let Some(default_result_type) = default_expr.get_type() {
281            if default_result_type.is_dynamic() {
282                self.result_types.insert(default_result_type);
283            } else if let Some(default_result_type) =
284                context.canonicalize_type_ref(&default_result_type)
285            {
286                self.result_types.insert(default_result_type);
287            } else {
288                context
289                    .report_problem(AnalysisProblem::expression_type_not_known(&default_expr))?;
290            }
291        } else {
292            context.report_problem(AnalysisProblem::case_when_type_unknown(
293                default_expr.clone(),
294            ))?;
295        }
296        self.nullabilities.push(default_expr.is_not_null());
297        self.default_expr = Some(default_expr);
298        Ok(context)
299    }
300}
301
302#[cfg(test)]
303mod test_case_expr_analysis_context_analyze_default_expr {
304    use crate::{
305        sem::{FromClause, PgBuiltInType, WithClause},
306        syn::{Node, NodeInner, NodeList},
307        test_helpers::{SynBuilder, TestParseContext, test_context},
308    };
309    use sql_fun_core::IVec;
310    use testresult::TestResult;
311
312    #[rstest::rstest]
313    fn test_analyze_default_expr_none(test_context: TestParseContext) -> TestResult {
314        let with_clause = WithClause::default();
315        let from_clause = FromClause::default();
316        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
317
318        let builder = SynBuilder::new();
319        let case_expr = builder.case_expr(Node::none(), NodeList::default(), Node::none());
320        let tokens = IVec::default();
321        let _new_context = acontext.analyze_default_expr(test_context, case_expr, &tokens)?;
322        assert!(acontext.default_expr.is_none());
323        Ok(())
324    }
325
326    #[rstest::rstest]
327    fn test_analyze_default_expr_some(mut test_context: TestParseContext) -> TestResult {
328        test_context.setup_type(PgBuiltInType::int4());
329        let with_clause = WithClause::default();
330        let from_clause = FromClause::default();
331        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
332        let builder = SynBuilder::new();
333        let expr = NodeInner::AConst(builder.const_int4(10));
334        let case_expr = builder.case_expr(Node::none(), NodeList::default(), expr.into());
335        let tokens = IVec::default();
336        let _new_context = acontext.analyze_default_expr(test_context, case_expr, &tokens)?;
337
338        assert!(acontext.default_expr.is_some());
339        Ok(())
340    }
341}
342
343impl CaseExprAnalysisContext<'_> {
344    fn cast_args<TParseContext>(
345        &mut self,
346        context: &mut TParseContext,
347        result_type: &TypeReference,
348    ) -> Result<Option<TypeReference>, AnalysisError>
349    where
350        TParseContext: ParseContext,
351    {
352        for when_expr in &mut self.when_exprs {
353            let Some(_ty) = when_expr.result.get_type() else {
354                continue;
355            };
356            SemScalarExpr::implicit_cast_if_require(context, result_type, &mut when_expr.result)?;
357        }
358        if let Some(default) = self.default_expr.as_mut() {
359            SemScalarExpr::implicit_cast_if_require(context, result_type, default)?;
360        }
361
362        Ok(Some(result_type.clone()))
363    }
364}
365
366impl CaseExprAnalysisContext<'_> {
367    fn type_fixup<TParseContext>(
368        &mut self,
369        context: &mut TParseContext,
370    ) -> Result<Option<TypeReference>, AnalysisError>
371    where
372        TParseContext: ParseContext,
373    {
374        if self.result_types.len() == 1 {
375            return Ok(self.result_types.iter().next().cloned());
376        }
377
378        let cast_candiates = self.enumerate_cast_candiates(context);
379        if cast_candiates.is_empty() {
380            context.report_problem(AnalysisProblem::incompatible_case_values(
381                self.result_types.clone(),
382            ))?;
383            Ok(None)
384        } else if cast_candiates.len() == 1 {
385            let Some((result_type, _casts)) = cast_candiates.into_iter().next() else {
386                AnalysisError::raise_unexpected_none("cast candiates")?
387            };
388            Ok(self.cast_args(context, &result_type)?)
389        } else {
390            let mut implicit_castable = Vec::new();
391            for (ty, _casts) in cast_candiates {
392                if self
393                    .result_types
394                    .iter()
395                    .all(|t| context.get_implicit_cast(t, &ty).is_some())
396                {
397                    implicit_castable.push(ty);
398                }
399            }
400
401            if implicit_castable.len() == 1 {
402                Ok(implicit_castable.into_iter().next())
403            } else {
404                todo!("{implicit_castable:#?}");
405            }
406        }
407    }
408}
409
410#[cfg(test)]
411mod test_case_expr_analysis_context_type_fixup {
412    use sql_fun_core::IVec;
413    use testresult::TestResult;
414
415    use super::SemScalarExprNode;
416    use crate::{
417        sem::{CastContext, CastDefinition, FromClause, PgBuiltInType, SemScalarExpr, WithClause},
418        syn::NodeInner,
419        test_helpers::{SynBuilder, TestParseContext, test_context},
420    };
421
422    #[rstest::rstest]
423    fn test_type_fixup_with_implicit_cast(mut test_context: TestParseContext) -> TestResult {
424        test_context.setup_type(PgBuiltInType::int4());
425        test_context.setup_type(PgBuiltInType::text());
426        let int4 = PgBuiltInType::int4();
427        let text = PgBuiltInType::text();
428        test_context.set_get_implicit_cast_result(
429            &int4,
430            &text,
431            Some(CastDefinition::new(CastContext::Implicit)),
432        );
433
434        let with_clause = WithClause::default();
435        let from_clause = FromClause::default();
436        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
437
438        let builder = SynBuilder::new();
439        let expr = NodeInner::AConst(builder.const_int4(1));
440        let result = NodeInner::AConst(builder.const_int4(10));
441        let when_int = builder.case_when(expr.into(), result.into());
442
443        let expr = NodeInner::AConst(builder.const_sval("a"));
444        let result = NodeInner::AConst(builder.const_sval("b"));
445        let when_text = builder.case_when(expr.into(), result.into());
446
447        let tokens = IVec::default();
448        let mut context =
449            acontext.analyze_case_when_list(test_context, vec![when_int, when_text], &tokens)?;
450        let result_type = acontext.type_fixup(&mut context)?;
451        assert_eq!(Some(text.clone()), result_type);
452
453        match &acontext.when_exprs[0].result {
454            SemScalarExpr::ImplicitCast(cast_expr) => {
455                assert_eq!(Some(text.clone()), cast_expr.get_type());
456            }
457            other => panic!("expected implicit cast, got {other:?}"),
458        }
459
460        match &acontext.when_exprs[1].result {
461            SemScalarExpr::Const(_) => {}
462            other => panic!("expected const, got {other:?}"),
463        }
464        Ok(())
465    }
466
467    #[rstest::rstest]
468    fn test_type_fixup_no_cast_candidates(mut test_context: TestParseContext) -> TestResult {
469        let int4 = PgBuiltInType::int4();
470        let text = PgBuiltInType::text();
471        test_context.setup_type(int4.clone());
472        test_context.setup_type(text.clone());
473
474        let with_clause = WithClause::default();
475        let from_clause = FromClause::default();
476        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
477        acontext.result_types.insert(int4);
478        acontext.result_types.insert(text);
479
480        let result = acontext.type_fixup(&mut test_context)?;
481        assert!(result.is_none());
482        assert_eq!(1, test_context.reported_problem_count());
483        Ok(())
484    }
485}
486
487impl CaseExprAnalysisContext<'_> {
488    fn enumerate_cast_candiates<TParseContext>(
489        &mut self,
490        context: &mut TParseContext,
491    ) -> HashMap<TypeReference, Vec<crate::sem::CastDefinition>>
492    where
493        TParseContext: ParseContext,
494    {
495        let mut cast_candiates = HashMap::new();
496        for ty1 in self.result_types.clone() {
497            for ty2 in self.result_types.clone() {
498                if ty1 == ty2 {
499                    continue;
500                }
501                let Some(cast) = context.get_implicit_cast(&ty1, &ty2) else {
502                    continue;
503                };
504                cast_candiates
505                    .entry(ty2)
506                    .and_modify(|v: &mut Vec<_>| v.push(cast.clone()))
507                    .or_insert(vec![cast.clone()]);
508            }
509        }
510        cast_candiates
511    }
512}
513
514#[cfg(test)]
515mod test_case_expr_analysis_context_enumerate_cast_candiates {
516    use testresult::TestResult;
517
518    use crate::{
519        sem::{CastContext, CastDefinition, FromClause, PgBuiltInType, WithClause},
520        test_helpers::{TestParseContext, test_context},
521    };
522
523    #[rstest::rstest]
524    fn test_enumerate_cast_candiates_single(mut test_context: TestParseContext) -> TestResult {
525        let int4 = PgBuiltInType::int4();
526        let text = PgBuiltInType::text();
527        test_context.setup_type(int4.clone());
528        test_context.setup_type(text.clone());
529        test_context.set_get_implicit_cast_result(
530            &int4,
531            &text,
532            Some(CastDefinition::new(CastContext::Implicit)),
533        );
534
535        let with_clause = WithClause::default();
536        let from_clause = FromClause::default();
537        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
538        acontext.result_types.insert(int4);
539        acontext.result_types.insert(text.clone());
540
541        let cast_candidates = acontext.enumerate_cast_candiates(&mut test_context);
542        let Some(casts) = cast_candidates.get(&text) else {
543            panic!("expected cast candidates for text");
544        };
545        assert_eq!(1, casts.len());
546        Ok(())
547    }
548}
549
550impl CaseExprAnalysisContext<'_> {
551    fn is_not_null(&self) -> Option<bool> {
552        if self.nullabilities.iter().any(|n| n == &Some(false)) {
553            Some(false)
554        } else if self.nullabilities.iter().all(std::option::Option::is_some) {
555            Some(true)
556        } else {
557            None
558        }
559    }
560}
561
562#[cfg(test)]
563mod test_case_expr_analysis_context_is_not_null {
564    use crate::sem::{FromClause, WithClause};
565
566    #[test]
567    fn test_is_not_null_any_false() {
568        let with_clause = WithClause::default();
569        let from_clause = FromClause::default();
570        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
571
572        acontext.nullabilities = vec![Some(true), Some(false)];
573        assert_eq!(Some(false), acontext.is_not_null());
574    }
575
576    #[test]
577    fn test_is_not_null_all_some() {
578        let with_clause = WithClause::default();
579        let from_clause = FromClause::default();
580        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
581
582        acontext.nullabilities = vec![Some(true), Some(true)];
583        assert_eq!(Some(true), acontext.is_not_null());
584    }
585
586    #[test]
587    fn test_is_not_null_with_unknown() {
588        let with_clause = WithClause::default();
589        let from_clause = FromClause::default();
590        let mut acontext = super::CaseExprAnalysisContext::new(&with_clause, &from_clause);
591
592        acontext.nullabilities = vec![Some(true), None];
593        assert_eq!(None, acontext.is_not_null());
594    }
595}
596
597impl CaseExprAnalysisContext<'_> {
598    fn into_case_expr<TParseContext>(
599        mut self,
600        context: &mut TParseContext,
601    ) -> Result<CaseExpr, AnalysisError>
602    where
603        TParseContext: ParseContext,
604    {
605        let case_expr_type = self.type_fixup(context)?;
606        let is_not_null = self.is_not_null();
607        Ok(CaseExpr {
608            arg_expr: Box::new(self.case_arg),
609            default_expr: Box::new(self.default_expr),
610            when_exprs: self.when_exprs,
611            case_expr_type,
612            is_not_null,
613        })
614    }
615}
616
617#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
618pub struct CaseWhen {
619    when_value: SemScalarExpr,
620    result: SemScalarExpr,
621}
622
623impl CaseWhen {
624    pub fn new(when_value: SemScalarExpr, result: SemScalarExpr) -> Self {
625        Self { when_value, result }
626    }
627}
628
629/// case expression
630#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
631pub struct CaseExpr {
632    arg_expr: Box<Option<SemScalarExpr>>,
633    when_exprs: Vec<CaseWhen>,
634    default_expr: Box<Option<SemScalarExpr>>,
635    case_expr_type: Option<TypeReference>,
636    is_not_null: Option<bool>,
637}
638
639impl CaseExpr {
640    /// create a instance
641    #[must_use]
642    pub fn new(
643        arg_expr: Box<Option<SemScalarExpr>>,
644        when_exprs: Vec<CaseWhen>,
645        default_expr: Box<Option<SemScalarExpr>>,
646        case_expr_type: Option<TypeReference>,
647        is_not_null: Option<bool>,
648    ) -> Self {
649        Self {
650            arg_expr,
651            when_exprs,
652            default_expr,
653            case_expr_type,
654            is_not_null,
655        }
656    }
657}
658
659impl SemScalarExprNode for CaseExpr {
660    fn get_type(&self) -> Option<TypeReference> {
661        self.case_expr_type.clone()
662    }
663
664    fn is_not_null(&self) -> Option<bool> {
665        self.is_not_null
666    }
667}
668
669impl<TParseContext> AnalyzeScalarExpr<TParseContext, crate::syn::CaseExpr> for CaseExpr
670where
671    TParseContext: ParseContext,
672{
673    fn analyze_scalar_expr(
674        mut context: TParseContext,
675        with_clause: &WithClause,
676        from_clause: &FromClause,
677        syn: crate::syn::CaseExpr,
678        tokens: &IVec<ScanToken>,
679    ) -> Result<(SemScalarExpr, TParseContext), AnalysisError> {
680        let mut analisys_context = CaseExprAnalysisContext::new(with_clause, from_clause);
681
682        context = analisys_context.analyze_case_arg(context, &syn, tokens)?;
683        let Some(args) = syn.get_args().map(|v| v.as_case_when()) else {
684            AnalysisError::raise_unexpected_none("caseexpr.args")?
685        };
686        context = analisys_context.analyze_case_when_list(context, args, tokens)?;
687        context = analisys_context.analyze_default_expr(context, syn, tokens)?;
688        let case = analisys_context.into_case_expr(&mut context)?;
689        Ok((SemScalarExpr::Case(case), context))
690    }
691}