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 // column values
m_lexer.skipToken(TokenType::open_paren); m_lexer.skipToken(TokenType::open_paren);
do { do {
// TODO here it is problem when exception from parse_expression<-parse_value is thrown
// it makes double free
auto value = parse_expression(); auto value = parse_expression();
column_values.emplace_back(std::move(value)); column_values.emplace_back(std::move(value));
@ -313,18 +311,10 @@ namespace usql {
m_lexer.skipToken(TokenType::keyword_by); m_lexer.skipToken(TokenType::keyword_by);
do { do {
int col_index = FUNCTION_CALL;
bool asc = true; bool asc = true;
auto token_type = m_lexer.tokenType(); auto cspec_token_type = m_lexer.tokenType();
std::string tokenString = m_lexer.consumeToken().token_string; std::string cspec_token = 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");
}
if (m_lexer.tokenType() == TokenType::keyword_asc) { if (m_lexer.tokenType() == TokenType::keyword_asc) {
m_lexer.skipToken(TokenType::keyword_asc); m_lexer.skipToken(TokenType::keyword_asc);
@ -333,10 +323,18 @@ namespace usql {
asc = false; 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); m_lexer.skipTokenOptional(TokenType::comma);
} while (m_lexer.tokenType() != TokenType::eof && m_lexer.tokenType() != TokenType::keyword_offset && m_lexer.tokenType() != TokenType::keyword_limit); } 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() { std::unique_ptr<Node> Parser::parse_value() {
auto token_type = m_lexer.tokenType(); auto token_typcol = m_lexer.tokenType();
// parenthesised expression // parenthesised expression
if (token_type == TokenType::open_paren) { if (token_typcol == TokenType::open_paren) {
m_lexer.skipToken(TokenType::open_paren); m_lexer.skipToken(TokenType::open_paren);
auto left = parse_expression(); auto left = parse_expression();
do { do {
@ -420,7 +418,7 @@ namespace usql {
} }
// function call // 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::string function_name = m_lexer.consumeToken(TokenType::identifier).token_string;
std::vector<std::unique_ptr<Node>> pars; std::vector<std::unique_ptr<Node>> pars;
@ -436,27 +434,27 @@ namespace usql {
// numbers and strings // numbers and strings
std::string tokenString = m_lexer.consumeToken().token_string; 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)); 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)); 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); return std::make_unique<StringValueNode>(tokenString);
// db column // db column
if (token_type == TokenType::identifier) if (token_typcol == TokenType::identifier)
return std::make_unique<DatabaseValueNode>(tokenString); return std::make_unique<DatabaseValueNode>(tokenString);
// null // null
if (token_type == TokenType::keyword_null) if (token_typcol == TokenType::keyword_null)
return std::make_unique<NullValueNode>(); return std::make_unique<NullValueNode>();
// true / false // true / false
if (token_type == TokenType::keyword_true || token_type == TokenType::keyword_false) if (token_typcol == TokenType::keyword_true || token_typcol == TokenType::keyword_false)
return std::make_unique<BooleanValueNode>(token_type == TokenType::keyword_true); return std::make_unique<BooleanValueNode>(token_typcol == TokenType::keyword_true);
// token * for count(*) // token * for count(*)
if (token_type == TokenType::multiply) if (token_typcol == TokenType::multiply)
return std::make_unique<StringValueNode>(tokenString); return std::make_unique<StringValueNode>(tokenString);
throw Exception("Unknown operand node " + tokenString); throw Exception("Unknown operand node " + tokenString);