From b575189b9b8a1587a40ab11055c070cd5194a4a3 Mon Sep 17 00:00:00 2001 From: jimingquan Date: Mon, 22 Nov 2021 17:46:09 +0800 Subject: [PATCH] enhance match attribute filter (#3272) * enhance match attribute filter * add test case * fix test error * delete some null test * fix test error * fix storage crash --- src/graph/validator/MatchValidator.cpp | 58 ++++++++++------- src/graph/validator/MatchValidator.h | 13 ++-- src/graph/visitor/FoldConstantExprVisitor.cpp | 20 ++++-- .../visitor/test/FilterTransformTest.cpp | 12 ++-- src/parser/MatchSentence.h | 2 + src/storage/exec/IndexScanNode.cpp | 36 ++++++---- .../tck/features/expression/EndsWith.feature | 8 +-- tests/tck/features/expression/Null.feature | 24 +++---- .../features/expression/StartsWith.feature | 8 +-- .../expression/function/Mathematical.feature | 4 +- .../function/TypeConversion.feature | 45 ++++++++----- tests/tck/features/go/GO.feature | 4 +- tests/tck/features/lookup/ByIndex.feature | 4 +- .../features/lookup/ByIndex.intVid.feature | 4 +- tests/tck/features/match/Base.IntVid.feature | 64 +++++++++++++++++- tests/tck/features/match/Base.feature | 65 ++++++++++++++++++- tests/tck/features/schema/Schema.feature | 2 +- tests/tck/features/yield/yield.IntVid.feature | 18 ++--- tests/tck/features/yield/yield.feature | 18 ++--- 19 files changed, 281 insertions(+), 128 deletions(-) diff --git a/src/graph/validator/MatchValidator.cpp b/src/graph/validator/MatchValidator.cpp index 905ffe158d4..5789a41e593 100644 --- a/src/graph/validator/MatchValidator.cpp +++ b/src/graph/validator/MatchValidator.cpp @@ -112,8 +112,7 @@ Status MatchValidator::validateImpl() { return Status::OK(); } -Status MatchValidator::validatePath(const MatchPath *path, - MatchClauseContext &matchClauseCtx) const { +Status MatchValidator::validatePath(const MatchPath *path, MatchClauseContext &matchClauseCtx) { NG_RETURN_IF_ERROR( buildNodeInfo(path, matchClauseCtx.nodeInfos, matchClauseCtx.aliasesGenerated)); NG_RETURN_IF_ERROR( @@ -122,8 +121,7 @@ Status MatchValidator::validatePath(const MatchPath *path, return Status::OK(); } -Status MatchValidator::buildPathExpr(const MatchPath *path, - MatchClauseContext &matchClauseCtx) const { +Status MatchValidator::buildPathExpr(const MatchPath *path, MatchClauseContext &matchClauseCtx) { auto *pathAlias = path->alias(); if (pathAlias == nullptr) { return Status::OK(); @@ -148,7 +146,7 @@ Status MatchValidator::buildPathExpr(const MatchPath *path, Status MatchValidator::buildNodeInfo(const MatchPath *path, std::vector &nodeInfos, - std::unordered_map &aliases) const { + std::unordered_map &aliases) { auto *sm = qctx_->schemaMng(); auto steps = path->steps(); auto *pool = qctx_->objPool(); @@ -182,7 +180,7 @@ Status MatchValidator::buildNodeInfo(const MatchPath *path, } Expression *filter = nullptr; if (props != nullptr) { - auto result = makeNodeSubFilter(props, "*"); + auto result = makeNodeSubFilter(const_cast(props), "*"); NG_RETURN_IF_ERROR(result); filter = result.value(); } else if (node->labels() != nullptr && !node->labels()->labels().empty()) { @@ -204,7 +202,7 @@ Status MatchValidator::buildNodeInfo(const MatchPath *path, Status MatchValidator::buildEdgeInfo(const MatchPath *path, std::vector &edgeInfos, - std::unordered_map &aliases) const { + std::unordered_map &aliases) { auto *sm = qctx_->schemaMng(); auto steps = path->steps(); edgeInfos.resize(steps); @@ -250,7 +248,7 @@ Status MatchValidator::buildEdgeInfo(const MatchPath *path, } Expression *filter = nullptr; if (props != nullptr) { - auto result = makeEdgeSubFilter(props); + auto result = makeEdgeSubFilter(const_cast(props)); NG_RETURN_IF_ERROR(result); filter = result.value(); } @@ -521,32 +519,40 @@ Status MatchValidator::validateUnwind(const UnwindClause *unwindClause, return Status::OK(); } -StatusOr MatchValidator::makeEdgeSubFilter(const MapExpression *map) const { +StatusOr MatchValidator::makeEdgeSubFilter(MapExpression *map) const { auto *pool = qctx_->objPool(); DCHECK(map != nullptr); auto &items = map->items(); DCHECK(!items.empty()); - if (!ExpressionUtils::isEvaluableExpr(items[0].second)) { - return Status::SemanticError("Props must be constant: `%s'", + auto foldStatus = ExpressionUtils::foldConstantExpr(items[0].second); + NG_RETURN_IF_ERROR(foldStatus); + auto foldExpr = foldStatus.value(); + if (!ExpressionUtils::isEvaluableExpr(foldExpr)) { + return Status::SemanticError("Props must be evaluable: `%s'", items[0].second->toString().c_str()); } + map->setItem(0, std::make_pair(items[0].first, foldExpr)); Expression *root = RelationalExpression::makeEQ( - pool, EdgePropertyExpression::make(pool, "*", items[0].first), items[0].second->clone()); + pool, EdgePropertyExpression::make(pool, "*", items[0].first), foldExpr); for (auto i = 1u; i < items.size(); i++) { - if (!ExpressionUtils::isEvaluableExpr(items[i].second)) { - return Status::SemanticError("Props must be constant: `%s'", + foldStatus = ExpressionUtils::foldConstantExpr(items[i].second); + NG_RETURN_IF_ERROR(foldStatus); + foldExpr = foldStatus.value(); + if (!ExpressionUtils::isEvaluableExpr(foldExpr)) { + return Status::SemanticError("Props must be evaluable: `%s'", items[i].second->toString().c_str()); } + map->setItem(0, std::make_pair(items[i].first, foldExpr)); auto *left = root; auto *right = RelationalExpression::makeEQ( - pool, EdgePropertyExpression::make(pool, "*", items[i].first), items[i].second->clone()); + pool, EdgePropertyExpression::make(pool, "*", items[i].first), foldExpr); root = LogicalExpression::makeAnd(pool, left, right); } return root; } -StatusOr MatchValidator::makeNodeSubFilter(const MapExpression *map, +StatusOr MatchValidator::makeNodeSubFilter(MapExpression *map, const std::string &label) const { auto *pool = qctx_->objPool(); // Node has tag without property @@ -562,20 +568,28 @@ StatusOr MatchValidator::makeNodeSubFilter(const MapExpression *ma auto &items = map->items(); DCHECK(!items.empty()); - if (!ExpressionUtils::isEvaluableExpr(items[0].second)) { - return Status::SemanticError("Props must be constant: `%s'", + auto foldStatus = ExpressionUtils::foldConstantExpr(items[0].second); + NG_RETURN_IF_ERROR(foldStatus); + auto foldExpr = foldStatus.value(); + if (!ExpressionUtils::isEvaluableExpr(foldExpr)) { + return Status::SemanticError("Props must be evaluable: `%s'", items[0].second->toString().c_str()); } + map->setItem(0, std::make_pair(items[0].first, foldExpr)); Expression *root = RelationalExpression::makeEQ( - pool, TagPropertyExpression::make(pool, label, items[0].first), items[0].second->clone()); + pool, TagPropertyExpression::make(pool, label, items[0].first), foldExpr); for (auto i = 1u; i < items.size(); i++) { - if (!ExpressionUtils::isEvaluableExpr(items[i].second)) { - return Status::SemanticError("Props must be constant: `%s'", + foldStatus = ExpressionUtils::foldConstantExpr(items[i].second); + NG_RETURN_IF_ERROR(foldStatus); + foldExpr = foldStatus.value(); + if (!ExpressionUtils::isEvaluableExpr(foldExpr)) { + return Status::SemanticError("Props must be evaluable: `%s'", items[i].second->toString().c_str()); } + map->setItem(i, std::make_pair(items[i].first, foldExpr)); auto *left = root; auto *right = RelationalExpression::makeEQ( - pool, TagPropertyExpression::make(pool, label, items[i].first), items[i].second->clone()); + pool, TagPropertyExpression::make(pool, label, items[i].first), foldExpr); root = LogicalExpression::makeAnd(pool, left, right); } return root; diff --git a/src/graph/validator/MatchValidator.h b/src/graph/validator/MatchValidator.h index 14259adc8d5..e62743f4e6e 100644 --- a/src/graph/validator/MatchValidator.h +++ b/src/graph/validator/MatchValidator.h @@ -25,7 +25,7 @@ class MatchValidator final : public Validator { AstContext *getAstContext() override; - Status validatePath(const MatchPath *path, MatchClauseContext &matchClauseCtx) const; + Status validatePath(const MatchPath *path, MatchClauseContext &matchClauseCtx); Status validateFilter(const Expression *filter, WhereClauseContext &whereClauseCtx) const; @@ -68,13 +68,13 @@ class MatchValidator final : public Validator { Status buildNodeInfo(const MatchPath *path, std::vector &edgeInfos, - std::unordered_map &aliases) const; + std::unordered_map &aliases); Status buildEdgeInfo(const MatchPath *path, std::vector &nodeInfos, - std::unordered_map &aliases) const; + std::unordered_map &aliases); - Status buildPathExpr(const MatchPath *path, MatchClauseContext &matchClauseCtx) const; + Status buildPathExpr(const MatchPath *path, MatchClauseContext &matchClauseCtx); Status combineAliases(std::unordered_map &curAliases, const std::unordered_map &lastAliases) const; @@ -89,10 +89,9 @@ class MatchValidator final : public Validator { Status buildOutputs(const YieldColumns *yields); - StatusOr makeEdgeSubFilter(const MapExpression *map) const; + StatusOr makeEdgeSubFilter(MapExpression *map) const; - StatusOr makeNodeSubFilter(const MapExpression *map, - const std::string &label) const; + StatusOr makeNodeSubFilter(MapExpression *map, const std::string &label) const; private: std::unique_ptr matchCtx_; diff --git a/src/graph/visitor/FoldConstantExprVisitor.cpp b/src/graph/visitor/FoldConstantExprVisitor.cpp index dd970696774..5b5015e2279 100644 --- a/src/graph/visitor/FoldConstantExprVisitor.cpp +++ b/src/graph/visitor/FoldConstantExprVisitor.cpp @@ -346,17 +346,25 @@ Expression *FoldConstantExprVisitor::fold(Expression *expr) { auto value = expr->eval(ctx(nullptr)); if (value.type() == Value::Type::NULLVALUE) { switch (value.getNull()) { - case NullType::DIV_BY_ZERO: + case NullType::DIV_BY_ZERO: { canBeFolded_ = false; - status_ = Status::Error("/ by zero"); + status_ = Status::SemanticError("Divide by 0"); break; - case NullType::ERR_OVERFLOW: + } + case NullType::ERR_OVERFLOW: { + canBeFolded_ = false; + status_ = Status::SemanticError("result of %s cannot be represented as an integer", + expr->toString().c_str()); + break; + } + case NullType::BAD_TYPE: { canBeFolded_ = false; - status_ = Status::Error("result of %s cannot be represented as an integer", - expr->toString().c_str()); + status_ = Status::SemanticError("Type error `%s'", expr->toString().c_str()); break; - default: + } + default: { break; + } } } else { status_ = Status::OK(); diff --git a/src/graph/visitor/test/FilterTransformTest.cpp b/src/graph/visitor/test/FilterTransformTest.cpp index 7e949b64b4c..41eab24c428 100644 --- a/src/graph/visitor/test/FilterTransformTest.cpp +++ b/src/graph/visitor/test/FilterTransformTest.cpp @@ -29,7 +29,7 @@ TEST_F(FilterTransformTest, TestCalculationOverflow) { auto expr = ltExpr(minusExpr(laExpr("v", "age"), constantExpr(1)), constantExpr(9223372036854775807)); auto res = ExpressionUtils::filterTransform(expr); - auto expected = Status::Error( + auto expected = Status::SemanticError( "result of (9223372036854775807+1) cannot be represented as an " "integer"); ASSERT(!res.status().ok()); @@ -39,7 +39,7 @@ TEST_F(FilterTransformTest, TestCalculationOverflow) { { auto expr = ltExpr(addExpr(laExpr("v", "age"), constantExpr(1)), constantExpr(INT64_MIN)); auto res = ExpressionUtils::filterTransform(expr); - auto expected = Status::Error( + auto expected = Status::SemanticError( "result of (-9223372036854775808-1) cannot be represented as an " "integer"); ASSERT(!res.status().ok()); @@ -50,7 +50,7 @@ TEST_F(FilterTransformTest, TestCalculationOverflow) { auto expr = ltExpr(minusExpr(laExpr("v", "age"), constantExpr(1)), addExpr(constantExpr(9223372036854775807), constantExpr(1))); auto res = ExpressionUtils::filterTransform(expr); - auto expected = Status::Error( + auto expected = Status::SemanticError( "result of (9223372036854775807+1) cannot be represented as an " "integer"); ASSERT(!res.status().ok()); @@ -61,7 +61,7 @@ TEST_F(FilterTransformTest, TestCalculationOverflow) { auto expr = ltExpr(addExpr(laExpr("v", "age"), constantExpr(1)), minusExpr(constantExpr(INT64_MIN), constantExpr(1))); auto res = ExpressionUtils::filterTransform(expr); - auto expected = Status::Error( + auto expected = Status::SemanticError( "result of (-9223372036854775808-1) cannot be represented as an " "integer"); ASSERT(!res.status().ok()); @@ -72,7 +72,7 @@ TEST_F(FilterTransformTest, TestCalculationOverflow) { auto expr = notExpr(notExpr(notExpr(ltExpr(minusExpr(laExpr("v", "age"), constantExpr(1)), constantExpr(9223372036854775807))))); auto res = ExpressionUtils::filterTransform(expr); - auto expected = Status::Error( + auto expected = Status::SemanticError( "result of (9223372036854775807+1) cannot be represented as an " "integer"); ASSERT(!res.status().ok()); @@ -83,7 +83,7 @@ TEST_F(FilterTransformTest, TestCalculationOverflow) { auto expr = notExpr(notExpr( notExpr(ltExpr(addExpr(laExpr("v", "age"), constantExpr(1)), constantExpr(INT64_MIN))))); auto res = ExpressionUtils::filterTransform(expr); - auto expected = Status::Error( + auto expected = Status::SemanticError( "result of (-9223372036854775808-1) cannot be represented as an " "integer"); ASSERT(!res.status().ok()); diff --git a/src/parser/MatchSentence.h b/src/parser/MatchSentence.h index 4390650b164..244a43efb11 100644 --- a/src/parser/MatchSentence.h +++ b/src/parser/MatchSentence.h @@ -165,6 +165,8 @@ class MatchNode final { const MapExpression* props() const { return props_; } + MapExpression* props() { return props_; } + std::string toString() const; private: diff --git a/src/storage/exec/IndexScanNode.cpp b/src/storage/exec/IndexScanNode.cpp index 41e6cf17b5a..426f02d752e 100644 --- a/src/storage/exec/IndexScanNode.cpp +++ b/src/storage/exec/IndexScanNode.cpp @@ -61,20 +61,30 @@ std::string Path::encodeValue(const Value& value, std::string& key) { std::string val; bool isNull = false; - if (colDef.get_type() == ::nebula::cpp2::PropertyType::GEOGRAPHY) { - CHECK_EQ(value.type(), Value::Type::STRING); - val = value.getStr(); - } else if (value.type() == Value::Type::STRING) { - val = IndexKeyUtils::encodeValue(value, *colDef.get_type_length()); - if (val.back() != '\0') { - strategySet_.insert(QualifiedStrategy::constant()); + switch (colDef.get_type()) { + case ::nebula::cpp2::PropertyType::STRING: + case ::nebula::cpp2::PropertyType::FIXED_STRING: { + if (value.type() == Value::Type::NULLVALUE) { + val = IndexKeyUtils::encodeNullValue(Value::Type::STRING, colDef.get_type_length()); + isNull = true; + } else { + val = IndexKeyUtils::encodeValue(value, *colDef.get_type_length()); + if (val.back() != '\0') { + strategySet_.insert(QualifiedStrategy::constant()); + } + } + break; + } + default: { + if (value.type() == Value::Type::NULLVALUE) { + auto vType = IndexKeyUtils::toValueType(colDef.get_type()); + val = IndexKeyUtils::encodeNullValue(vType, colDef.get_type_length()); + isNull = true; + } else { + val = IndexKeyUtils::encodeValue(value); + } + break; } - } else if (value.type() == Value::Type::NULLVALUE) { - auto vtype = IndexKeyUtils::toValueType(colDef.get_type()); - val = IndexKeyUtils::encodeNullValue(vtype, colDef.get_type_length()); - isNull = true; - } else { - val = IndexKeyUtils::encodeValue(value); } // If the current colDef can be null, then it is necessary to additionally determine whether the // corresponding value under a nullable is null when parsing the key (the encoding of the maximum diff --git a/tests/tck/features/expression/EndsWith.feature b/tests/tck/features/expression/EndsWith.feature index 8da777c0715..51212924c6c 100644 --- a/tests/tck/features/expression/EndsWith.feature +++ b/tests/tck/features/expression/EndsWith.feature @@ -60,9 +60,7 @@ Feature: Ends With Expression """ YIELD 123 ENDS WITH 3 """ - Then the result should be, in any order: - | (123 ENDS WITH 3) | - | BAD_TYPE | + Then a SemanticError should be raised at runtime: Type error `(123 ENDS WITH 3)' Scenario: yield not ends with When executing query: @@ -118,9 +116,7 @@ Feature: Ends With Expression """ YIELD 123 NOT ENDS WITH 3 """ - Then the result should be, in any order: - | (123 NOT ENDS WITH 3) | - | BAD_TYPE | + Then a SemanticError should be raised at runtime: Type error `(123 NOT ENDS WITH 3)' Scenario: ends with go When executing query: diff --git a/tests/tck/features/expression/Null.feature b/tests/tck/features/expression/Null.feature index 2044d72b542..e4616dbedc4 100644 --- a/tests/tck/features/expression/Null.feature +++ b/tests/tck/features/expression/Null.feature @@ -24,11 +24,11 @@ Feature: NULL related operations | NULL | NULL | NULL | NULL | NULL | When executing query: """ - RETURN cbrt(NULL) AS value1, hypot(NULL, NULL) AS value2, pow(NULL, NULL) AS value3, exp(NULL) AS value4, exp2(NULL) AS value5 + RETURN cbrt(NULL) AS value1, exp(NULL) AS value4, exp2(NULL) AS value5 """ Then the result should be, in any order: - | value1 | value2 | value3 | value4 | value5 | - | NULL | BAD_TYPE | BAD_TYPE | NULL | NULL | + | value1 | value4 | value5 | + | NULL | NULL | NULL | When executing query: """ RETURN log(NULL) AS value1, log2(NULL) AS value2, log10(NULL) AS value3, sin(NULL) AS value4, asin(NULL) AS value5 @@ -38,18 +38,18 @@ Feature: NULL related operations | NULL | NULL | NULL | NULL | NULL | When executing query: """ - RETURN cos(NULL) AS value1, acos(NULL) AS value2, tan(NULL) AS value3, atan(NULL) AS value4, rand32(NULL) AS value5 + RETURN cos(NULL) AS value1, acos(NULL) AS value2, tan(NULL) AS value3, atan(NULL) AS value4 """ Then the result should be, in any order: - | value1 | value2 | value3 | value4 | value5 | - | NULL | NULL | NULL | NULL | BAD_TYPE | + | value1 | value2 | value3 | value4 | + | NULL | NULL | NULL | NULL | When executing query: """ - RETURN collect(NULL) AS value1, avg(NULL) AS value2, count(NULL) AS value3, max(NULL) AS value4, rand64(NULL,NULL) AS value5 + RETURN collect(NULL) AS value1, avg(NULL) AS value2, count(NULL) AS value3, max(NULL) AS value4 """ Then the result should be, in any order: - | value1 | value2 | value3 | value4 | value5 | - | [] | NULL | 0 | NULL | BAD_TYPE | + | value1 | value2 | value3 | value4 | + | [] | NULL | 0 | NULL | When executing query: """ RETURN min(NULL) AS value1, std(NULL) AS value2, sum(NULL) AS value3, bit_and(NULL) AS value4, bit_or(NULL,NULL) AS value5 @@ -59,8 +59,8 @@ Feature: NULL related operations | NULL | NULL | 0 | NULL | NULL | When executing query: """ - RETURN bit_xor(NULL) AS value1, size(NULL) AS value2, range(NULL,NULL) AS value3, sign(NULL) AS value4, radians(NULL) AS value5 + RETURN bit_xor(NULL) AS value1, size(NULL) AS value2, sign(NULL) AS value4, radians(NULL) AS value5 """ Then the result should be, in any order: - | value1 | value2 | value3 | value4 | value5 | - | NULL | NULL | BAD_TYPE | NULL | NULL | + | value1 | value2 | value4 | value5 | + | NULL | NULL | NULL | NULL | diff --git a/tests/tck/features/expression/StartsWith.feature b/tests/tck/features/expression/StartsWith.feature index 4410ca986c0..782fe02d414 100644 --- a/tests/tck/features/expression/StartsWith.feature +++ b/tests/tck/features/expression/StartsWith.feature @@ -46,9 +46,7 @@ Feature: Starts With Expression """ YIELD 123 STARTS WITH 1 """ - Then the result should be, in any order: - | (123 STARTS WITH 1) | - | BAD_TYPE | + Then a SemanticError should be raised at runtime: Type error `(123 STARTS WITH 1)' Scenario: yield not starts with When executing query: @@ -90,9 +88,7 @@ Feature: Starts With Expression """ YIELD 123 NOT STARTS WITH 1 """ - Then the result should be, in any order: - | (123 NOT STARTS WITH 1) | - | BAD_TYPE | + Then a SemanticError should be raised at runtime: Type error `(123 NOT STARTS WITH 1)' Scenario: starts with go When executing query: diff --git a/tests/tck/features/expression/function/Mathematical.feature b/tests/tck/features/expression/function/Mathematical.feature index 656658d1168..cecdd0e40e5 100644 --- a/tests/tck/features/expression/function/Mathematical.feature +++ b/tests/tck/features/expression/function/Mathematical.feature @@ -22,6 +22,4 @@ Feature: Mathematical function Expression """ return [bit_and(5,true),bit_or(2,1.3),bit_xor("5",1)] as error_test """ - Then the result should be, in any order: - | error_test | - | [BAD_TYPE, BAD_TYPE, BAD_TYPE] | + Then a SemanticError should be raised at runtime: Type error `bit_and(5,true)' diff --git a/tests/tck/features/expression/function/TypeConversion.feature b/tests/tck/features/expression/function/TypeConversion.feature index a2481adb3d8..c3e83ccb30b 100644 --- a/tests/tck/features/expression/function/TypeConversion.feature +++ b/tests/tck/features/expression/function/TypeConversion.feature @@ -9,72 +9,81 @@ Feature: TypeConversion Expression Scenario: toBoolean When executing query: """ - YIELD [toBoolean(true), toBoolean(false), toBoolean(1), toBoolean(3.14), + YIELD [toBoolean(true), toBoolean(false), toBoolean("trUe"), toBoolean("3.14"), toBoolean(null)] AS yield_toBoolean """ Then the result should be, in any order: - | yield_toBoolean | - | [true, false, BAD_TYPE, BAD_TYPE, true, NULL, NULL] | + | yield_toBoolean | + | [true, false, true, NULL, NULL] | When executing query: """ - UNWIND [true, false, 1, 3.14, "trUe", "3.14", null] AS b + UNWIND [true, false, "trUe", "3.14", null] AS b RETURN toBoolean(b) AS unwind_toBoolean """ Then the result should be, in any order: | unwind_toBoolean | | true | | false | - | BAD_TYPE | - | BAD_TYPE | | true | | NULL | | NULL | + When executing query: + """ + YIELD [toBoolean(1), toBoolean(3.14)] AS yield_toBoolean + """ + Then a SemanticError should be raised at runtime: Type error `toBoolean(1)' Scenario: toFloat When executing query: """ - YIELD [toFloat(true), toFloat(false), toFloat(1), toFloat(3.14), + YIELD [toFloat(1), toFloat(3.14), toFloat("trUe"), toFloat("3.14"), toFloat(null)] AS yield_toFloat """ Then the result should be, in any order: - | yield_toFloat | - | [BAD_TYPE, BAD_TYPE, 1.0, 3.14, NULL, 3.14, NULL] | + | yield_toFloat | + | [1.0, 3.14, NULL, 3.14, NULL] | When executing query: """ - UNWIND [true, false, 1, 3.14, "trUe", "3.14", null] AS b + UNWIND [1, 3.14, "trUe", "3.14", null] AS b RETURN toFloat(b) AS unwind_toFloat """ Then the result should be, in any order: | unwind_toFloat | - | BAD_TYPE | - | BAD_TYPE | | 1.0 | | 3.14 | | NULL | | 3.14 | | NULL | + When executing query: + """ + YIELD [toFloat(true), toFloat(false)] AS yield_toFloat + """ + Then a SemanticError should be raised at runtime: Type error `toFloat(true)' Scenario: toInteger When executing query: """ - YIELD [toInteger(true), toInteger(false), toInteger(1), toInteger(3.14), + YIELD [toInteger(1), toInteger(3.14), toInteger("trUe"), toInteger("3.14"), toInteger(null), toInteger("1e3"), toInteger("1E3"), toInteger("1.5E4")] AS yield_toInteger """ Then the result should be, in any order: - | yield_toInteger | - | [BAD_TYPE, BAD_TYPE, 1, 3, NULL, 3, NULL, 1000, 1000, 15000] | + | yield_toInteger | + | [1, 3, NULL, 3, NULL, 1000, 1000, 15000] | When executing query: """ - UNWIND [true, false, 1, 3.14, "trUe", "3.14", null] AS b + UNWIND [1, 3.14, "trUe", "3.14", null] AS b RETURN toInteger(b) AS unwind_toInteger """ Then the result should be, in any order: | unwind_toInteger | - | BAD_TYPE | - | BAD_TYPE | | 1 | | 3 | | NULL | | 3 | | NULL | + When executing query: + """ + YIELD [toInteger(true), toInteger(false)] AS yield_toInteger + """ + Then a SemanticError should be raised at runtime: Type error `toInteger(true)' diff --git a/tests/tck/features/go/GO.feature b/tests/tck/features/go/GO.feature index 7878a3f9017..e48ead1ab2b 100644 --- a/tests/tck/features/go/GO.feature +++ b/tests/tck/features/go/GO.feature @@ -18,12 +18,12 @@ Feature: Go Sentence """ GO FROM "Tim Duncan", "Tony Parker" OVER like WHERE $$.player.age > 9223372036854775807+1 YIELD like._dst """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer When executing query: """ GO FROM "Tim Duncan", "Tony Parker" OVER like WHERE $$.player.age > -9223372036854775808-1 YIELD like._dst """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer When executing query: """ GO FROM "Tim Duncan" OVER like YIELD $^.player.name as name, $^.player.age as age diff --git a/tests/tck/features/lookup/ByIndex.feature b/tests/tck/features/lookup/ByIndex.feature index d6df792509c..f12621b80fd 100644 --- a/tests/tck/features/lookup/ByIndex.feature +++ b/tests/tck/features/lookup/ByIndex.feature @@ -94,12 +94,12 @@ Feature: Lookup by index itself """ LOOKUP ON player WHERE player.age > 9223372036854775807+1 """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer When executing query: """ LOOKUP ON player WHERE player.age > -9223372036854775808-1 """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer Scenario: [2] edge index Given a graph with space named "nba" diff --git a/tests/tck/features/lookup/ByIndex.intVid.feature b/tests/tck/features/lookup/ByIndex.intVid.feature index 7f6c3466b63..5dd9e4aaa5c 100644 --- a/tests/tck/features/lookup/ByIndex.intVid.feature +++ b/tests/tck/features/lookup/ByIndex.intVid.feature @@ -94,12 +94,12 @@ Feature: Lookup by index itself in integer vid """ LOOKUP ON player WHERE player.age > 9223372036854775807+1 """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer When executing query: """ LOOKUP ON player WHERE player.age > -9223372036854775808-1 """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer Scenario: [2] edge index Given a graph with space named "nba_int_vid" diff --git a/tests/tck/features/match/Base.IntVid.feature b/tests/tck/features/match/Base.IntVid.feature index 0b95df4156d..d06379f3775 100644 --- a/tests/tck/features/match/Base.IntVid.feature +++ b/tests/tck/features/match/Base.IntVid.feature @@ -59,12 +59,12 @@ Feature: Basic match """ MATCH (v:player) where v.age > 9223372036854775807+1 return v """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer When executing query: """ MATCH (v:player) where v.age > -9223372036854775808-1 return v """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer Scenario: Une step When executing query: @@ -415,6 +415,66 @@ Feature: Basic match | [:like "Tony Parker"->"Manu Ginobili" @0 {likeness: 95}] | | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | + Scenario: filter evaluable + When executing query: + """ + match (v:player{age: -1}) return v + """ + Then the result should be, in any order, with relax comparison: + | v | + When executing query: + """ + match (v:player{age: +20}) return v + """ + Then the result should be, in any order, with relax comparison: + | v | + | ("Luka Doncic" :player{age: 20, name: "Luka Doncic"}) | + When executing query: + """ + match (v:player{age: 1+19}) return v + """ + Then the result should be, in any order, with relax comparison: + | v | + | ("Luka Doncic" :player{age: 20, name: "Luka Doncic"}) | + When executing query: + """ + match (v:player)-[e:like{likeness:-1}]->() return e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [:like "Blake Griffin"->"Chris Paul" @0 {likeness: -1}] | + | [:like "Rajon Rondo"->"Ray Allen" @0 {likeness: -1}] | + When executing query: + """ + match (v:player)-[e:like{likeness:40+50+5}]->() return e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [:like "Tim Duncan"->"Manu Ginobili" @0 {likeness: 95}] | + | [:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}] | + | [:like "Paul George"->"Russell Westbrook" @0 {likeness: 95}] | + | [:like "Tony Parker"->"Manu Ginobili" @0 {likeness: 95}] | + | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | + When executing query: + """ + match (v:player)-[e:like{likeness:4*20+5}]->() return e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [:like "Jason Kidd"->"Dirk Nowitzki"@0{likeness:85}] | + | [:like "Steve Nash"->"Jason Kidd"@0{likeness:85}] | + When executing query: + """ + match (v:player)-[e:like{likeness:"99"}]->() return e + """ + Then the result should be, in any order, with relax comparison: + | e | + When executing query: + """ + match (v:player{age:"24"-1}) return v + """ + Then a SemanticError should be raised at runtime: Type error `("24"-1)' + Scenario: No return When executing query: """ diff --git a/tests/tck/features/match/Base.feature b/tests/tck/features/match/Base.feature index 26227d58e9b..ddd9f76d970 100644 --- a/tests/tck/features/match/Base.feature +++ b/tests/tck/features/match/Base.feature @@ -97,12 +97,12 @@ Feature: Basic match """ MATCH (v:player) where v.age > 9223372036854775807+1 return v """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer When executing query: """ MATCH (v:player) where v.age > -9223372036854775808-1 return v """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775808-1) cannot be represented as an integer Scenario: One step When executing query: @@ -518,6 +518,67 @@ Feature: Basic match | [:like "Tony Parker"->"Manu Ginobili" @0 {likeness: 95}] | | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | + Scenario: filter evaluable + When executing query: + """ + match (v:player{age: -1}) return v + """ + Then the result should be, in any order, with relax comparison: + | v | + | ("Null1" :player{age: -1, name: NULL}) | + When executing query: + """ + match (v:player{age: +20}) return v + """ + Then the result should be, in any order, with relax comparison: + | v | + | ("Luka Doncic" :player{age: 20, name: "Luka Doncic"}) | + When executing query: + """ + match (v:player{age: 1+19}) return v + """ + Then the result should be, in any order, with relax comparison: + | v | + | ("Luka Doncic" :player{age: 20, name: "Luka Doncic"}) | + When executing query: + """ + match (v:player)-[e:like{likeness:-1}]->() return e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [:like "Blake Griffin"->"Chris Paul" @0 {likeness: -1}] | + | [:like "Rajon Rondo"->"Ray Allen" @0 {likeness: -1}] | + When executing query: + """ + match (v:player)-[e:like{likeness:40+50+5}]->() return e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [:like "Tim Duncan"->"Manu Ginobili" @0 {likeness: 95}] | + | [:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}] | + | [:like "Paul George"->"Russell Westbrook" @0 {likeness: 95}] | + | [:like "Tony Parker"->"Manu Ginobili" @0 {likeness: 95}] | + | [:like "Tony Parker"->"Tim Duncan" @0 {likeness: 95}] | + When executing query: + """ + match (v:player)-[e:like{likeness:4*20+5}]->() return e + """ + Then the result should be, in any order, with relax comparison: + | e | + | [:like "Jason Kidd"->"Dirk Nowitzki"@0{likeness:85}] | + | [:like "Steve Nash"->"Jason Kidd"@0{likeness:85}] | + When executing query: + """ + match (v:player)-[e:like{likeness:"99"}]->() return e + """ + Then the result should be, in any order, with relax comparison: + | e | + When executing query: + """ + match (v:player{age:"24"-1}) return v + """ + Then a SemanticError should be raised at runtime: Type error `("24"-1)' + Scenario: No return When executing query: """ diff --git a/tests/tck/features/schema/Schema.feature b/tests/tck/features/schema/Schema.feature index 252c3589bf6..b203ea87b62 100644 --- a/tests/tck/features/schema/Schema.feature +++ b/tests/tck/features/schema/Schema.feature @@ -655,7 +655,7 @@ Feature: Insert string vid of vertex and edge """ CREATE TAG bad_null_default_value(name string DEFAULT "N/A", age int DEFAULT 1%0) """ - Then a ExecutionError should be raised at runtime: / by zero + Then a SemanticError should be raised at runtime: Divide by 0 # test alter tag with wrong type default value of string when add When executing query: """ diff --git a/tests/tck/features/yield/yield.IntVid.feature b/tests/tck/features/yield/yield.IntVid.feature index e00a0c10284..7e0772a9d96 100644 --- a/tests/tck/features/yield/yield.IntVid.feature +++ b/tests/tck/features/yield/yield.IntVid.feature @@ -320,42 +320,42 @@ Feature: Yield Sentence """ YIELD 9223372036854775807+1 """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer When executing query: """ YIELD -9223372036854775807-2 """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775807-2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775807-2) cannot be represented as an integer When executing query: """ YIELD -9223372036854775807+-2 """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775807+-2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775807+-2) cannot be represented as an integer When executing query: """ YIELD 9223372036854775807*2 """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807*2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807*2) cannot be represented as an integer When executing query: """ YIELD -9223372036854775807*-2 """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775807*-2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775807*-2) cannot be represented as an integer When executing query: """ YIELD 9223372036854775807*-2 """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807*-2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807*-2) cannot be represented as an integer When executing query: """ YIELD 1/0 """ - Then a ExecutionError should be raised at runtime: / by zero + Then a SemanticError should be raised at runtime: Divide by 0 When executing query: """ YIELD 2%0 """ - Then a ExecutionError should be raised at runtime: / by zero + Then a SemanticError should be raised at runtime: Divide by 0 When executing query: """ YIELD -9223372036854775808 @@ -367,7 +367,7 @@ Feature: Yield Sentence """ YIELD --9223372036854775808 """ - Then a ExecutionError should be raised at runtime: result of -(-9223372036854775808) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of -(-9223372036854775808) cannot be represented as an integer When executing query: """ YIELD -9223372036854775809 diff --git a/tests/tck/features/yield/yield.feature b/tests/tck/features/yield/yield.feature index 01ca33e0b6a..254609ba9a7 100644 --- a/tests/tck/features/yield/yield.feature +++ b/tests/tck/features/yield/yield.feature @@ -330,42 +330,42 @@ Feature: Yield Sentence """ YIELD 9223372036854775807+1 """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807+1) cannot be represented as an integer When executing query: """ YIELD -9223372036854775807-2 """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775807-2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775807-2) cannot be represented as an integer When executing query: """ YIELD -9223372036854775807+-2 """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775807+-2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775807+-2) cannot be represented as an integer When executing query: """ YIELD 9223372036854775807*2 """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807*2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807*2) cannot be represented as an integer When executing query: """ YIELD -9223372036854775807*-2 """ - Then a ExecutionError should be raised at runtime: result of (-9223372036854775807*-2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (-9223372036854775807*-2) cannot be represented as an integer When executing query: """ YIELD 9223372036854775807*-2 """ - Then a ExecutionError should be raised at runtime: result of (9223372036854775807*-2) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of (9223372036854775807*-2) cannot be represented as an integer When executing query: """ YIELD 1/0 """ - Then a ExecutionError should be raised at runtime: / by zero + Then a SemanticError should be raised at runtime: Divide by 0 When executing query: """ YIELD 2%0 """ - Then a ExecutionError should be raised at runtime: / by zero + Then a SemanticError should be raised at runtime: Divide by 0 When executing query: """ YIELD -9223372036854775808 @@ -377,7 +377,7 @@ Feature: Yield Sentence """ YIELD --9223372036854775808 """ - Then a ExecutionError should be raised at runtime: result of -(-9223372036854775808) cannot be represented as an integer + Then a SemanticError should be raised at runtime: result of -(-9223372036854775808) cannot be represented as an integer When executing query: """ YIELD -9223372036854775809