diff --git a/src/graph/validator/Validator.cpp b/src/graph/validator/Validator.cpp index 687d4731492..7bcd2523972 100644 --- a/src/graph/validator/Validator.cpp +++ b/src/graph/validator/Validator.cpp @@ -36,6 +36,7 @@ #include "graph/validator/SetValidator.h" #include "graph/validator/UseValidator.h" #include "graph/validator/YieldValidator.h" +#include "graph/visitor/CheckDepthVisitor.h" #include "graph/visitor/DeduceTypeVisitor.h" #include "graph/visitor/EvaluableExprVisitor.h" #include "parser/Sentence.h" @@ -353,6 +354,11 @@ StatusOr Validator::deduceExprType(const Expression* expr) const { } Status Validator::deduceProps(const Expression* expr, ExpressionProps& exprProps) { + CheckDepthVisitor check_depth_visitor; + const_cast(expr)->accept(&check_depth_visitor); + if (!check_depth_visitor.ok()) { + return std::move(check_depth_visitor).status(); + } DeducePropsVisitor visitor(qctx_, space_.id, &exprProps, &userDefinedVarNameList_); const_cast(expr)->accept(&visitor); return std::move(visitor).status(); diff --git a/src/graph/visitor/CMakeLists.txt b/src/graph/visitor/CMakeLists.txt index bce16e2f074..09d7695f0a6 100644 --- a/src/graph/visitor/CMakeLists.txt +++ b/src/graph/visitor/CMakeLists.txt @@ -14,6 +14,7 @@ nebula_add_library( RewriteVisitor.cpp FindVisitor.cpp VidExtractVisitor.cpp + CheckDepthVisitor.cpp ) nebula_add_subdirectory(test) diff --git a/src/graph/visitor/CheckDepthVisitor.cpp b/src/graph/visitor/CheckDepthVisitor.cpp new file mode 100644 index 00000000000..aeefb6786ea --- /dev/null +++ b/src/graph/visitor/CheckDepthVisitor.cpp @@ -0,0 +1,251 @@ +/* Copyright (c) 2021 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#include "graph/visitor/CheckDepthVisitor.h" + +#include +#include + +#include "common/datatypes/DataSet.h" +#include "common/datatypes/Edge.h" +#include "common/datatypes/List.h" +#include "common/datatypes/Map.h" +#include "common/datatypes/Path.h" +#include "common/datatypes/Set.h" +#include "common/function/FunctionManager.h" +#include "graph/context/QueryContext.h" +#include "graph/context/QueryExpressionContext.h" +#include "graph/context/ValidateContext.h" +#include "graph/util/SchemaUtil.h" +#include "graph/visitor/EvaluableExprVisitor.h" + +namespace nebula { +namespace graph { + +CheckDepthVisitor::CheckDepthVisitor() {} + +void CheckDepthVisitor::visit(ConstantExpression *) {} + +void CheckDepthVisitor::visit(UnaryExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + expr->operand()->accept(this); +} + +void CheckDepthVisitor::visit(TypeCastingExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + expr->operand()->accept(this); + if (!ok()) return; +} + +void CheckDepthVisitor::visit(LabelExpression *) {} + +void CheckDepthVisitor::visit(ArithmeticExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + expr->left()->accept(this); + if (!ok()) return; + expr->right()->accept(this); +} + +void CheckDepthVisitor::visit(RelationalExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + expr->left()->accept(this); + if (!ok()) return; + expr->right()->accept(this); +} + +void CheckDepthVisitor::visit(SubscriptExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + expr->left()->accept(this); + if (!ok()) return; + expr->right()->accept(this); +} + +void CheckDepthVisitor::visit(AttributeExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + expr->left()->accept(this); + if (!ok()) return; + expr->right()->accept(this); +} + +void CheckDepthVisitor::visit(LogicalExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + auto &operands = expr->operands(); + for (auto i = 0u; i < operands.size(); i++) { + operands[i]->accept(this); + if (!ok()) return; + } +} + +void CheckDepthVisitor::visit(LabelAttributeExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + const_cast(expr->left())->accept(this); + if (!ok()) return; + const_cast(expr->right())->accept(this); +} + +void CheckDepthVisitor::visit(FunctionCallExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + for (auto &arg : expr->args()->args()) { + arg->accept(this); + if (!ok()) return; + } +} + +void CheckDepthVisitor::visit(AggregateExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + expr->arg()->accept(this); +} + +void CheckDepthVisitor::visit(CaseExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + if (expr->hasCondition()) { + expr->condition()->accept(this); + if (!ok()) return; + } + if (expr->hasDefault()) { + expr->defaultResult()->accept(this); + if (!ok()) return; + } + for (const auto &whenThen : expr->cases()) { + whenThen.when->accept(this); + if (!ok()) return; + whenThen.then->accept(this); + if (!ok()) return; + } +} + +void CheckDepthVisitor::visit(PredicateExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + if (expr->hasFilter()) { + expr->filter()->accept(this); + if (!ok()) { + return; + } + } + expr->collection()->accept(this); +} + +void CheckDepthVisitor::visit(ListComprehensionExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + if (expr->hasFilter()) { + expr->filter()->accept(this); + if (!ok()) { + return; + } + } + if (expr->hasMapping()) { + expr->mapping()->accept(this); + if (!ok()) { + return; + } + } + expr->collection()->accept(this); + if (!ok()) { + return; + } +} + +void CheckDepthVisitor::visit(ReduceExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + expr->initial()->accept(this); + if (!ok()) return; + expr->mapping()->accept(this); + if (!ok()) return; + expr->collection()->accept(this); + if (!ok()) return; +} + +void CheckDepthVisitor::visit(SubscriptRangeExpression *expr) { + checkDepth(); + SCOPE_EXIT { recoverDepth(); }; + if (!ok()) return; + expr->list()->accept(this); + if (!ok()) { + return; + } + if (expr->lo() != nullptr) { + expr->lo()->accept(this); + if (!ok()) { + return; + } + } + + if (expr->hi() != nullptr) { + expr->hi()->accept(this); + if (!ok()) { + return; + } + } +} + +void CheckDepthVisitor::visit(UUIDExpression *) {} + +void CheckDepthVisitor::visit(VariableExpression *) {} + +void CheckDepthVisitor::visit(VersionedVariableExpression *) {} + +void CheckDepthVisitor::visit(ListExpression *) {} + +void CheckDepthVisitor::visit(SetExpression *) {} + +void CheckDepthVisitor::visit(MapExpression *) {} + +void CheckDepthVisitor::visit(TagPropertyExpression *) {} + +void CheckDepthVisitor::visit(EdgePropertyExpression *) {} + +void CheckDepthVisitor::visit(InputPropertyExpression *) {} + +void CheckDepthVisitor::visit(VariablePropertyExpression *) {} + +void CheckDepthVisitor::visit(DestPropertyExpression *) {} + +void CheckDepthVisitor::visit(SourcePropertyExpression *) {} + +void CheckDepthVisitor::visit(EdgeSrcIdExpression *) {} + +void CheckDepthVisitor::visit(EdgeTypeExpression *) {} + +void CheckDepthVisitor::visit(EdgeRankExpression *) {} + +void CheckDepthVisitor::visit(EdgeDstIdExpression *) {} + +void CheckDepthVisitor::visit(VertexExpression *) {} + +void CheckDepthVisitor::visit(EdgeExpression *) {} + +void CheckDepthVisitor::visit(ColumnExpression *) {} + +void CheckDepthVisitor::visit(PathBuildExpression *) {} +} // namespace graph +} // namespace nebula diff --git a/src/graph/visitor/CheckDepthVisitor.h b/src/graph/visitor/CheckDepthVisitor.h new file mode 100644 index 00000000000..6aa1184c6cd --- /dev/null +++ b/src/graph/visitor/CheckDepthVisitor.h @@ -0,0 +1,96 @@ +/* Copyright (c) 2021 vesoft inc. All rights reserved. + * + * This source code is licensed under Apache 2.0 License. + */ + +#pragma once + +#include "common/base/Status.h" +#include "common/datatypes/Value.h" +#include "common/expression/ExprVisitor.h" +#include "graph/context/ValidateContext.h" + +namespace nebula { +namespace graph { + +class QueryContext; + +class CheckDepthVisitor final : public ExprVisitor { + public: + CheckDepthVisitor(); + ~CheckDepthVisitor() = default; + + bool ok() const { return status_.ok(); } + + Status status() && { return std::move(status_); } + + private: + void visit(ConstantExpression *) override; + void visit(UnaryExpression *expr) override; + void visit(TypeCastingExpression *expr) override; + void visit(LabelExpression *) override; + void visit(LabelAttributeExpression *expr) override; + // binary expression + void visit(ArithmeticExpression *expr) override; + void visit(RelationalExpression *expr) override; + void visit(SubscriptExpression *expr) override; + void visit(AttributeExpression *expr) override; + void visit(LogicalExpression *expr) override; + // function call + void visit(FunctionCallExpression *expr) override; + void visit(AggregateExpression *expr) override; + void visit(UUIDExpression *) override; + // variable expression + void visit(VariableExpression *) override; + void visit(VersionedVariableExpression *) override; + // container expression + void visit(ListExpression *) override; + void visit(SetExpression *) override; + void visit(MapExpression *) override; + // property Expression + void visit(TagPropertyExpression *) override; + void visit(EdgePropertyExpression *) override; + void visit(InputPropertyExpression *) override; + void visit(VariablePropertyExpression *) override; + void visit(DestPropertyExpression *) override; + void visit(SourcePropertyExpression *) override; + void visit(EdgeSrcIdExpression *) override; + void visit(EdgeTypeExpression *) override; + void visit(EdgeRankExpression *) override; + void visit(EdgeDstIdExpression *) override; + // vertex/edge expression + void visit(VertexExpression *) override; + void visit(EdgeExpression *) override; + // case expression + void visit(CaseExpression *expr) override; + // path build expression + void visit(PathBuildExpression *) override; + // column expression + void visit(ColumnExpression *) override; + // predicate expression + void visit(PredicateExpression *expr) override; + // list comprehension expression + void visit(ListComprehensionExpression *expr) override; + // reduce expression + void visit(ReduceExpression *expr) override; + // subscript range + void visit(SubscriptRangeExpression *expr) override; + + inline void checkDepth() { + if (++depth > MAX_DEPTH) { + status_ = Status::SemanticError( + "The above expression is not a valid expression, " + "because its depth exceeds the maximum depth"); + } + } + + inline void recoverDepth() { --depth; } + + Status status_; + + int32_t depth = 0; + const int32_t MAX_DEPTH = 512; +}; + +} // namespace graph +} // namespace nebula diff --git a/tests/tck/features/expression/Depth.feature b/tests/tck/features/expression/Depth.feature new file mode 100644 index 00000000000..df2447345e4 --- /dev/null +++ b/tests/tck/features/expression/Depth.feature @@ -0,0 +1,159 @@ +# Copyright (c) 2021 vesoft inc. All rights reserved. +# +# This source code is licensed under Apache 2.0 License. +Feature: Check Expression Depth + + Background: + Given a graph with space named "nba" + + Scenario: yield exceeds expression + When executing query: + """ + YIELD 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 AS result + """ + Then the result should be, in any order: + | result | + | 488 | + When executing query: + """ + YIELD 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 AS result + """ + Then a SemanticError should be raised at runtime: The above expression is not a valid expression, because its depth exceeds the maximum depth + When executing query: + """ + YIELD 1 IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS + NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL IS NULL AS result + """ + Then a SemanticError should be raised at runtime: The above expression is not a valid expression, because its depth exceeds the maximum depth