support for functions in where clause

This commit is contained in:
2021-08-13 15:54:14 +02:00
parent e53d062ff5
commit ee0cbf64ff
3 changed files with 37 additions and 16 deletions

View File

@@ -444,8 +444,9 @@ namespace usql {
std::unique_ptr<Node> Parser::parse_operand_node() {
auto token_type = m_lexer.tokenType();
// parenthised expression
if (token_type == TokenType::open_paren) {
m_lexer.skipToken(TokenType::open_paren);
// open paren already consumed
auto left = parse_expression();
do {
left = parse_expression(std::move(left));
@@ -455,21 +456,39 @@ namespace usql {
return left;
}
std::string tokenString = m_lexer.consumeCurrentToken().token_string;
switch (token_type) {
case TokenType::int_number:
return std::make_unique<IntValueNode>(std::stoi(tokenString));
case TokenType::double_number:
return std::make_unique<DoubleValueNode>(std::stod(tokenString));
case TokenType::string_literal:
return std::make_unique<StringValueNode>(tokenString);
case TokenType::identifier:
return std::make_unique<DatabaseValueNode>(tokenString);
case TokenType::keyword_null:
return std::make_unique<NullValueNode>();
default:
throw Exception("Unknown operand node " + tokenString);
// function call
if (token_type == TokenType::identifier && m_lexer.nextTokenType() == TokenType::open_paren) {
std::string function_name = m_lexer.consumeCurrentToken().token_string;
std::vector<std::unique_ptr<Node>> pars;
m_lexer.skipToken(TokenType::open_paren);
while (m_lexer.tokenType() != TokenType::close_paren) { // TODO handle errors
pars.push_back(parse_operand_node());
m_lexer.skipTokenOptional(TokenType::comma);
}
m_lexer.skipToken(TokenType::close_paren);
return std::make_unique<FunctionNode>(function_name, std::move(pars));
}
// numbers and strings
std::string tokenString = m_lexer.consumeCurrentToken().token_string;
if (token_type == TokenType::int_number)
return std::make_unique<IntValueNode>(std::stoi(tokenString));
if (token_type == TokenType::double_number)
return std::make_unique<DoubleValueNode>(std::stod(tokenString));
if (token_type == TokenType::string_literal)
return std::make_unique<StringValueNode>(tokenString);
// db column
if (token_type == TokenType::identifier)
return std::make_unique<DatabaseValueNode>(tokenString);
// null
if (token_type == TokenType::keyword_null)
return std::make_unique<NullValueNode>();
throw Exception("Unknown operand node " + tokenString);
}
RelationalOperatorType Parser::parse_relational_operator() {