prototype implementation
This commit is contained in:
@@ -398,7 +398,7 @@ cpp<#
|
||||
,@(loop for op in
|
||||
'(or-operator xor-operator and-operator addition-operator
|
||||
subtraction-operator multiplication-operator division-operator
|
||||
mod-operator not-equal-operator equal-operator less-operator
|
||||
mod-operator not-equal-operator less-operator
|
||||
greater-operator less-equal-operator greater-equal-operator
|
||||
in-list-operator subscript-operator)
|
||||
collecting
|
||||
@@ -458,6 +458,33 @@ cpp<#
|
||||
(:clone))))))
|
||||
(define-unary-operators))
|
||||
|
||||
(lcp:define-class equal-operator (binary-operator)
|
||||
((isNullCheckRequired "bool" :initval "false" :scope :public))
|
||||
(:public
|
||||
#>cpp
|
||||
DEFVISITABLE(ExpressionVisitor<TypedValue>);
|
||||
DEFVISITABLE(ExpressionVisitor<void>);
|
||||
|
||||
bool Accept(HierarchicalTreeVisitor &visitor) override {
|
||||
if (visitor.PreVisit(*this)) {
|
||||
expression1_->Accept(visitor) && expression2_->Accept(visitor);
|
||||
}
|
||||
return visitor.PostVisit(*this);
|
||||
}
|
||||
cpp<#)
|
||||
(:protected
|
||||
#>cpp
|
||||
using BinaryOperator::BinaryOperator;
|
||||
EqualOperator(Expression *expression1, Expression *expression2, bool is_nullcheck_required = false)
|
||||
: BinaryOperator(expression1, expression2), isnullcheckrequired_(is_nullcheck_required) {}
|
||||
cpp<#)
|
||||
(:private
|
||||
#>cpp
|
||||
friend class AstStorage;
|
||||
cpp<#)
|
||||
(:serialize (:slk))
|
||||
(:clone))
|
||||
|
||||
(lcp:define-class aggregation (binary-operator)
|
||||
((op "Op" :scope :public)
|
||||
(symbol-pos :int32_t :initval -1 :scope :public
|
||||
|
||||
@@ -2267,9 +2267,9 @@ antlrcpp::Any CypherMainVisitor::visitCaseExpression(MemgraphCypher::CaseExpress
|
||||
Expression *else_expression = ctx->else_expression ? ctx->else_expression->accept(this).as<Expression *>()
|
||||
: storage_->Create<PrimitiveLiteral>(TypedValue());
|
||||
for (auto *alternative : alternatives) {
|
||||
Expression *condition =
|
||||
test_expression ? storage_->Create<EqualOperator>(test_expression, alternative->when_expression->accept(this))
|
||||
: alternative->when_expression->accept(this).as<Expression *>();
|
||||
Expression *condition = test_expression ? storage_->Create<EqualOperator>(
|
||||
test_expression, alternative->when_expression->accept(this), true)
|
||||
: alternative->when_expression->accept(this).as<Expression *>();
|
||||
Expression *then_expression = alternative->then_expression->accept(this);
|
||||
else_expression = storage_->Create<IfOperator>(condition, then_expression, else_expression);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
|
||||
BINARY_OPERATOR_VISITOR(DivisionOperator, /, /);
|
||||
BINARY_OPERATOR_VISITOR(ModOperator, %, %);
|
||||
BINARY_OPERATOR_VISITOR(NotEqualOperator, !=, <>);
|
||||
BINARY_OPERATOR_VISITOR(EqualOperator, ==, =);
|
||||
// BINARY_OPERATOR_VISITOR(EqualOperator, ==, =);
|
||||
BINARY_OPERATOR_VISITOR(LessOperator, <, <);
|
||||
BINARY_OPERATOR_VISITOR(GreaterOperator, >, >);
|
||||
BINARY_OPERATOR_VISITOR(LessEqualOperator, <=, <=);
|
||||
@@ -94,6 +94,29 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
|
||||
#undef BINARY_OPERATOR_VISITOR
|
||||
#undef UNARY_OPERATOR_VISITOR
|
||||
|
||||
TypedValue Visit(EqualOperator &op) override {
|
||||
auto val1 = op.expression1_->Accept(*this);
|
||||
auto val2 = op.expression2_->Accept(*this);
|
||||
|
||||
// if(val1.IsNull())
|
||||
// {
|
||||
// val1.V
|
||||
// }
|
||||
|
||||
// if(op.isoperandnull_)
|
||||
// throw QueryRuntimeException("Use the generic form when checking against NULL.");
|
||||
|
||||
try {
|
||||
if (op.isnullcheckrequired_ && val2.IsNull()) {
|
||||
throw QueryRuntimeException("Use the generic form when checking against NULL.");
|
||||
}
|
||||
|
||||
return val1 == val2;
|
||||
} catch (const TypedValueException &) {
|
||||
throw QueryRuntimeException("Invalid types: {} and {} for '='.", val1.type(), val2.type());
|
||||
}
|
||||
}
|
||||
|
||||
TypedValue Visit(AndOperator &op) override {
|
||||
auto value1 = op.expression1_->Accept(*this);
|
||||
if (value1.IsBool() && !value1.ValueBool()) {
|
||||
|
||||
@@ -790,6 +790,26 @@ TEST_P(CypherMainVisitorTest, CaseSimpleForm) {
|
||||
ast_generator.CheckLiteral(if_operator->else_expression_, TypedValue());
|
||||
}
|
||||
|
||||
TEST_P(CypherMainVisitorTest, CaseSimpleFormNullcheckIsSet) {
|
||||
auto &ast_generator = *GetParam();
|
||||
auto *query = dynamic_cast<CypherQuery *>(ast_generator.ParseQuery("RETURN CASE 5 WHEN 10 THEN 1 END"));
|
||||
ASSERT_TRUE(query);
|
||||
ASSERT_TRUE(query->single_query_);
|
||||
auto *single_query = query->single_query_;
|
||||
auto *return_clause = dynamic_cast<Return *>(single_query->clauses_[0]);
|
||||
auto *if_operator = dynamic_cast<IfOperator *>(return_clause->body_.named_expressions[0]->expression_);
|
||||
auto *condition = dynamic_cast<EqualOperator *>(if_operator->condition_);
|
||||
ASSERT_TRUE(condition);
|
||||
ast_generator.CheckLiteral(condition->expression1_, 5);
|
||||
ast_generator.CheckLiteral(condition->expression2_, 10);
|
||||
|
||||
// This might be the only line thats different.
|
||||
ASSERT_TRUE(condition->isnullcheckrequired_);
|
||||
|
||||
ast_generator.CheckLiteral(if_operator->then_expression_, 1);
|
||||
ast_generator.CheckLiteral(if_operator->else_expression_, TypedValue());
|
||||
}
|
||||
|
||||
TEST_P(CypherMainVisitorTest, IsNull) {
|
||||
auto &ast_generator = *GetParam();
|
||||
auto *query = dynamic_cast<CypherQuery *>(ast_generator.ParseQuery("RETURN 2 iS NulL"));
|
||||
|
||||
Reference in New Issue
Block a user