order by accepts column names now

This commit is contained in:
VaclavT 2021-09-20 18:22:08 +02:00
parent 0107ee0e4f
commit a85c53e4f7
1 changed files with 24 additions and 26 deletions

View File

@ -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<Node> 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<std::unique_ptr<Node>> 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<IntValueNode>(std::stoi(tokenString));
if (token_type == TokenType::double_number)
if (token_typcol == TokenType::double_number)
return std::make_unique<DoubleValueNode>(std::stod(tokenString));
if (token_type == TokenType::string_literal)
if (token_typcol == TokenType::string_literal)
return std::make_unique<StringValueNode>(tokenString);
// db column
if (token_type == TokenType::identifier)
if (token_typcol == TokenType::identifier)
return std::make_unique<DatabaseValueNode>(tokenString);
// null
if (token_type == TokenType::keyword_null)
if (token_typcol == TokenType::keyword_null)
return std::make_unique<NullValueNode>();
// true / false
if (token_type == TokenType::keyword_true || token_type == TokenType::keyword_false)
return std::make_unique<BooleanValueNode>(token_type == TokenType::keyword_true);
if (token_typcol == TokenType::keyword_true || token_typcol == TokenType::keyword_false)
return std::make_unique<BooleanValueNode>(token_typcol == TokenType::keyword_true);
// token * for count(*)
if (token_type == TokenType::multiply)
if (token_typcol == TokenType::multiply)
return std::make_unique<StringValueNode>(tokenString);
throw Exception("Unknown operand node " + tokenString);