initial support for is null and is not null

will nedd some work, but just for now
This commit is contained in:
VaclavT 2021-09-08 18:34:11 +02:00
parent 0db976f471
commit 61f3af90af
6 changed files with 30 additions and 5 deletions

View File

@ -104,7 +104,8 @@ namespace usql {
bool Lexer::isRelationalOperator(TokenType token_type) {
return (token_type == TokenType::equal || token_type == TokenType::not_equal ||
token_type == TokenType::greater || token_type == TokenType::greater_equal ||
token_type == TokenType::lesser || token_type == TokenType::lesser_equal);
token_type == TokenType::lesser || token_type == TokenType::lesser_equal ||
token_type == TokenType::is);
}
bool Lexer::isLogicalOperator(TokenType token_type) {
@ -145,6 +146,8 @@ namespace usql {
return TokenType::lesser;
if (token == "<=")
return TokenType::lesser_equal;
if (token == "is")
return TokenType::is;
if (token == "as")
return TokenType::keyword_as;
if (token == "create")
@ -321,6 +324,9 @@ namespace usql {
case TokenType::lesser_equal:
txt = "<=";
break;
case TokenType::is:
txt = "is";
break;
case TokenType::keyword_as:
txt = "as";
break;

View File

@ -20,6 +20,7 @@ namespace usql {
greater_equal,
lesser,
lesser_equal,
is,
keyword_as,
keyword_create,
keyword_drop,

View File

@ -145,9 +145,11 @@ void debug() {
// "select ticker, dimension, calendar_date, eps, dps, roa*100 as roa, roe*100 as roe, pp(revenue), netinc from sf1 where (ticker = 'AIG' or ticker = 'WFC') and dimension = 'MRY' and calendar_date > to_date('2019-01-01', '%Y-%m-%d') order by 3 desc
// "select ticker, dimension, calendar_date, eps, dps, roa*100 as roa, roe*100 as roe, pp(revenue) as revenue, pp(netinc) as netinc from sf1 where (ticker = 'AIG' or ticker = 'WFC') and dimension = 'MRY' and calendar_date > to_date('2019-01-01', '%Y-%m-%d') 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')",
"insert into a (i, s, b) values(1, upper('zero'), 'Y')",
"insert into a (i, s, b, f) values(1 + 10000, upper('one'), 'N', 3.1415)",
"select * from a where d is null",
"insert into a (i, s, f) values(2 + 10000, upper('two'), 3.1415)",
"select * from a where b is null",
"select * from a where b is not null",
// "select * from a where b='N'",
// "update a set i = i * 100, f = f + 0.01 where i > 1",
// "select to_string(i, '%d.%m.%Y %H:%M:%S'), i, s from a where i < to_date('20.12.2019', '%d.%m.%Y')",

View File

@ -472,6 +472,12 @@ namespace usql {
return RelationalOperatorType::lesser;
case TokenType::lesser_equal:
return RelationalOperatorType::lesser_equal;
case TokenType::is:
if (m_lexer.tokenType() == TokenType::keyword_not) {
m_lexer.skipToken(TokenType::keyword_not);
return RelationalOperatorType::is_not;
}
return RelationalOperatorType::is;
default:
throw Exception("Unknown relational operator " + op.token_string);
}

View File

@ -210,7 +210,9 @@ namespace usql {
greater_equal,
lesser,
lesser_equal,
not_equal
not_equal,
is,
is_not
// like
};

View File

@ -398,7 +398,15 @@ bool USql::eval_relational_operator(const RelationalOperatorNode &filter, Table
double comparator;
if (left_value->node_type == NodeType::int_value && right_value->node_type == NodeType::int_value) {
if (left_value->node_type == NodeType::null_value || right_value->node_type == NodeType::null_value) {
bool all_null = left_value->isNull() && right_value->node_type == NodeType::null_value ||
right_value->isNull() && left_value->node_type == NodeType::null_value;
if (filter.op == RelationalOperatorType::is)
return all_null;
if (filter.op == RelationalOperatorType::is_not)
return !all_null;
return false;
} else if (left_value->node_type == NodeType::int_value && right_value->node_type == NodeType::int_value) {
comparator = left_value->getIntegerValue() - right_value->getIntegerValue();
} else if ((left_value->node_type == NodeType::int_value && right_value->node_type == NodeType::float_value) ||
(left_value->node_type == NodeType::float_value && right_value->node_type == NodeType::int_value) ||