diff --git a/src/common/expression/AggregateExpression.h b/src/common/expression/AggregateExpression.h index 3f8a3212dbc..9f050217dce 100644 --- a/src/common/expression/AggregateExpression.h +++ b/src/common/expression/AggregateExpression.h @@ -78,6 +78,8 @@ class AggregateExpression final : public Expression { aggData_ = agg_data; } + void setDepth() override { setDepthFromSubExpr(arg_); } + private: explicit AggregateExpression(ObjectPool* pool, const std::string& name = "", @@ -89,6 +91,7 @@ class AggregateExpression final : public Expression { if (aggFuncResult.ok()) { aggFunc_ = std::move(aggFuncResult).value(); } + setDepth(); } void writeTo(Encoder& encoder) const override; diff --git a/src/common/expression/BinaryExpression.h b/src/common/expression/BinaryExpression.h index 37ce0e644b5..7c1df118e39 100644 --- a/src/common/expression/BinaryExpression.h +++ b/src/common/expression/BinaryExpression.h @@ -43,9 +43,16 @@ class BinaryExpression : public Expression { rhs_ = expr; } + void setDepth() override { + setDepthFromSubExpr(lhs_); + setDepthFromSubExpr(rhs_); + } + protected: BinaryExpression(ObjectPool* pool, Kind kind, Expression* lhs, Expression* rhs) - : Expression(pool, kind), lhs_(lhs), rhs_(rhs) {} + : Expression(pool, kind), lhs_(lhs), rhs_(rhs) { + setDepth(); + } void writeTo(Encoder& encoder) const override; diff --git a/src/common/expression/CaseExpression.h b/src/common/expression/CaseExpression.h index 0abbc11bfda..d0935440977 100644 --- a/src/common/expression/CaseExpression.h +++ b/src/common/expression/CaseExpression.h @@ -127,12 +127,20 @@ class CaseExpression final : public Expression { return expr; } + void setDepth() override { + for (auto& item : cases_) { + setDepthFromSubExpr(item.when); + setDepthFromSubExpr(item.then); + } + } + private: explicit CaseExpression(ObjectPool* pool) : Expression(pool, Kind::kCase), isGeneric_(true) {} explicit CaseExpression(ObjectPool* pool, CaseList* cases, bool isGeneric) : Expression(pool, Kind::kCase), isGeneric_(isGeneric) { cases_ = cases->items(); + setDepth(); } void writeTo(Encoder& encoder) const override; diff --git a/src/common/expression/ContainerExpression.h b/src/common/expression/ContainerExpression.h index 69fe29ef348..ce9a3fb167b 100644 --- a/src/common/expression/ContainerExpression.h +++ b/src/common/expression/ContainerExpression.h @@ -116,6 +116,9 @@ class ListExpression final : public Expression { explicit ListExpression(ObjectPool *pool) : Expression(pool, Kind::kList) {} explicit ListExpression(ObjectPool *pool, ExpressionList *items) : Expression(pool, Kind::kList) { + for (auto &item : items->get()) { + setDepthFromSubExpr(item); + } items_ = items->get(); } @@ -183,6 +186,9 @@ class SetExpression final : public Expression { explicit SetExpression(ObjectPool *pool) : Expression(pool, Kind::kSet) {} explicit SetExpression(ObjectPool *pool, ExpressionList *items) : Expression(pool, Kind::kSet) { + for (auto &item : items->get()) { + setDepthFromSubExpr(item); + } items_ = items->get(); } @@ -248,11 +254,18 @@ class MapExpression final : public Expression { return true; } + void setDepth() override { + for (auto &item : items_) { + setDepthFromSubExpr(item.second); + } + } + private: explicit MapExpression(ObjectPool *pool) : Expression(pool, Kind::kMap) {} explicit MapExpression(ObjectPool *pool, MapItemList *items) : Expression(pool, Kind::kMap) { items_ = items->get(); + setDepth(); } void writeTo(Encoder &encoder) const override; diff --git a/src/common/expression/Expression.h b/src/common/expression/Expression.h index 1f5a1aacd66..7e7aa0f59ca 100644 --- a/src/common/expression/Expression.h +++ b/src/common/expression/Expression.h @@ -6,6 +6,8 @@ #ifndef COMMON_EXPRESSION_EXPRESSION_H_ #define COMMON_EXPRESSION_EXPRESSION_H_ +#include + #include "common/base/Base.h" #include "common/base/ObjectPool.h" #include "common/context/ExpressionContext.h" @@ -168,6 +170,12 @@ class Expression { return false; } + int32_t getDepth() { return depth_; } + + virtual void setDepth() { return; } + + bool checkDepth() { return depth_ < MAX_DEPTH; } + protected: class Encoder final { public: @@ -217,7 +225,15 @@ class Expression { ObjectPool* pool_{nullptr}; + void setDepthFromSubExpr(Expression* expr) { + if (expr != nullptr) { + depth_ = std::max(depth_, expr->getDepth() + 1); + } + } + Kind kind_; + int32_t depth_ = 1; + const int32_t MAX_DEPTH = 512; }; std::ostream& operator<<(std::ostream& os, Expression::Kind kind); diff --git a/src/common/expression/FunctionCallExpression.h b/src/common/expression/FunctionCallExpression.h index c74d94914da..daed37385ce 100644 --- a/src/common/expression/FunctionCallExpression.h +++ b/src/common/expression/FunctionCallExpression.h @@ -104,6 +104,12 @@ class FunctionCallExpression final : public Expression { return args_; } + void setDepth() override { + for (auto& item : args_->args()) { + setDepthFromSubExpr(item); + } + } + private: explicit FunctionCallExpression(ObjectPool* pool, const std::string& name, ArgumentList* args) : Expression(pool, Kind::kFunctionCall), name_(name), args_(args) { @@ -113,6 +119,7 @@ class FunctionCallExpression final : public Expression { func_ = funcResult.value(); } } + setDepth(); } void writeTo(Encoder& encoder) const override; diff --git a/src/common/expression/LabelAttributeExpression.h b/src/common/expression/LabelAttributeExpression.h index 315031fefab..1d119698e98 100644 --- a/src/common/expression/LabelAttributeExpression.h +++ b/src/common/expression/LabelAttributeExpression.h @@ -64,6 +64,11 @@ class LabelAttributeExpression final : public Expression { std::string toString() const override; + void setDepth() override { + setDepthFromSubExpr(lhs_); + setDepthFromSubExpr(rhs_); + } + private: explicit LabelAttributeExpression(ObjectPool* pool, LabelExpression* lhs = nullptr, @@ -72,6 +77,7 @@ class LabelAttributeExpression final : public Expression { DCHECK(rhs == nullptr || rhs->value().isStr()); lhs_ = lhs; rhs_ = rhs; + setDepth(); } void writeTo(Encoder&) const override { diff --git a/src/common/expression/ListComprehensionExpression.h b/src/common/expression/ListComprehensionExpression.h index 26723d1f0ff..674a9ab47f7 100644 --- a/src/common/expression/ListComprehensionExpression.h +++ b/src/common/expression/ListComprehensionExpression.h @@ -99,6 +99,12 @@ class ListComprehensionExpression final : public Expression { return !originString_.empty(); } + void setDepth() override { + setDepthFromSubExpr(collection_); + setDepthFromSubExpr(filter_); + setDepthFromSubExpr(mapping_); + } + private: explicit ListComprehensionExpression(ObjectPool* pool, const std::string& innerVar = "", @@ -109,7 +115,9 @@ class ListComprehensionExpression final : public Expression { innerVar_(innerVar), collection_(collection), filter_(filter), - mapping_(mapping) {} + mapping_(mapping) { + setDepth(); + } void writeTo(Encoder& encoder) const override; diff --git a/src/common/expression/LogicalExpression.h b/src/common/expression/LogicalExpression.h index 4fe7a85ac0b..071ca90ccd6 100644 --- a/src/common/expression/LogicalExpression.h +++ b/src/common/expression/LogicalExpression.h @@ -93,6 +93,12 @@ class LogicalExpression final : public Expression { return true; } + void setDepth() override { + for (auto& item : operands_) { + setDepthFromSubExpr(item); + } + } + private: explicit LogicalExpression(ObjectPool* pool, Kind kind) : Expression(pool, kind) {} @@ -100,6 +106,7 @@ class LogicalExpression final : public Expression { : Expression(pool, kind) { operands_.emplace_back(lhs); operands_.emplace_back(rhs); + setDepth(); } void writeTo(Encoder& encoder) const override; diff --git a/src/common/expression/PredicateExpression.h b/src/common/expression/PredicateExpression.h index 9792e8f425d..2793ed744bc 100644 --- a/src/common/expression/PredicateExpression.h +++ b/src/common/expression/PredicateExpression.h @@ -99,6 +99,11 @@ class PredicateExpression final : public Expression { return filter_ != nullptr; } + void setDepth() override { + setDepthFromSubExpr(collection_); + setDepthFromSubExpr(filter_); + } + private: explicit PredicateExpression(ObjectPool* pool, const std::string& name = "", @@ -109,7 +114,9 @@ class PredicateExpression final : public Expression { name_(name), innerVar_(innerVar), collection_(collection), - filter_(filter) {} + filter_(filter) { + setDepth(); + } const Value& evalExists(ExpressionContext& ctx); void writeTo(Encoder& encoder) const override; diff --git a/src/common/expression/ReduceExpression.h b/src/common/expression/ReduceExpression.h index 130be05672f..902cf67bd64 100644 --- a/src/common/expression/ReduceExpression.h +++ b/src/common/expression/ReduceExpression.h @@ -98,6 +98,11 @@ class ReduceExpression final : public Expression { return !originString_.empty(); } + void setDepth() override { + setDepthFromSubExpr(collection_); + setDepthFromSubExpr(mapping_); + } + private: explicit ReduceExpression(ObjectPool* pool, const std::string& accumulator = "", @@ -110,7 +115,9 @@ class ReduceExpression final : public Expression { initial_(initial), innerVar_(innerVar), collection_(collection), - mapping_(mapping) {} + mapping_(mapping) { + setDepth(); + } void writeTo(Encoder& encoder) const override; void resetFrom(Decoder& decoder) override; diff --git a/src/common/expression/SubscriptExpression.h b/src/common/expression/SubscriptExpression.h index c1534bffc73..37a9b9ba789 100644 --- a/src/common/expression/SubscriptExpression.h +++ b/src/common/expression/SubscriptExpression.h @@ -106,12 +106,19 @@ class SubscriptRangeExpression final : public Expression { explicit SubscriptRangeExpression(ObjectPool* pool) : Expression(pool, Kind::kSubscriptRange), list_(nullptr), lo_(nullptr), hi_(nullptr) {} + void setDepth() override { + setDepthFromSubExpr(list_); + setDepthFromSubExpr(lo_); + setDepthFromSubExpr(hi_); + } + explicit SubscriptRangeExpression(ObjectPool* pool, Expression* list, Expression* lo, Expression* hi) : Expression(pool, Kind::kSubscriptRange), list_(DCHECK_NOTNULL(list)), lo_(lo), hi_(hi) { DCHECK(!(lo_ == nullptr && hi_ == nullptr)); + setDepth(); } void writeTo(Encoder& encoder) const override; diff --git a/src/common/expression/TypeCastingExpression.h b/src/common/expression/TypeCastingExpression.h index 092b529fb4f..ce935dd3a6c 100644 --- a/src/common/expression/TypeCastingExpression.h +++ b/src/common/expression/TypeCastingExpression.h @@ -50,11 +50,15 @@ class TypeCastingExpression final : public Expression { static bool validateTypeCast(Value::Type operandType, Value::Type type); + void setDepth() override { setDepthFromSubExpr(operand_); } + private: explicit TypeCastingExpression(ObjectPool* pool, Value::Type vType = Value::Type::__EMPTY__, Expression* operand = nullptr) - : Expression(pool, Kind::kTypeCasting), vType_(vType), operand_(operand) {} + : Expression(pool, Kind::kTypeCasting), vType_(vType), operand_(operand) { + setDepth(); + } void writeTo(Encoder& encoder) const override; void resetFrom(Decoder& decoder) override; diff --git a/src/common/expression/UnaryExpression.h b/src/common/expression/UnaryExpression.h index d17d459b59d..690ef91ed14 100644 --- a/src/common/expression/UnaryExpression.h +++ b/src/common/expression/UnaryExpression.h @@ -74,9 +74,13 @@ class UnaryExpression final : public Expression { operand_ = expr; } + void setDepth() override { setDepthFromSubExpr(operand_); } + private: explicit UnaryExpression(ObjectPool* pool, Kind kind, Expression* operand = nullptr) - : Expression(pool, kind), operand_(operand) {} + : Expression(pool, kind), operand_(operand) { + setDepth(); + } void writeTo(Encoder& encoder) const override; void resetFrom(Decoder& decoder) override; diff --git a/src/parser/parser.yy b/src/parser/parser.yy index 6d4c02565d4..53f638e9462 100644 --- a/src/parser/parser.yy +++ b/src/parser/parser.yy @@ -43,6 +43,11 @@ class GraphScanner; static constexpr size_t MAX_ABS_INTEGER = 9223372036854775808ULL; static constexpr size_t kCommentLengthLimit = 256; +#define CHECK_DEPTH(EXPR,LOCATION) \ + if(!EXPR->checkDepth()){ \ + throw nebula::GraphParser::syntax_error(LOCATION, "The above expression's depth exceeds the maximum depth!"); \ + } + } %code { @@ -564,6 +569,7 @@ expression } | compound_expression { $$ = $1; + CHECK_DEPTH($$, @1); } | MINUS { scanner.setUnaryMinus(true); @@ -575,112 +581,148 @@ expression $$ = UnaryExpression::makeNegate(qctx->objPool(), $3); } scanner.setUnaryMinus(false); + CHECK_DEPTH($$, @1); } | PLUS expression %prec UNARY_PLUS { $$ = UnaryExpression::makePlus(qctx->objPool(), $2); + CHECK_DEPTH($$, @1); } | NOT expression { $$ = UnaryExpression::makeNot(qctx->objPool(), $2); + CHECK_DEPTH($$, @1); } | KW_NOT expression { $$ = UnaryExpression::makeNot(qctx->objPool(), $2); + CHECK_DEPTH($$, @1); } | L_PAREN type_spec R_PAREN expression %prec CASTING { $$ = TypeCastingExpression::make(qctx->objPool(), graph::SchemaUtil::propTypeToValueType($2->type), $4); delete $2; + CHECK_DEPTH($$, @1); } | expression STAR expression { $$ = ArithmeticExpression::makeMultiply(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression DIV expression { $$ = ArithmeticExpression::makeDivision(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression MOD expression { $$ = ArithmeticExpression::makeMod(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression PLUS expression { $$ = ArithmeticExpression::makeAdd(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression MINUS expression { $$ = ArithmeticExpression::makeMinus(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression LT expression { $$ = RelationalExpression::makeLT(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression GT expression { $$ = RelationalExpression::makeGT(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression LE expression { $$ = RelationalExpression::makeLE(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression GE expression { $$ = RelationalExpression::makeGE(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression REG expression { $$ = RelationalExpression::makeREG(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_IN expression { $$ = RelationalExpression::makeIn(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_NOT_IN expression { $$ = RelationalExpression::makeNotIn(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_CONTAINS expression { $$ = RelationalExpression::makeContains(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_NOT_CONTAINS expression { $$ = RelationalExpression::makeNotContains(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_STARTS_WITH expression { $$ = RelationalExpression::makeStartsWith(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_NOT_STARTS_WITH expression { $$ = RelationalExpression::makeNotStartsWith(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_ENDS_WITH expression { $$ = RelationalExpression::makeEndsWith(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_NOT_ENDS_WITH expression { $$ = RelationalExpression::makeNotEndsWith(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_IS_NULL { $$ = UnaryExpression::makeIsNull(qctx->objPool(), $1); + CHECK_DEPTH($$, @1); } | expression KW_IS_NOT_NULL { $$ = UnaryExpression::makeIsNotNull(qctx->objPool(), $1); + CHECK_DEPTH($$, @1); } | expression KW_IS_EMPTY { $$ = UnaryExpression::makeIsEmpty(qctx->objPool(), $1); + CHECK_DEPTH($$, @1); } | expression KW_IS_NOT_EMPTY { $$ = UnaryExpression::makeIsNotEmpty(qctx->objPool(), $1); + CHECK_DEPTH($$, @1); } | expression EQ expression { $$ = RelationalExpression::makeEQ(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression NE expression { $$ = RelationalExpression::makeNE(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_AND expression { $$ = LogicalExpression::makeAnd(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_OR expression { $$ = LogicalExpression::makeOr(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | expression KW_XOR expression { $$ = LogicalExpression::makeXor(qctx->objPool(), $1, $3); + CHECK_DEPTH($$, @1); } | case_expression { $$ = $1; + CHECK_DEPTH($$, @1); } | predicate_expression { $$ = $1; + CHECK_DEPTH($$, @1); } | list_comprehension_expression { $$ = $1; + CHECK_DEPTH($$, @1); } | reduce_expression { $$ = $1; + CHECK_DEPTH($$, @1); } ; diff --git a/tests/tck/features/expression/Depth.feature b/tests/tck/features/expression/Depth.feature new file mode 100644 index 00000000000..018e22743a0 --- /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 SyntaxError 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 SyntaxError should be raised at runtime: The above expression is not a valid expression, because its depth exceeds the maximum depth! \ No newline at end of file