order by accepts column names now
This commit is contained in:
parent
0107ee0e4f
commit
a85c53e4f7
50
parser.cpp
50
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<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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue