prototype implementation

This commit is contained in:
Gabor Volfinger
2022-06-29 12:15:11 +02:00
parent 589e0e098b
commit 449fd02b8a
4 changed files with 75 additions and 5 deletions

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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()) {

View File

@@ -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"));