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