support for functions in where clause
This commit is contained in:
parent
e53d062ff5
commit
ee0cbf64ff
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
|
- better support for values in update and insert
|
||||||
- date functions - now, add_date...
|
- date functions - now, add_date...
|
||||||
- string functions rtrim, ltrim, rpad, lpad
|
- string functions rtrim, ltrim, rpad, lpad
|
||||||
- add pipe | concatenation
|
- 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",
|
// "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)",
|
"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')",
|
"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 s = 'null string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'",
|
||||||
"update table a set i = null",
|
"update table a set i = null",
|
||||||
"insert into a (i, s) values(2, 'two')",
|
"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() {
|
std::unique_ptr<Node> Parser::parse_operand_node() {
|
||||||
auto token_type = m_lexer.tokenType();
|
auto token_type = m_lexer.tokenType();
|
||||||
|
|
||||||
|
// parenthised expression
|
||||||
if (token_type == TokenType::open_paren) {
|
if (token_type == TokenType::open_paren) {
|
||||||
m_lexer.skipToken(TokenType::open_paren);
|
// open paren already consumed
|
||||||
auto left = parse_expression();
|
auto left = parse_expression();
|
||||||
do {
|
do {
|
||||||
left = parse_expression(std::move(left));
|
left = parse_expression(std::move(left));
|
||||||
|
|
@ -455,21 +456,39 @@ namespace usql {
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tokenString = m_lexer.consumeCurrentToken().token_string;
|
// function call
|
||||||
switch (token_type) {
|
if (token_type == TokenType::identifier && m_lexer.nextTokenType() == TokenType::open_paren) {
|
||||||
case TokenType::int_number:
|
std::string function_name = m_lexer.consumeCurrentToken().token_string;
|
||||||
return std::make_unique<IntValueNode>(std::stoi(tokenString));
|
std::vector<std::unique_ptr<Node>> pars;
|
||||||
case TokenType::double_number:
|
|
||||||
return std::make_unique<DoubleValueNode>(std::stod(tokenString));
|
m_lexer.skipToken(TokenType::open_paren);
|
||||||
case TokenType::string_literal:
|
while (m_lexer.tokenType() != TokenType::close_paren) { // TODO handle errors
|
||||||
return std::make_unique<StringValueNode>(tokenString);
|
pars.push_back(parse_operand_node());
|
||||||
case TokenType::identifier:
|
m_lexer.skipTokenOptional(TokenType::comma);
|
||||||
return std::make_unique<DatabaseValueNode>(tokenString);
|
}
|
||||||
case TokenType::keyword_null:
|
m_lexer.skipToken(TokenType::close_paren);
|
||||||
return std::make_unique<NullValueNode>();
|
return std::make_unique<FunctionNode>(function_name, std::move(pars));
|
||||||
default:
|
|
||||||
throw Exception("Unknown operand node " + tokenString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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() {
|
RelationalOperatorType Parser::parse_relational_operator() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue