Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for intersect/union, limit, group by, order by, variable, list exprs #5061

Merged
merged 6 commits into from
Dec 28, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 27 additions & 17 deletions src/common/expression/PredicateExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,11 @@ const Value& PredicateExpression::eval(ExpressionContext& ctx) {
auto& v = list[i];
ctx.setInnerVar(innerVar_, v);
auto& filterVal = filter_->eval(ctx);
if (!filterVal.empty() && !filterVal.isNull() && !filterVal.isImplicitBool()) {
if (filterVal.empty() || filterVal.isNull()) {
return Value::kNullValue;
} else if (!filterVal.isImplicitBool()) {
return Value::kNullBadType;
}
if (filterVal.empty() || filterVal.isNull() || !filterVal.implicitBool()) {
} else if (!filterVal.implicitBool()) {
result_ = false;
return result_;
}
Expand All @@ -110,34 +111,42 @@ const Value& PredicateExpression::eval(ExpressionContext& ctx) {
auto& v = list[i];
ctx.setInnerVar(innerVar_, v);
auto& filterVal = filter_->eval(ctx);
if (!filterVal.empty() && !filterVal.isNull() && !filterVal.isImplicitBool()) {
if (filterVal.empty() || filterVal.isNull()) {
result_ = Value::kNullValue;
} else if (!filterVal.isImplicitBool()) {
return Value::kNullBadType;
}
if (filterVal.isBool() && filterVal.implicitBool()) {
} else if (filterVal.implicitBool()) {
result_ = true;
return result_;
}
}
return result_;
}
case Type::SINGLE: {
result_ = false;
bool hasNull = false;
// If there are more than one satisfied, the result is false
bool hasSatisfied = false;
for (size_t i = 0; i < list.size(); ++i) {
auto& v = list[i];
ctx.setInnerVar(innerVar_, v);
auto& filterVal = filter_->eval(ctx);
if (!filterVal.empty() && !filterVal.isNull() && !filterVal.isImplicitBool()) {
if (filterVal.empty() || filterVal.isNull()) {
hasNull = true;
} else if (!filterVal.isImplicitBool()) {
return Value::kNullBadType;
}
if (filterVal.isBool() && filterVal.implicitBool()) {
if (result_ == false) {
result_ = true;
} else {
} else if (filterVal.implicitBool()) {
if (hasSatisfied) {
result_ = false;
return result_;
}
hasSatisfied = true;
}
}
if (hasNull) {
result_ = Value::kNullValue;
} else {
result_ = hasSatisfied;
}
return result_;
}
case Type::NONE: {
Expand All @@ -146,10 +155,12 @@ const Value& PredicateExpression::eval(ExpressionContext& ctx) {
auto& v = list[i];
ctx.setInnerVar(innerVar_, v);
auto& filterVal = filter_->eval(ctx);
if (!filterVal.empty() && !filterVal.isNull() && !filterVal.isImplicitBool()) {
if (filterVal.empty() || filterVal.isNull()) {
result_ = Value::kNullValue;
return result_;
} else if (!filterVal.isImplicitBool()) {
return Value::kNullBadType;
}
if (filterVal.isBool() && filterVal.implicitBool()) {
} else if (filterVal.implicitBool()) {
result_ = false;
return result_;
}
Expand All @@ -159,7 +170,6 @@ const Value& PredicateExpression::eval(ExpressionContext& ctx) {
// no default so the compiler will warning when lack
}

result_ = Value::kNullBadType;
return result_;
}

Expand Down
4 changes: 4 additions & 0 deletions src/graph/context/Symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ std::string SymbolTable::toString() const {
return ss.str();
}

bool SymbolTable::existsVar(const std::string& varName) const {
return vars_.find(varName) != vars_.end();
}

Variable* SymbolTable::newVariable(const std::string& name) {
VLOG(1) << "New variable for: " << name;
DCHECK(vars_.find(name) == vars_.end());
Expand Down
2 changes: 2 additions & 0 deletions src/graph/context/Symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class SymbolTable final {
explicit SymbolTable(ObjectPool* objPool, ExecutionContext* ectx)
: objPool_(DCHECK_NOTNULL(objPool)), ectx_(DCHECK_NOTNULL(ectx)) {}

bool existsVar(const std::string& varName) const;

Variable* newVariable(const std::string& name);

bool readBy(const std::string& varName, PlanNode* node);
Expand Down
3 changes: 3 additions & 0 deletions src/graph/validator/AssignmentValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Status AssignmentValidator::validateImpl() {

auto outputs = validator_->outputCols();
var_ = *assignSentence->var();
if (qctx_->symTable()->existsVar(var_)) {
return Status::SemanticError("Variable `%s' already exists", var_.c_str());
}
vctx_->registerVariable(var_, std::move(outputs));
return Status::OK();
}
Expand Down
65 changes: 65 additions & 0 deletions tests/tck/features/aggregate/Agg.feature
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,71 @@ Feature: Basic Aggregate and GroupBy
Then the result should be, in any order, with relax comparison:
| COUNT(*) |
| 56 |
When executing query:
"""
UNWIND [1,2,NULL] AS a
RETURN COUNT(*), COUNT(a)
"""
Then the result should be, in any order, with relax comparison:
| COUNT(*) | COUNT(a) |
| 3 | 2 |
When executing query:
"""
UNWIND [1,2,NULL] AS a
RETURN SUM(a), AVG(a), MIN(a), MAX(a), COLLECT(a)
"""
Then the result should be, in any order, with relax comparison:
| SUM(a) | AVG(a) | MIN(a) | MAX(a) | COLLECT(a) |
| 3 | 1.5 | 1 | 2 | [1,2] |
When executing query:
"""
UNWIND [1,2,NULL,2] AS a
RETURN COLLECT(a), COLLECT(DISTINCT a)
"""
Then the result should be, in any order, with relax comparison:
| COLLECT(a) | COLLECT(distinct a) |
| [1,2,2] | [1,2] |
When executing query:
"""
UNWIND [NULL,NULL,NULL] AS a
RETURN SUM(a), AVG(a), MIN(a), MAX(a), COLLECT(a), COLLECT(DISTINCT a)
"""
Then the result should be, in any order, with relax comparison:
| SUM(a) | AVG(a) | MIN(a) | MAX(a) | COLLECT(a) | COLLECT(distinct a) |
| 0 | NULL | NULL | NULL | [] | [] |
# one group key
When executing query:
"""
MATCH (v:player)-[e:like]->(v2) WHERE id(v) IN ["Tony Parker", "Tim Duncan", "LaMarcus Aldridge"]
RETURN v, COUNT(*), COUNT(v2), COUNT(DISTINCT v2), MIN(v2.player.age), MAX(e.likeness), SUM(e.likeness), COLLECT(v2), COLLECT(DISTINCT v2)
ORDER BY v
"""
Then the result should be, in any order, with relax comparison:
| v | COUNT(*) | COUNT(v2) | COUNT(distinct v2) | MIN(v2.player.age) | MAX(e.likeness) | SUM(e.likeness) | COLLECT(v2) | COLLECT(distinct v2) |
| ("LaMarcus Aldridge") | 2 | 2 | 2 | 36 | 75 | 150 | [("Tim Duncan"), ("Tony Parker")] | [("Tim Duncan"), ("Tony Parker")] |
| ("Tim Duncan") | 2 | 2 | 2 | 36 | 95 | 190 | [("Manu Ginobili"), ("Tony Parker") ] | [("Manu Ginobili"), ("Tony Parker")] |
| ("Tony Parker") | 3 | 3 | 3 | 33 | 95 | 280 | [("LaMarcus Aldridge"), ("Manu Ginobili"), ("Tim Duncan")] | [("LaMarcus Aldridge"), ("Manu Ginobili"), ("Tim Duncan")] |
# multi group keys
When executing query:
"""
MATCH (v:player)-[e:like*1..3]->(v2)-[e2:like]->(v3) WHERE id(v) IN ["Tony Parker", "Tim Duncan", "LaMarcus Aldridge"]
RETURN v, v2, COUNT(*), COUNT(id(v3)), COUNT(DISTINCT id(v3)), MIN(v3.player.age), MAX(e2.likeness), SUM(e2.likeness), COLLECT(id(v3)), COLLECT(DISTINCT id(v3))
ORDER BY v
"""
Then the result should be, in any order, with relax comparison:
| v | v2 | COUNT(*) | COUNT(id(v3)) | COUNT(distinct id(v3)) | MIN(v3.player.age) | MAX(e2.likeness) | SUM(e2.likeness) | COLLECT(id(v3)) | COLLECT(distinct id(v3)) |
| ("LaMarcus Aldridge") | ("LaMarcus Aldridge") | 2 | 2 | 2 | 36 | 75 | 150 | ["Tim Duncan", "Tony Parker"] | ["Tim Duncan", "Tony Parker"] |
| ("LaMarcus Aldridge") | ("Manu Ginobili") | 4 | 4 | 1 | 42 | 90 | 360 | ["Tim Duncan", "Tim Duncan", "Tim Duncan", "Tim Duncan"] | ["Tim Duncan"] |
| ("LaMarcus Aldridge") | ("Tony Parker") | 8 | 8 | 3 | 33 | 95 | 745 | ["LaMarcus Aldridge", "Manu Ginobili", "Tim Duncan", "LaMarcus Aldridge", "Manu Ginobili", "Tim Duncan", "LaMarcus Aldridge", "Manu Ginobili"] | ["LaMarcus Aldridge", "Manu Ginobili", "Tim Duncan"] |
| ("LaMarcus Aldridge") | ("Tim Duncan") | 10 | 10 | 2 | 36 | 95 | 950 | ["Manu Ginobili", "Tony Parker", "Manu Ginobili", "Tony Parker", "Tony Parker", "Manu Ginobili", "Manu Ginobili", "Tony Parker", "Manu Ginobili", "Tony Parker"] | ["Manu Ginobili", "Tony Parker"] |
| ("Tim Duncan") | ("Manu Ginobili") | 3 | 3 | 1 | 42 | 90 | 270 | ["Tim Duncan", "Tim Duncan", "Tim Duncan"] | ["Tim Duncan"] |
| ("Tim Duncan") | ("LaMarcus Aldridge") | 2 | 2 | 2 | 36 | 75 | 150 | ["Tim Duncan", "Tony Parker"] | ["Tim Duncan", "Tony Parker"] |
| ("Tim Duncan") | ("Tim Duncan") | 4 | 4 | 2 | 36 | 95 | 380 | ["Tony Parker", "Manu Ginobili", "Manu Ginobili", "Manu Ginobili"] | ["Tony Parker", "Manu Ginobili"] |
| ("Tim Duncan") | ("Tony Parker") | 8 | 8 | 3 | 33 | 95 | 750 | ["LaMarcus Aldridge", "Manu Ginobili", "Tim Duncan", "LaMarcus Aldridge", "Manu Ginobili", "Tim Duncan", "Manu Ginobili", "Tim Duncan"] | ["LaMarcus Aldridge", "Manu Ginobili", "Tim Duncan"] |
| ("Tony Parker") | ("LaMarcus Aldridge") | 4 | 4 | 2 | 36 | 75 | 300 | ["Tim Duncan", "Tony Parker", "Tim Duncan", "Tony Parker"] | ["Tim Duncan", "Tony Parker"] |
| ("Tony Parker") | ("Tim Duncan") | 9 | 9 | 2 | 36 | 95 | 855 | ["Manu Ginobili", "Tony Parker", "Manu Ginobili", "Tony Parker", "Manu Ginobili", "Tony Parker", "Manu Ginobili", "Tony Parker", "Tony Parker"] | ["Manu Ginobili", "Tony Parker"] |
| ("Tony Parker") | ("Tony Parker") | 8 | 8 | 3 | 33 | 95 | 750 | ["Manu Ginobili", "Tim Duncan", "LaMarcus Aldridge", "Manu Ginobili", "Manu Ginobili", "Tim Duncan", "LaMarcus Aldridge", "Tim Duncan"] | ["Manu Ginobili", "Tim Duncan", "LaMarcus Aldridge"] |
| ("Tony Parker") | ("Manu Ginobili") | 5 | 5 | 1 | 42 | 90 | 450 | ["Tim Duncan", "Tim Duncan", "Tim Duncan", "Tim Duncan", "Tim Duncan"] | ["Tim Duncan"] |

Scenario: [1] Basic GroupBy
When executing query:
Expand Down
101 changes: 100 additions & 1 deletion tests/tck/features/expression/Predicate.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# This source code is licensed under Apache 2.0 License.
Feature: Predicate

Scenario: yield a predicate
Scenario: basic
Given a graph with space named "nba"
When executing query:
"""
Expand Down Expand Up @@ -33,6 +33,105 @@ Feature: Predicate
Then the result should be, in any order:
| r |
| True |
When executing query:
"""
YIELD ALL(n in null WHERE TRUE) AS a, ANY(n in null WHERE TRUE) AS b, SINGLE(n in null WHERE TRUE) AS c, NONE(n in null WHERE TRUE) AS d
"""
Then the result should be, in any order:
| a | b | c | d |
| NULL | NULL | NULL | NULL |
When executing query:
"""
WITH 1 AS a
RETURN ALL(a IN [2, 3] WHERE a > 1) AS r
"""
Then the result should be, in any order:
| r |
| True |
When executing query:
"""
RETURN ALL(a IN [2, 3] WHERE a > 2) AS r
"""
Then the result should be, in any order:
| r |
| False |
When executing query:
"""
RETURN ALL(a IN [2, 3, NULL] WHERE a > 0) AS r
"""
Then the result should be, in any order:
| r |
| NULL |
When executing query:
"""
RETURN Any(a IN [2, 3] WHERE a > 1) AS r
"""
Then the result should be, in any order:
| r |
| True |
When executing query:
"""
RETURN Any(a IN [2, 3] WHERE a > 3) AS r
"""
Then the result should be, in any order:
| r |
| False |
When executing query:
"""
RETURN Any(a IN [2, 3, NULL] WHERE a > 3) AS r
"""
Then the result should be, in any order:
| r |
| NULL |
When executing query:
"""
RETURN Single(a IN [2, 3] WHERE a > 4) AS r
"""
Then the result should be, in any order:
| r |
| False |
When executing query:
"""
RETURN Single(a IN [2, 3, 4] WHERE a >= 2) AS r
"""
Then the result should be, in any order:
| r |
| False |
When executing query:
"""
RETURN Single(a IN [2, 3, 4] WHERE a == 3) AS r
"""
Then the result should be, in any order:
| r |
| True |
When executing query:
"""
RETURN Single(a IN [2, 3, NULL] WHERE a == 3) AS r
"""
Then the result should be, in any order:
| r |
| NULL |
When executing query:
"""
RETURN None(a IN [2, 3, NULL] WHERE a > 1) AS r
"""
Then the result should be, in any order:
| r |
| False |
When executing query:
"""
RETURN None(a IN [2, 3, 4] WHERE a > 100) AS r
"""
Then the result should be, in any order:
| r |
| True |
When executing query:
"""
RETURN None(a IN [2, 3, NULL] WHERE a > 3) AS r
"""
Then the result should be, in any order:
| r |
| NULL |

Scenario: use a predicate in GO
Given a graph with space named "nba"
Expand Down
20 changes: 20 additions & 0 deletions tests/tck/features/go/GroupbyLimit.feature
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,26 @@ Feature: Groupby & limit Sentence
"""
Then the result should be, in any order, with relax comparison:
| name |
When executing query:
"""
GO FROM "Danny Green" OVER serve YIELD $$.team.name AS name | LIMIT 3.0, 2
"""
Then a SyntaxError should be raised at runtime: syntax error near `3.0'
When executing query:
"""
GO FROM "Danny Green" OVER serve YIELD $$.team.name AS name | LIMIT 3, 2.0
"""
Then a SyntaxError should be raised at runtime: syntax error near `2.0'
When executing query:
"""
GO FROM "Danny Green" OVER serve YIELD $$.team.name AS name | LIMIT 1+2
"""
Then a SyntaxError should be raised at runtime: syntax error near `+2'
When executing query:
"""
GO FROM "Danny Green" OVER serve YIELD $$.team.name AS name | LIMIT 3, 1+1
"""
Then a SyntaxError should be raised at runtime: syntax error near `+1'

Scenario: OFFSET 0
When executing query:
Expand Down
20 changes: 20 additions & 0 deletions tests/tck/features/go/Orderby.feature
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,23 @@ Feature: Orderby Sentence
GO FROM "Boris Diaw" OVER serve YIELD $^.player.name as team, serve.start_year as start, $$.team.name as team | ORDER BY $-.team
"""
Then a SemanticError should be raised at runtime:

Scenario: Order by with null
When executing query:
"""
UNWIND [3, NULL, 1] AS a
UNWIND [1, 4, NULL] AS b
RETURN a, b
ORDER BY a ASC, b DESC
"""
Then the result should be, in order, with relax comparison:
| a | b |
| 1 | NULL |
| 1 | 4 |
| 1 | 1 |
| 3 | NULL |
| 3 | 4 |
| 3 | 1 |
| NULL | NULL |
| NULL | 4 |
| NULL | 1 |
Loading