From a85c53e4f73d1400fc4941412854a32479eb8529 Mon Sep 17 00:00:00 2001 From: VaclavT Date: Mon, 20 Sep 2021 18:22:08 +0200 Subject: [PATCH] order by accepts column names now --- parser.cpp | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/parser.cpp b/parser.cpp index e7f5c36..4889147 100644 --- a/parser.cpp +++ b/parser.cpp @@ -191,8 +191,6 @@ namespace usql { // column values m_lexer.skipToken(TokenType::open_paren); do { - // TODO here it is problem when exception from parse_expression<-parse_value is thrown - // it makes double free auto value = parse_expression(); column_values.emplace_back(std::move(value)); @@ -313,18 +311,10 @@ namespace usql { m_lexer.skipToken(TokenType::keyword_by); do { - int col_index = FUNCTION_CALL; bool asc = true; - auto token_type = m_lexer.tokenType(); - std::string tokenString = m_lexer.consumeToken().token_string; - switch (token_type) { - case TokenType::int_number: - col_index = std::stoi(tokenString); - break; - default: - throw Exception("column index allowed in order by clause at this moment"); - } + auto cspec_token_type = m_lexer.tokenType(); + std::string cspec_token = m_lexer.consumeToken().token_string; if (m_lexer.tokenType() == TokenType::keyword_asc) { m_lexer.skipToken(TokenType::keyword_asc); @@ -332,11 +322,19 @@ namespace usql { m_lexer.skipToken(TokenType::keyword_desc); asc = false; } - - order_cols.emplace_back(col_index, asc); + + switch (cspec_token_type) { + case TokenType::int_number: + order_cols.emplace_back(std::stoi(cspec_token), asc); + break; + case TokenType::identifier: + order_cols.emplace_back(cspec_token, asc); + break; + default: + throw Exception("order by column can be either column index or identifier"); + } m_lexer.skipTokenOptional(TokenType::comma); - } while (m_lexer.tokenType() != TokenType::eof && m_lexer.tokenType() != TokenType::keyword_offset && m_lexer.tokenType() != TokenType::keyword_limit); } @@ -405,10 +403,10 @@ namespace usql { } std::unique_ptr Parser::parse_value() { - auto token_type = m_lexer.tokenType(); + auto token_typcol = m_lexer.tokenType(); // parenthesised expression - if (token_type == TokenType::open_paren) { + if (token_typcol == TokenType::open_paren) { m_lexer.skipToken(TokenType::open_paren); auto left = parse_expression(); do { @@ -420,7 +418,7 @@ namespace usql { } // function call - if (token_type == TokenType::identifier && m_lexer.nextTokenType() == TokenType::open_paren) { + if (token_typcol == TokenType::identifier && m_lexer.nextTokenType() == TokenType::open_paren) { std::string function_name = m_lexer.consumeToken(TokenType::identifier).token_string; std::vector> pars; @@ -436,27 +434,27 @@ namespace usql { // numbers and strings std::string tokenString = m_lexer.consumeToken().token_string; - if (token_type == TokenType::int_number) + if (token_typcol == TokenType::int_number) return std::make_unique(std::stoi(tokenString)); - if (token_type == TokenType::double_number) + if (token_typcol == TokenType::double_number) return std::make_unique(std::stod(tokenString)); - if (token_type == TokenType::string_literal) + if (token_typcol == TokenType::string_literal) return std::make_unique(tokenString); // db column - if (token_type == TokenType::identifier) + if (token_typcol == TokenType::identifier) return std::make_unique(tokenString); // null - if (token_type == TokenType::keyword_null) + if (token_typcol == TokenType::keyword_null) return std::make_unique(); // true / false - if (token_type == TokenType::keyword_true || token_type == TokenType::keyword_false) - return std::make_unique(token_type == TokenType::keyword_true); + if (token_typcol == TokenType::keyword_true || token_typcol == TokenType::keyword_false) + return std::make_unique(token_typcol == TokenType::keyword_true); // token * for count(*) - if (token_type == TokenType::multiply) + if (token_typcol == TokenType::multiply) return std::make_unique(tokenString); throw Exception("Unknown operand node " + tokenString);