support for functions in where clause
This commit is contained in:
parent
e53d062ff5
commit
ee0cbf64ff
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
### TODO
|
||||
- better support for values in update and insert
|
||||
- date functions - now, add_date...
|
||||
- string functions rtrim, ltrim, rpad, lpad
|
||||
- add pipe | concatenation
|
||||
|
|
|
|||
3
main.cpp
3
main.cpp
|
|
@ -139,7 +139,8 @@ int main(int argc, char *argv[]) {
|
|||
// "select ticker, dimension, calendar_date, eps, dps from sf1 where (ticker = 'AIG' or ticker = 'WFC') and dimension = 'MRY' order by 3 desc",
|
||||
"create table a (i integer not null, s varchar(64), f float null, d date null, b boolean)",
|
||||
"insert into a (i, s, b) values(1, upper('one'), 'Y')",
|
||||
"select i+2, s, b from a where i >=1 order by 1 desc offset 0 limit 1",
|
||||
"select i, s from a where i < to_date('20.12.1973', '%d.%m.%Y')",
|
||||
// xxxxxxxx "select i+2, s, b from a where i >=1 order by 1 desc offset 0 limit 1",
|
||||
// "update table a set s = 'null string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'",
|
||||
"update table a set i = null",
|
||||
"insert into a (i, s) values(2, 'two')",
|
||||
|
|
|
|||
49
parser.cpp
49
parser.cpp
|
|
@ -444,8 +444,9 @@ namespace usql {
|
|||
std::unique_ptr<Node> Parser::parse_operand_node() {
|
||||
auto token_type = m_lexer.tokenType();
|
||||
|
||||
// parenthised expression
|
||||
if (token_type == TokenType::open_paren) {
|
||||
m_lexer.skipToken(TokenType::open_paren);
|
||||
// open paren already consumed
|
||||
auto left = parse_expression();
|
||||
do {
|
||||
left = parse_expression(std::move(left));
|
||||
|
|
@ -455,21 +456,39 @@ namespace usql {
|
|||
return left;
|
||||
}
|
||||
|
||||
std::string tokenString = m_lexer.consumeCurrentToken().token_string;
|
||||
switch (token_type) {
|
||||
case TokenType::int_number:
|
||||
return std::make_unique<IntValueNode>(std::stoi(tokenString));
|
||||
case TokenType::double_number:
|
||||
return std::make_unique<DoubleValueNode>(std::stod(tokenString));
|
||||
case TokenType::string_literal:
|
||||
return std::make_unique<StringValueNode>(tokenString);
|
||||
case TokenType::identifier:
|
||||
return std::make_unique<DatabaseValueNode>(tokenString);
|
||||
case TokenType::keyword_null:
|
||||
return std::make_unique<NullValueNode>();
|
||||
default:
|
||||
throw Exception("Unknown operand node " + tokenString);
|
||||
// function call
|
||||
if (token_type == TokenType::identifier && m_lexer.nextTokenType() == TokenType::open_paren) {
|
||||
std::string function_name = m_lexer.consumeCurrentToken().token_string;
|
||||
std::vector<std::unique_ptr<Node>> pars;
|
||||
|
||||
m_lexer.skipToken(TokenType::open_paren);
|
||||
while (m_lexer.tokenType() != TokenType::close_paren) { // TODO handle errors
|
||||
pars.push_back(parse_operand_node());
|
||||
m_lexer.skipTokenOptional(TokenType::comma);
|
||||
}
|
||||
m_lexer.skipToken(TokenType::close_paren);
|
||||
return std::make_unique<FunctionNode>(function_name, std::move(pars));
|
||||
}
|
||||
|
||||
// numbers and strings
|
||||
std::string tokenString = m_lexer.consumeCurrentToken().token_string;
|
||||
|
||||
if (token_type == TokenType::int_number)
|
||||
return std::make_unique<IntValueNode>(std::stoi(tokenString));
|
||||
if (token_type == TokenType::double_number)
|
||||
return std::make_unique<DoubleValueNode>(std::stod(tokenString));
|
||||
if (token_type == TokenType::string_literal)
|
||||
return std::make_unique<StringValueNode>(tokenString);
|
||||
|
||||
// db column
|
||||
if (token_type == TokenType::identifier)
|
||||
return std::make_unique<DatabaseValueNode>(tokenString);
|
||||
|
||||
// null
|
||||
if (token_type == TokenType::keyword_null)
|
||||
return std::make_unique<NullValueNode>();
|
||||
|
||||
throw Exception("Unknown operand node " + tokenString);
|
||||
}
|
||||
|
||||
RelationalOperatorType Parser::parse_relational_operator() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue