bool ParserCase::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) { Pos begin = pos; ParserWhiteSpaceOrComments ws; ParserString s_case{"CASE", true, true}; ParserString s_when{"WHEN", true, true}; ParserString s_then{"THEN", true, true}; ParserString s_else{"ELSE", true, true}; ParserString s_end{ "END", true, true}; ParserExpressionWithOptionalAlias p_expr{false}; if (!s_case.parse(pos, end, node, max_parsed_pos, expected)) { /// Parse as a simple ASTFunction. return ParserFunction{}.parse(pos = begin, end, node, max_parsed_pos, expected); } ws.ignore(pos, end); bool has_case_expr = false; auto old_pos = pos; has_case_expr = !s_when.parse(pos, end, node, max_parsed_pos, expected); pos = old_pos; ASTs args; auto parse_branches = [&]() { bool has_branch = false; while (s_when.parse(pos, end, node, max_parsed_pos, expected)) { has_branch = true; ws.ignore(pos, end); ASTPtr expr_when; if (!p_expr.parse(pos, end, expr_when, max_parsed_pos, expected)) return false; args.push_back(expr_when); ws.ignore(pos, end); if (!s_then.parse(pos, end, node, max_parsed_pos, expected)) return false; ws.ignore(pos, end); ASTPtr expr_then; if (!p_expr.parse(pos, end, expr_then, max_parsed_pos, expected)) return false; args.push_back(expr_then); ws.ignore(pos, end); } if (!has_branch) return false; ws.ignore(pos, end); if (!s_else.parse(pos, end, node, max_parsed_pos, expected)) return false; ws.ignore(pos, end); ASTPtr expr_else; if (!p_expr.parse(pos, end, expr_else, max_parsed_pos, expected)) return false; args.push_back(expr_else); ws.ignore(pos, end); if (!s_end.parse(pos, end, node, max_parsed_pos, expected)) return false; return true; }; if (has_case_expr) { ASTPtr case_expr; if (!p_expr.parse(pos, end, case_expr, max_parsed_pos, expected)) return false; args.push_back(case_expr); ws.ignore(pos, end); if (!parse_branches()) return false; auto function_args = std::make_shared<ASTExpressionList>(StringRange{begin, pos}); function_args->children = std::move(args); auto function = std::make_shared<ASTFunction>(StringRange{begin, pos}); function->name = "caseWithExpr"; function->arguments = function_args; function->children.push_back(function->arguments); node = function; } else { if (!parse_branches()) return false; auto function_args = std::make_shared<ASTExpressionList>(StringRange{begin, pos}); function_args->children = std::move(args); auto function = std::make_shared<ASTFunction>(StringRange{begin, pos}); function->name = "caseWithoutExpr"; function->arguments = function_args; function->children.push_back(function->arguments); node = function; } return true; }
bool ParserCase::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { ParserKeyword s_case{"CASE"}; ParserKeyword s_when{"WHEN"}; ParserKeyword s_then{"THEN"}; ParserKeyword s_else{"ELSE"}; ParserKeyword s_end{ "END"}; ParserExpressionWithOptionalAlias p_expr{false}; if (!s_case.ignore(pos, expected)) return false; auto old_pos = pos; bool has_case_expr = !s_when.ignore(pos, expected); pos = old_pos; ASTs args; auto parse_branches = [&]() { bool has_branch = false; while (s_when.ignore(pos, expected)) { has_branch = true; ASTPtr expr_when; if (!p_expr.parse(pos, expr_when, expected)) return false; args.push_back(expr_when); if (!s_then.ignore(pos, expected)) return false; ASTPtr expr_then; if (!p_expr.parse(pos, expr_then, expected)) return false; args.push_back(expr_then); } if (!has_branch) return false; ASTPtr expr_else; if (s_else.ignore(pos, expected)) { if (!p_expr.parse(pos, expr_else, expected)) return false; } else { Field field_with_null; ASTLiteral null_literal(field_with_null); expr_else = std::make_shared<ASTLiteral>(null_literal); } args.push_back(expr_else); if (!s_end.ignore(pos, expected)) return false; return true; }; if (has_case_expr) { ASTPtr case_expr; if (!p_expr.parse(pos, case_expr, expected)) return false; args.push_back(case_expr); if (!parse_branches()) return false; auto function_args = std::make_shared<ASTExpressionList>(); function_args->children = std::move(args); auto function = std::make_shared<ASTFunction>(); function->name = "caseWithExpression"; function->arguments = function_args; function->children.push_back(function->arguments); node = function; } else { if (!parse_branches()) return false; auto function_args = std::make_shared<ASTExpressionList>(); function_args->children = std::move(args); auto function = std::make_shared<ASTFunction>(); function->name = "multiIf"; function->arguments = function_args; function->children.push_back(function->arguments); node = function; } return true; }