1#include <Parsers/ParserCase.h>
2#include <Parsers/ExpressionElementParsers.h>
3#include <Parsers/ExpressionListParsers.h>
4#include <Parsers/ASTFunction.h>
5#include <Parsers/ASTLiteral.h>
6#include <Core/Field.h>
7
8namespace DB
9{
10
11bool ParserCase::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
12{
13 ParserKeyword s_case{"CASE"};
14 ParserKeyword s_when{"WHEN"};
15 ParserKeyword s_then{"THEN"};
16 ParserKeyword s_else{"ELSE"};
17 ParserKeyword s_end{ "END"};
18 ParserExpressionWithOptionalAlias p_expr{false};
19
20 if (!s_case.ignore(pos, expected))
21 return false;
22
23 auto old_pos = pos;
24 bool has_case_expr = !s_when.ignore(pos, expected);
25 pos = old_pos;
26
27 ASTs args;
28
29 auto parse_branches = [&]()
30 {
31 bool has_branch = false;
32 while (s_when.ignore(pos, expected))
33 {
34 has_branch = true;
35
36 ASTPtr expr_when;
37 if (!p_expr.parse(pos, expr_when, expected))
38 return false;
39 args.push_back(expr_when);
40
41 if (!s_then.ignore(pos, expected))
42 return false;
43
44 ASTPtr expr_then;
45 if (!p_expr.parse(pos, expr_then, expected))
46 return false;
47 args.push_back(expr_then);
48 }
49
50 if (!has_branch)
51 return false;
52
53 ASTPtr expr_else;
54 if (s_else.ignore(pos, expected))
55 {
56 if (!p_expr.parse(pos, expr_else, expected))
57 return false;
58 }
59 else
60 {
61 Field field_with_null;
62 ASTLiteral null_literal(field_with_null);
63 expr_else = std::make_shared<ASTLiteral>(null_literal);
64 }
65 args.push_back(expr_else);
66
67 if (!s_end.ignore(pos, expected))
68 return false;
69
70 return true;
71 };
72
73 if (has_case_expr)
74 {
75 ASTPtr case_expr;
76 if (!p_expr.parse(pos, case_expr, expected))
77 return false;
78 args.push_back(case_expr);
79
80 if (!parse_branches())
81 return false;
82
83 auto function_args = std::make_shared<ASTExpressionList>();
84 function_args->children = std::move(args);
85
86 auto function = std::make_shared<ASTFunction>();
87 function->name = "caseWithExpression";
88 function->arguments = function_args;
89 function->children.push_back(function->arguments);
90
91 node = function;
92 }
93 else
94 {
95 if (!parse_branches())
96 return false;
97
98 auto function_args = std::make_shared<ASTExpressionList>();
99 function_args->children = std::move(args);
100
101 auto function = std::make_shared<ASTFunction>();
102 function->name = "multiIf";
103 function->arguments = function_args;
104 function->children.push_back(function->arguments);
105
106 node = function;
107 }
108
109 return true;
110}
111
112}
113