diff --git a/src/mvcc/version_list.hpp b/src/mvcc/version_list.hpp index 1cad4fe78..73f0d8a5e 100644 --- a/src/mvcc/version_list.hpp +++ b/src/mvcc/version_list.hpp @@ -9,7 +9,7 @@ namespace mvcc { class SerializationError : public utils::BasicException { static constexpr const char *default_message = - "Can't serialize due to concurrent operations"; + "Can't serialize due to concurrent operations."; public: using utils::BasicException::BasicException; diff --git a/src/query/common.cpp b/src/query/common.cpp index c632e4266..69e73c580 100644 --- a/src/query/common.cpp +++ b/src/query/common.cpp @@ -18,7 +18,7 @@ int64_t ParseIntegerLiteral(const std::string &s) { // Not really correct since long long can have a bigger range than int64_t. return static_cast(std::stoll(s, 0, 0)); } catch (const std::out_of_range &) { - throw SemanticException("Integer literal exceeds 64 bits"); + throw SemanticException("Integer literal exceeds 64 bits."); } } @@ -55,12 +55,12 @@ std::string ParseStringLiteral(const std::string &s) { // t is high surrogate pair. Expect one more utf16 codepoint. j = i + kShortUnicodeLength + 1; if (j >= static_cast(s.size()) - 1 || s[j] != '\\') { - throw SemanticException("Invalid utf codepoint"); + throw SemanticException("Invalid UTF codepoint."); } ++j; if (j >= static_cast(s.size()) - 1 || (s[j] != 'u' && s[j] != 'U')) { - throw SemanticException("Invalid utf codepoint"); + throw SemanticException("Invalid UTF codepoint."); } ++j; int k = j; @@ -69,7 +69,7 @@ std::string ParseStringLiteral(const std::string &s) { ++k; } if (k != j + kShortUnicodeLength) { - throw SemanticException("Invalid utf codepoint"); + throw SemanticException("Invalid UTF codepoint."); } char16_t surrogates[3] = {t, static_cast(stoi( @@ -131,14 +131,14 @@ std::string ParseStringLiteral(const std::string &s) { try { unescaped += EncodeEscapedUnicodeCodepointUtf32(s, i); } catch (const std::range_error &) { - throw SemanticException("Invalid utf codepoint"); + throw SemanticException("Invalid UTF codepoint."); } break; case 'u': try { unescaped += EncodeEscapedUnicodeCodepointUtf16(s, i); } catch (const std::range_error &) { - throw SemanticException("Invalid utf codepoint"); + throw SemanticException("Invalid UTF codepoint."); } break; default: @@ -161,7 +161,7 @@ double ParseDoubleLiteral(const std::string &s) { try { return utils::ParseDouble(s); } catch (const utils::BasicException &) { - throw SemanticException("Couldn't parse string to double"); + throw SemanticException("Couldn't parse string to double."); } } @@ -229,7 +229,7 @@ bool TypedValueCompare(const TypedValue &a, const TypedValue &b) { // the same type, or int+float combinations if ((a.type() != b.type() && !(a.IsNumeric() && b.IsNumeric()))) throw QueryRuntimeException( - "Can't compare value of type {} to value of type {}", a.type(), + "Can't compare value of type {} to value of type {}.", a.type(), b.type()); switch (a.type()) { @@ -253,7 +253,7 @@ bool TypedValueCompare(const TypedValue &a, const TypedValue &b) { case TypedValue::Type::Edge: case TypedValue::Type::Path: throw QueryRuntimeException( - "Comparison is not defined for values of type {}", a.type()); + "Comparison is not defined for values of type {}.", a.type()); default: LOG(FATAL) << "Unhandled comparison for types"; } diff --git a/src/query/exceptions.hpp b/src/query/exceptions.hpp index ee993c4dd..4532d3602 100644 --- a/src/query/exceptions.hpp +++ b/src/query/exceptions.hpp @@ -46,13 +46,13 @@ class SemanticException : public QueryException { class UnboundVariableError : public SemanticException { public: explicit UnboundVariableError(const std::string &name) - : SemanticException("Unbound variable: " + name) {} + : SemanticException("Unbound variable: " + name + ".") {} }; class RedeclareVariableError : public SemanticException { public: explicit RedeclareVariableError(const std::string &name) - : SemanticException("Redeclaring variable: " + name) {} + : SemanticException("Redeclaring variable: " + name + ".") {} }; class TypeMismatchError : public SemanticException { @@ -60,7 +60,7 @@ class TypeMismatchError : public SemanticException { TypeMismatchError(const std::string &name, const std::string &datum, const std::string &expected) : SemanticException(fmt::format( - "Type mismatch: '{}' already defined as '{}', but expected '{}'.", + "Type mismatch: {} already defined as {}, expected {}.", name, datum, expected)) {} }; @@ -74,7 +74,7 @@ class IndexInMulticommandTxException : public QueryException { using QueryException::QueryException; IndexInMulticommandTxException() : QueryException( - "Index creation not allowed in multicommand transactions") {} + "CREATE INDEX not allowed in multicommand transactions.") {} }; /** @@ -96,7 +96,7 @@ class HintedAbortError : public utils::BasicException { : utils::BasicException( "Transaction was asked to abort, most likely because it was " "executing longer than time specified by " - "--query-execution-time-sec flag") {} + "--query-execution-time-sec flag.") {} }; class ReconstructionException : public QueryException { @@ -111,7 +111,7 @@ class RemoveAttachedVertexException : public QueryRuntimeException { public: RemoveAttachedVertexException() : QueryRuntimeException( - "Failed to remove vertex because of it's existing " + "Failed to remove node because of it's existing " "connections. Consider using DETACH DELETE.") {} }; @@ -119,14 +119,15 @@ class UserModificationInMulticommandTxException : public QueryException { public: UserModificationInMulticommandTxException() : QueryException( - "User modification not allowed in multicommand transactions") {} + "Authentication clause not allowed in multicommand transactions.") { + } }; class StreamClauseInMulticommandTxException : public QueryException { public: StreamClauseInMulticommandTxException() : QueryException( - "Stream clause not allowed in multicommand transactions") {} + "Stream clause not allowed in multicommand transactions.") {} }; } // namespace query diff --git a/src/query/frontend/ast/cypher_main_visitor.cpp b/src/query/frontend/ast/cypher_main_visitor.cpp index 43abecd10..2adec1ea0 100644 --- a/src/query/frontend/ast/cypher_main_visitor.cpp +++ b/src/query/frontend/ast/cypher_main_visitor.cpp @@ -129,16 +129,17 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery( if (dynamic_cast(clause)) { if (has_update || has_return) { throw SemanticException( - "Unwind can't be after return or update clause"); + "UNWIND can't be put after RETURN clause or after an update."); } } else if (auto *match = dynamic_cast(clause)) { if (has_update || has_return) { - throw SemanticException("Match can't be after return or update clause"); + throw SemanticException( + "MATCH can't be put after RETURN clause or after an update."); } if (match->optional_) { has_optional_match = true; } else if (has_optional_match) { - throw SemanticException("Match can't be after optional match"); + throw SemanticException("MATCH can't be put after OPTIONAL MATCH."); } } else if (dynamic_cast(clause) || dynamic_cast(clause) || @@ -149,24 +150,24 @@ antlrcpp::Any CypherMainVisitor::visitSingleQuery( dynamic_cast(clause) || dynamic_cast(clause)) { if (has_return) { - throw SemanticException("Update clauses can't be after return"); + throw SemanticException("Update clause can't be used after RETURN."); } has_update = true; } else if (dynamic_cast(clause)) { if (has_return) { - throw SemanticException("There can be only one return in a clause"); + throw SemanticException("There can only be one RETURN in a clause."); } has_return = true; } else if (dynamic_cast(clause)) { if (has_return) { - throw SemanticException("Return can't be before with"); + throw SemanticException("RETURN can't be put before WITH."); } has_update = has_return = has_optional_match = false; } else if (dynamic_cast(clause)) { // If there is CreateIndex clause then there shouldn't be anything else. if (single_query->clauses_.size() != 1U) { throw SemanticException( - "CreateIndex must be only clause in the query."); + "CREATE INDEX must be the only clause in a query."); } has_create_index = true; } else { @@ -272,7 +273,7 @@ antlrcpp::Any CypherMainVisitor::visitUserOrRoleName( std::string value = ctx->symbolicName()->accept(this).as(); const std::regex NAME_REGEX("[a-zA-Z0-9_.+-]+"); if (!std::regex_match(value, NAME_REGEX)) { - throw SyntaxException("invalid user or role name"); + throw SyntaxException("Invalid user or role name."); } return value; } @@ -319,7 +320,7 @@ antlrcpp::Any CypherMainVisitor::visitCreateUser( auth->user_ = ctx->user->accept(this).as(); if (ctx->password) { if (!ctx->password->StringLiteral() && !ctx->literal()->CYPHERNULL()) { - throw SyntaxException("password should be a string literal or NULL"); + throw SyntaxException("Password should be a string literal or null."); } auth->password_ = ctx->password->accept(this); } @@ -335,7 +336,7 @@ antlrcpp::Any CypherMainVisitor::visitSetPassword( auth->action_ = AuthQuery::Action::SET_PASSWORD; auth->user_ = ctx->user->accept(this).as(); if (!ctx->password->StringLiteral() && !ctx->literal()->CYPHERNULL()) { - throw SyntaxException("password should be a string literal or NULL"); + throw SyntaxException("Password should be a string literal or null."); } auth->password_ = ctx->password->accept(this); return auth; @@ -499,17 +500,17 @@ antlrcpp::Any CypherMainVisitor::visitCreateStream( MemgraphCypher::CreateStreamContext *ctx) { std::string stream_name(ctx->streamName()->getText()); if (!ctx->streamUri->StringLiteral()) { - throw SyntaxException("Stream URI should be a string literal!"); + throw SyntaxException("Stream URI should be a string literal."); } Expression *stream_uri = ctx->streamUri->accept(this); if (!ctx->streamTopic->StringLiteral()) { - throw SyntaxException("Topic should be a string literal!"); + throw SyntaxException("Topic should be a string literal."); } Expression *stream_topic = ctx->streamTopic->accept(this); if (!ctx->transformUri->StringLiteral()) { - throw SyntaxException("Transform URI should be a string literal!"); + throw SyntaxException("Transform URI should be a string literal."); } Expression *transform_uri = ctx->transformUri->accept(this); @@ -535,7 +536,7 @@ antlrcpp::Any CypherMainVisitor::visitBatchIntervalOption( MemgraphCypher::BatchIntervalOptionContext *ctx) { if (!ctx->literal()->numberLiteral() || !ctx->literal()->numberLiteral()->integerLiteral()) { - throw SyntaxException("Batch interval should be an integer literal!"); + throw SyntaxException("Batch interval should be an integer."); } return ctx->literal()->accept(this); } @@ -547,7 +548,7 @@ antlrcpp::Any CypherMainVisitor::visitBatchSizeOption( MemgraphCypher::BatchSizeOptionContext *ctx) { if (!ctx->literal()->numberLiteral() || !ctx->literal()->numberLiteral()->integerLiteral()) { - throw SyntaxException("Batch size should be an integer literal!"); + throw SyntaxException("Batch size should be an integer."); } return ctx->literal()->accept(this); } @@ -579,7 +580,7 @@ antlrcpp::Any CypherMainVisitor::visitStartStopStream( if (ctx->limitBatchesOption()) { if (!is_start) { - throw SyntaxException("Stop stream clause can't set batch limit!"); + throw SyntaxException("STOP STREAM can't set batch limit."); } limit_batches = ctx->limitBatchesOption()->accept(this); } @@ -594,7 +595,7 @@ antlrcpp::Any CypherMainVisitor::visitLimitBatchesOption( MemgraphCypher::LimitBatchesOptionContext *ctx) { if (!ctx->literal()->numberLiteral() || !ctx->literal()->numberLiteral()->integerLiteral()) { - throw SyntaxException("Batch limit should be an integer literal!"); + throw SyntaxException("Batch limit should be an integer."); } return ctx->literal()->accept(this); } @@ -673,7 +674,7 @@ antlrcpp::Any CypherMainVisitor::visitReturnItem( std::string(ctx->variable()->accept(this).as()); } else { if (in_with_ && !dynamic_cast(named_expr->expression_)) { - throw SemanticException("Only variables can be non aliased in with"); + throw SemanticException("Only variables can be non-aliased in WITH."); } named_expr->name_ = std::string(ctx->getText()); named_expr->token_position_ = @@ -752,7 +753,7 @@ antlrcpp::Any CypherMainVisitor::visitMapLiteral( ctx->propertyKeyName()[i]->accept(this); Expression *value = ctx->expression()[i]->accept(this); if (!map.insert({key, value}).second) { - throw SemanticException("Same key can't appear twice in map literal"); + throw SemanticException("Same key can't appear twice in a map literal."); } } return map; @@ -900,7 +901,8 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern( if (relationshipDetail->total_weight && edge->type_ != EdgeAtom::Type::WEIGHTED_SHORTEST_PATH) throw SemanticException( - "Variable for total weight is allowed only in wShortest"); + "Variable for total weight is allowed only with weighted shortest " + "path expansion."); auto visit_lambda = [this](auto *lambda) { EdgeAtom::Lambda edge_lambda; std::string traversed_edge_variable = @@ -927,7 +929,8 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern( case 0: if (edge->type_ == EdgeAtom::Type::WEIGHTED_SHORTEST_PATH) throw SemanticException( - "Lambda for calculating weights is mandatory"); + "Lambda for calculating weights is mandatory with weighted " + "shortest path expansion."); // In variable expansion inner variables are mandatory. anonymous_identifiers.push_back(&edge->filter_lambda_.inner_edge); anonymous_identifiers.push_back(&edge->filter_lambda_.inner_node); @@ -948,17 +951,17 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern( break; case 2: if (edge->type_ != EdgeAtom::Type::WEIGHTED_SHORTEST_PATH) - throw SemanticException("Only one relationship lambda allowed"); + throw SemanticException("Only one filter lambda can be supplied."); edge->weight_lambda_ = visit_lambda(relationshipLambdas[0]); visit_total_weight(); edge->filter_lambda_ = visit_lambda(relationshipLambdas[1]); break; default: - throw SemanticException("Only one relationship lambda allowed"); + throw SemanticException("Only one filter lambda can be supplied."); } } else if (!relationshipLambdas.empty()) { throw SemanticException( - "Relationship lambda only supported in variable length expansion"); + "Filter lambda is only allowed in variable length expansion."); } auto properties = relationshipDetail->properties(); @@ -974,7 +977,8 @@ antlrcpp::Any CypherMainVisitor::visitRelationshipPattern( break; } default: - throw SemanticException("Only one property map supported in edge"); + throw SemanticException( + "Only one property map can be supplied for edge."); } return edge; @@ -1037,7 +1041,8 @@ antlrcpp::Any CypherMainVisitor::visitVariableExpansion( upper = ctx->expression()[1]->accept(this); } if (lower && edge_type == EdgeAtom::Type::WEIGHTED_SHORTEST_PATH) - throw SemanticException("Lower bound is not allowed in wShortest."); + throw SemanticException( + "Lower bound is not allowed in weighted shortest path expansion."); return std::make_tuple(edge_type, lower, upper); } @@ -1301,7 +1306,7 @@ antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) { Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this); if (!ctx->filterExpression()->where()) { - throw SyntaxException("all(...) requires a WHERE predicate"); + throw SyntaxException("ALL(...) requires a WHERE predicate."); } Where *where = ctx->filterExpression()->where()->accept(this); return static_cast( @@ -1315,7 +1320,7 @@ antlrcpp::Any CypherMainVisitor::visitAtom(MemgraphCypher::AtomContext *ctx) { Expression *list_expr = ctx->filterExpression()->idInColl()->expression()->accept(this); if (!ctx->filterExpression()->where()) { - throw SyntaxException("single(...) requires a WHERE predicate"); + throw SyntaxException("SINGLE(...) requires a WHERE predicate."); } Where *where = ctx->filterExpression()->where()->accept(this); return static_cast( diff --git a/src/query/frontend/semantic/symbol_generator.cpp b/src/query/frontend/semantic/symbol_generator.cpp index 0d6ea58d7..724de43cf 100644 --- a/src/query/frontend/semantic/symbol_generator.cpp +++ b/src/query/frontend/semantic/symbol_generator.cpp @@ -51,7 +51,7 @@ void SymbolGenerator::VisitReturnBody(ReturnBody &body, Where *where) { user_symbols.emplace_back(sym_pair.second); } if (user_symbols.empty()) { - throw SemanticException("There are no variables in scope to use for '*'"); + throw SemanticException("There are no variables in scope to use for '*'."); } } // WITH/RETURN clause removes declarations of all the previous variables and @@ -132,7 +132,7 @@ bool SymbolGenerator::PreVisit(CypherUnion &) { bool SymbolGenerator::PostVisit(CypherUnion &cypher_union) { if (prev_return_names_ != curr_return_names_) { throw SemanticException( - "All sub queries in an UNION must have the same column names"); + "All subqueries in an UNION must have the same column names."); } // create new symbols for the result of the union @@ -238,7 +238,7 @@ bool SymbolGenerator::Visit(TestStream &) { return true; } SymbolGenerator::ReturnType SymbolGenerator::Visit(Identifier &ident) { if (scope_.in_skip || scope_.in_limit) { - throw SemanticException("Variables are not allowed in {}", + throw SemanticException("Variables are not allowed in {}.", scope_.in_skip ? "SKIP" : "LIMIT"); } Symbol symbol; @@ -297,12 +297,12 @@ bool SymbolGenerator::PreVisit(Aggregation &aggr) { if ((!scope_.in_return && !scope_.in_with) || scope_.in_order_by || scope_.in_skip || scope_.in_limit || scope_.in_where) { throw SemanticException( - "Aggregation functions are only allowed in WITH and RETURN"); + "Aggregation functions are only allowed in WITH and RETURN."); } if (scope_.in_aggregation) { throw SemanticException( "Using aggregation functions inside aggregation functions is not " - "allowed"); + "allowed."); } if (scope_.num_if_operators) { // Neo allows aggregations here and produces very interesting behaviors. @@ -313,7 +313,7 @@ bool SymbolGenerator::PreVisit(Aggregation &aggr) { // TODO: Rethink of allowing aggregations in some parts of the CASE // construct. throw SemanticException( - "Using aggregation functions inside of CASE is not allowed"); + "Using aggregation functions inside of CASE is not allowed."); } // Create a virtual symbol for aggregation result. // Currently, we only have aggregation operators which return numbers. diff --git a/src/query/frontend/stripped.cpp b/src/query/frontend/stripped.cpp index f7b579c54..ee06bae56 100644 --- a/src/query/frontend/stripped.cpp +++ b/src/query/frontend/stripped.cpp @@ -56,7 +56,7 @@ StrippedQuery::StrippedQuery(const std::string &query) : original_(query) { update(MatchEscapedName(i), Token::ESCAPED_NAME); update(MatchUnescapedName(i), Token::UNESCAPED_NAME); update(MatchWhitespaceAndComments(i), Token::SPACE); - if (token == Token::UNMATCHED) throw LexingException("Invalid query"); + if (token == Token::UNMATCHED) throw LexingException("Invalid query."); tokens.emplace_back(token, original_.substr(i, len)); i += len; } @@ -233,26 +233,26 @@ std::string GetFirstUtf8Symbol(const char *_s) { if ((*s >> 7) == 0x00) return std::string(_s, _s + 1); if ((*s >> 5) == 0x06) { auto *s1 = s + 1; - if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character."); return std::string(_s, _s + 2); } if ((*s >> 4) == 0x0e) { auto *s1 = s + 1; - if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character."); auto *s2 = s + 2; - if ((*s2 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s2 >> 6) != 0x02) throw LexingException("Invalid character."); return std::string(_s, _s + 3); } if ((*s >> 3) == 0x1e) { auto *s1 = s + 1; - if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character."); auto *s2 = s + 2; - if ((*s2 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s2 >> 6) != 0x02) throw LexingException("Invalid character."); auto *s3 = s + 3; - if ((*s3 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s3 >> 6) != 0x02) throw LexingException("Invalid character."); return std::string(_s, _s + 4); } - throw LexingException("Invalid character"); + throw LexingException("Invalid character."); } // Return codepoint of first utf8 symbol and its encoded length. @@ -264,28 +264,28 @@ std::pair GetFirstUtf8SymbolCodepoint(const char *_s) { if ((*s >> 7) == 0x00) return {*s & 0x7f, 1}; if ((*s >> 5) == 0x06) { auto *s1 = s + 1; - if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character."); return {((*s & 0x1f) << 6) | (*s1 & 0x3f), 2}; } if ((*s >> 4) == 0x0e) { auto *s1 = s + 1; - if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character."); auto *s2 = s + 2; - if ((*s2 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s2 >> 6) != 0x02) throw LexingException("Invalid character."); return {((*s & 0x0f) << 12) | ((*s1 & 0x3f) << 6) | (*s2 & 0x3f), 3}; } if ((*s >> 3) == 0x1e) { auto *s1 = s + 1; - if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s1 >> 6) != 0x02) throw LexingException("Invalid character."); auto *s2 = s + 2; - if ((*s2 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s2 >> 6) != 0x02) throw LexingException("Invalid character."); auto *s3 = s + 3; - if ((*s3 >> 6) != 0x02) throw LexingException("Invalid character"); + if ((*s3 >> 6) != 0x02) throw LexingException("Invalid character."); return {((*s & 0x07) << 18) | ((*s1 & 0x3f) << 12) | ((*s2 & 0x3f) << 6) | (*s3 & 0x3f), 4}; } - throw LexingException("Invalid character"); + throw LexingException("Invalid character."); } // From here until end of file there are functions that calculate matches for diff --git a/src/query/interpret/awesome_memgraph_functions.cpp b/src/query/interpret/awesome_memgraph_functions.cpp index dbfe333d7..5b24d1e94 100644 --- a/src/query/interpret/awesome_memgraph_functions.cpp +++ b/src/query/interpret/awesome_memgraph_functions.cpp @@ -34,7 +34,7 @@ namespace { TypedValue Coalesce(const std::vector &args, Context *) { if (args.size() == 0U) { - throw QueryRuntimeException("coalesce requires at least one argument"); + throw QueryRuntimeException("'coalesce' requires at least one argument."); } for (auto &arg : args) { if (arg.type() != TypedValue::Type::Null) { @@ -46,7 +46,7 @@ TypedValue Coalesce(const std::vector &args, Context *) { TypedValue EndNode(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("endNode requires one argument"); + throw QueryRuntimeException("'endNode' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -54,13 +54,13 @@ TypedValue EndNode(const std::vector &args, Context *) { case TypedValue::Type::Edge: return args[0].Value().to(); default: - throw QueryRuntimeException("endNode argument should be an edge"); + throw QueryRuntimeException("'endNode' argument must be an edge."); } } TypedValue Head(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("head requires one argument"); + throw QueryRuntimeException("'head' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -71,13 +71,13 @@ TypedValue Head(const std::vector &args, Context *) { return list[0]; } default: - throw QueryRuntimeException("head argument should be a list"); + throw QueryRuntimeException("'head' argument must be a list."); } } TypedValue Last(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("last requires one argument"); + throw QueryRuntimeException("'last' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -88,13 +88,13 @@ TypedValue Last(const std::vector &args, Context *) { return list.back(); } default: - throw QueryRuntimeException("last argument should be a list"); + throw QueryRuntimeException("'last' argument must be a list."); } } TypedValue Properties(const std::vector &args, Context *ctx) { if (args.size() != 1U) { - throw QueryRuntimeException("properties requires one argument"); + throw QueryRuntimeException("'properties' requires exactly one argument."); } auto get_properties = [&](const auto &record_accessor) { std::map properties; @@ -113,13 +113,13 @@ TypedValue Properties(const std::vector &args, Context *ctx) { return get_properties(args[0].Value()); default: throw QueryRuntimeException( - "properties argument should be a vertex or an edge"); + "'properties' argument must be a node or an edge."); } } TypedValue Size(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("size requires one argument"); + throw QueryRuntimeException("'size' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -138,13 +138,13 @@ TypedValue Size(const std::vector &args, Context *) { return static_cast(args[0].ValuePath().edges().size()); default: throw QueryRuntimeException( - "size argument should be a string, a collection or a path"); + "'size' argument must be a string, a collection or a path."); } } TypedValue StartNode(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("startNode requires one argument"); + throw QueryRuntimeException("'startNode' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -152,13 +152,13 @@ TypedValue StartNode(const std::vector &args, Context *) { case TypedValue::Type::Edge: return args[0].Value().from(); default: - throw QueryRuntimeException("startNode argument should be an edge"); + throw QueryRuntimeException("'startNode' argument must be an edge."); } } TypedValue Degree(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("degree requires one argument"); + throw QueryRuntimeException("'degree' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -168,13 +168,13 @@ TypedValue Degree(const std::vector &args, Context *) { return static_cast(vertex.out_degree() + vertex.in_degree()); } default: - throw QueryRuntimeException("degree argument should be a vertex"); + throw QueryRuntimeException("'degree' argument must be a node."); } } TypedValue ToBoolean(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("toBoolean requires one argument"); + throw QueryRuntimeException("'toBoolean' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -193,13 +193,13 @@ TypedValue ToBoolean(const std::vector &args, Context *) { } default: throw QueryRuntimeException( - "toBoolean argument should be an integer, a string or a boolean"); + "'toBoolean' argument must be an integer, a string or a boolean."); } } TypedValue ToFloat(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("toFloat requires one argument"); + throw QueryRuntimeException("'toFloat' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -216,13 +216,13 @@ TypedValue ToFloat(const std::vector &args, Context *) { } default: throw QueryRuntimeException( - "toFloat argument should be a string or a number"); + "'toFloat' argument must be a string or a number."); } } TypedValue ToInteger(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("toInteger requires one argument"); + throw QueryRuntimeException("'toInteger' requires exactly one argument'"); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -244,13 +244,13 @@ TypedValue ToInteger(const std::vector &args, Context *) { } default: throw QueryRuntimeException( - "toInteger argument should be a string, a boolean or a number"); + "'toInteger' argument must be a string, a boolean or a number."); } } TypedValue Type(const std::vector &args, Context *ctx) { if (args.size() != 1U) { - throw QueryRuntimeException("type requires one argument"); + throw QueryRuntimeException("'type' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -259,13 +259,13 @@ TypedValue Type(const std::vector &args, Context *ctx) { return ctx->db_accessor_.EdgeTypeName( args[0].Value().EdgeType()); default: - throw QueryRuntimeException("type argument should be an edge"); + throw QueryRuntimeException("'type' argument must be an edge."); } } TypedValue Keys(const std::vector &args, Context *ctx) { if (args.size() != 1U) { - throw QueryRuntimeException("keys requires one argument"); + throw QueryRuntimeException("'keys' requires exactly one argument."); } auto get_keys = [&](const auto &record_accessor) { std::vector keys; @@ -282,14 +282,13 @@ TypedValue Keys(const std::vector &args, Context *ctx) { case TypedValue::Type::Edge: return get_keys(args[0].Value()); default: - throw QueryRuntimeException( - "keys argument should be a vertex or an edge"); + throw QueryRuntimeException("'keys' argument must be a node or an edge."); } } TypedValue Labels(const std::vector &args, Context *ctx) { if (args.size() != 1U) { - throw QueryRuntimeException("labels requires one argument"); + throw QueryRuntimeException("'labels' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -302,17 +301,17 @@ TypedValue Labels(const std::vector &args, Context *ctx) { return labels; } default: - throw QueryRuntimeException("labels argument should be a vertex"); + throw QueryRuntimeException("'labels' argument must be a node."); } } TypedValue Nodes(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("nodes requires one argument"); + throw QueryRuntimeException("'nodes' requires exactly one argument."); } if (args[0].IsNull()) return TypedValue::Null; if (!args[0].IsPath()) { - throw QueryRuntimeException("nodes argument should be a path"); + throw QueryRuntimeException("'nodes' argument should be a path."); } auto &vertices = args[0].ValuePath().vertices(); return std::vector(vertices.begin(), vertices.end()); @@ -320,11 +319,12 @@ TypedValue Nodes(const std::vector &args, Context *) { TypedValue Relationships(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("relationships requires one argument"); + throw QueryRuntimeException( + "'relationships' requires exactly one argument."); } if (args[0].IsNull()) return TypedValue::Null; if (!args[0].IsPath()) { - throw QueryRuntimeException("relationships argument should be a path"); + throw QueryRuntimeException("'relationships' argument must be a path."); } auto &edges = args[0].ValuePath().edges(); return std::vector(edges.begin(), edges.end()); @@ -332,14 +332,14 @@ TypedValue Relationships(const std::vector &args, Context *) { TypedValue Range(const std::vector &args, Context *) { if (args.size() != 2U && args.size() != 3U) { - throw QueryRuntimeException("range requires two or three arguments"); + throw QueryRuntimeException("'range' requires two or three arguments."); } bool has_null = false; auto check_type = [&](const TypedValue &t) { if (t.IsNull()) { has_null = true; } else if (t.type() != TypedValue::Type::Int) { - throw QueryRuntimeException("arguments of range should be integers"); + throw QueryRuntimeException("arguments of 'range' must be integers."); } }; std::for_each(args.begin(), args.end(), check_type); @@ -348,7 +348,7 @@ TypedValue Range(const std::vector &args, Context *) { auto rbound = args[1].Value(); int64_t step = args.size() == 3U ? args[2].Value() : 1; if (step == 0) { - throw QueryRuntimeException("step argument in range can't be zero"); + throw QueryRuntimeException("step argument of 'range' can't be zero."); } std::vector list; if (lbound <= rbound && step > 0) { @@ -365,7 +365,7 @@ TypedValue Range(const std::vector &args, Context *) { TypedValue Tail(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("tail requires one argument"); + throw QueryRuntimeException("'tail' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -377,13 +377,13 @@ TypedValue Tail(const std::vector &args, Context *) { return list; } default: - throw QueryRuntimeException("tail argument should be a list"); + throw QueryRuntimeException("'tail' argument must be a list."); } } TypedValue Abs(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("abs requires one argument"); + throw QueryRuntimeException("'abs' requires exactly one argument."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -394,26 +394,27 @@ TypedValue Abs(const std::vector &args, Context *) { case TypedValue::Type::Double: return std::abs(args[0].Value()); default: - throw QueryRuntimeException("abs argument should be a number"); + throw QueryRuntimeException("'abs' argument should be a number."); } } -#define WRAP_CMATH_FLOAT_FUNCTION(name, lowercased_name) \ - TypedValue name(const std::vector &args, Context *) { \ - if (args.size() != 1U) { \ - throw QueryRuntimeException(#lowercased_name " requires one argument"); \ - } \ - switch (args[0].type()) { \ - case TypedValue::Type::Null: \ - return TypedValue::Null; \ - case TypedValue::Type::Int: \ - return lowercased_name(args[0].Value()); \ - case TypedValue::Type::Double: \ - return lowercased_name(args[0].Value()); \ - default: \ - throw QueryRuntimeException(#lowercased_name \ - " argument should be a number"); \ - } \ +#define WRAP_CMATH_FLOAT_FUNCTION(name, lowercased_name) \ + TypedValue name(const std::vector &args, Context *) { \ + if (args.size() != 1U) { \ + throw QueryRuntimeException("'" #lowercased_name \ + "' requires exactly one argument."); \ + } \ + switch (args[0].type()) { \ + case TypedValue::Type::Null: \ + return TypedValue::Null; \ + case TypedValue::Type::Int: \ + return lowercased_name(args[0].Value()); \ + case TypedValue::Type::Double: \ + return lowercased_name(args[0].Value()); \ + default: \ + throw QueryRuntimeException(#lowercased_name \ + " argument must be a number."); \ + } \ } WRAP_CMATH_FLOAT_FUNCTION(Ceil, ceil) @@ -436,7 +437,7 @@ WRAP_CMATH_FLOAT_FUNCTION(Tan, tan) TypedValue Atan2(const std::vector &args, Context *) { if (args.size() != 2U) { - throw QueryRuntimeException("atan2 requires two arguments"); + throw QueryRuntimeException("'atan2' requires two arguments."); } if (args[0].type() == TypedValue::Type::Null) return TypedValue::Null; if (args[1].type() == TypedValue::Type::Null) return TypedValue::Null; @@ -447,7 +448,7 @@ TypedValue Atan2(const std::vector &args, Context *) { case TypedValue::Type::Double: return t.Value(); default: - throw QueryRuntimeException("arguments of atan2 should be numbers"); + throw QueryRuntimeException("Arguments of 'atan2' must be numbers."); } }; double y = to_double(args[0]); @@ -457,7 +458,7 @@ TypedValue Atan2(const std::vector &args, Context *) { TypedValue Sign(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("sign requires one argument"); + throw QueryRuntimeException("'sign' requires exactly one argument."); } auto sign = [](auto x) { return (0 < x) - (x < 0); }; switch (args[0].type()) { @@ -468,20 +469,20 @@ TypedValue Sign(const std::vector &args, Context *) { case TypedValue::Type::Double: return sign(args[0].Value()); default: - throw QueryRuntimeException("sign argument should be a number"); + throw QueryRuntimeException("'sign' argument must be a number."); } } TypedValue E(const std::vector &args, Context *) { if (args.size() != 0U) { - throw QueryRuntimeException("e requires no arguments"); + throw QueryRuntimeException("'e' requires no arguments."); } return M_E; } TypedValue Pi(const std::vector &args, Context *) { if (args.size() != 0U) { - throw QueryRuntimeException("pi requires no arguments"); + throw QueryRuntimeException("'pi' requires no arguments."); } return M_PI; } @@ -490,7 +491,7 @@ TypedValue Rand(const std::vector &args, Context *) { static thread_local std::mt19937 pseudo_rand_gen_{std::random_device{}()}; static thread_local std::uniform_real_distribution<> rand_dist_{0, 1}; if (args.size() != 0U) { - throw QueryRuntimeException("rand requires no arguments"); + throw QueryRuntimeException("'rand' requires no arguments."); } return rand_dist_(pseudo_rand_gen_); } @@ -499,7 +500,7 @@ template TypedValue StringMatchOperator(const std::vector &args, Context *) { if (args.size() != 2U) { throw QueryRuntimeException( - "startsWith and endsWith require two arguments"); + "'startsWith' and 'endsWith' require two arguments."); } bool has_null = false; auto check_arg = [&](const TypedValue &t) { @@ -507,7 +508,7 @@ TypedValue StringMatchOperator(const std::vector &args, Context *) { has_null = true; } else if (t.type() != TypedValue::Type::String) { throw QueryRuntimeException( - "arguments of startsWith and endsWith should be strings"); + "Arguments of 'startsWith' and 'endsWith' must be strings."); } }; check_arg(args[0]); @@ -541,15 +542,18 @@ auto Contains = StringMatchOperator; TypedValue Assert(const std::vector &args, Context *) { if (args.size() < 1U || args.size() > 2U) { - throw QueryRuntimeException("assert requires one or two arguments"); + throw QueryRuntimeException("'assert' requires one or two arguments"); } if (args[0].type() != TypedValue::Type::Bool) - throw QueryRuntimeException("first argument of assert must be a boolean"); + throw QueryRuntimeException( + "First argument of 'assert' must be a boolean."); if (args.size() == 2U && args[1].type() != TypedValue::Type::String) - throw QueryRuntimeException("second argument of assert must be a string"); + throw QueryRuntimeException( + "Second argument of 'assert' must be a string."); if (!args[0].ValueBool()) { - std::string message("assertion failed"); + std::string message("Assertion failed"); if (args.size() == 2U) message += ": " + args[1].ValueString(); + message += "."; throw QueryRuntimeException(message); } return args[0]; @@ -557,31 +561,31 @@ TypedValue Assert(const std::vector &args, Context *) { TypedValue Counter(const std::vector &args, Context *ctx) { if (args.size() != 1U) { - throw QueryRuntimeException("counter requires one argument"); + throw QueryRuntimeException("'counter' requires exactly one argument."); } if (!args[0].IsString()) - throw QueryRuntimeException("counter argument must be a string"); + throw QueryRuntimeException("'counter' argument must be a string."); return ctx->db_accessor_.Counter(args[0].ValueString()); } TypedValue CounterSet(const std::vector &args, Context *ctx) { if (args.size() != 2U) { - throw QueryRuntimeException("counterSet requires two arguments"); + throw QueryRuntimeException("'counterSet' requires two arguments."); } if (!args[0].IsString()) throw QueryRuntimeException( - "first argument of counterSet must be a string"); + "First argument of 'counterSet' must be a string."); if (!args[1].IsInt()) throw QueryRuntimeException( - "second argument of counterSet must be an integer"); + "Second argument of 'counterSet' must be an integer."); ctx->db_accessor_.CounterSet(args[0].ValueString(), args[1].ValueInt()); return TypedValue::Null; } TypedValue IndexInfo(const std::vector &args, Context *ctx) { if (args.size() != 0U) - throw QueryRuntimeException("indexInfo requires no arguments"); + throw QueryRuntimeException("'indexInfo' requires no arguments."); auto info = ctx->db_accessor_.IndexInfo(); return std::vector(info.begin(), info.end()); @@ -589,7 +593,7 @@ TypedValue IndexInfo(const std::vector &args, Context *ctx) { TypedValue WorkerId(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("workerId requires one argument"); + throw QueryRuntimeException("'workerId' requires exactly one argument."); } auto &arg = args[0]; switch (arg.type()) { @@ -599,13 +603,13 @@ TypedValue WorkerId(const std::vector &args, Context *) { return arg.ValueEdge().GlobalAddress().worker_id(); default: throw QueryRuntimeException( - "workerId argument must be a vertex or an edge"); + "'workerId' argument must be a node or an edge."); } } TypedValue Id(const std::vector &args, Context *ctx) { if (args.size() != 1U) { - throw QueryRuntimeException("id requires one argument"); + throw QueryRuntimeException("'id' requires exactly one argument."); } auto &arg = args[0]; switch (arg.type()) { @@ -616,13 +620,13 @@ TypedValue Id(const std::vector &args, Context *ctx) { return TypedValue(arg.ValueEdge().cypher_id()); } default: - throw QueryRuntimeException("id argument must be a vertex or an edge"); + throw QueryRuntimeException("'id' argument must be a node or an edge."); } } TypedValue ToString(const std::vector &args, Context *) { if (args.size() != 1U) { - throw QueryRuntimeException("toString requires one argument"); + throw QueryRuntimeException("'toString' requires exactly one argument."); } auto &arg = args[0]; switch (arg.type()) { @@ -638,20 +642,20 @@ TypedValue ToString(const std::vector &args, Context *) { return arg.ValueBool() ? "true" : "false"; default: throw QueryRuntimeException( - "toString argument must be a number, a string or a boolean"); + "'toString' argument must be a number, a string or a boolean."); } } TypedValue Timestamp(const std::vector &args, Context *ctx) { if (args.size() != 0) { - throw QueryRuntimeException("timestamp requires no arguments"); + throw QueryRuntimeException("'timestamp' requires no arguments."); } return ctx->timestamp_; } TypedValue Left(const std::vector &args, Context *ctx) { if (args.size() != 2) { - throw QueryRuntimeException("left requires two arguments"); + throw QueryRuntimeException("'left' requires two arguments."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -659,21 +663,21 @@ TypedValue Left(const std::vector &args, Context *ctx) { return TypedValue::Null; } throw QueryRuntimeException( - "second argument of left must be a non-negative integer"); + "Second argument of 'left' must be a non-negative integer."); case TypedValue::Type::String: if (args[1].IsInt() && args[1].ValueInt() >= 0) { return args[0].ValueString().substr(0, args[1].ValueInt()); } throw QueryRuntimeException( - "second argument of left must be a non-negative integer"); + "Second argument of 'left' must be a non-negative integer."); default: - throw QueryRuntimeException("first argument of left must be a string"); + throw QueryRuntimeException("First argument of 'left' must be a string."); } } TypedValue Right(const std::vector &args, Context *ctx) { if (args.size() != 2) { - throw QueryRuntimeException("right requires two arguments"); + throw QueryRuntimeException("'right' requires two arguments."); } switch (args[0].type()) { case TypedValue::Type::Null: @@ -681,7 +685,7 @@ TypedValue Right(const std::vector &args, Context *ctx) { return TypedValue::Null; } throw QueryRuntimeException( - "second argument of right must be a non-negative integer"); + "Second argument of 'right' must be a non-negative integer."); case TypedValue::Type::String: { const auto &str = args[0].ValueString(); if (args[1].IsInt() && args[1].ValueInt() >= 0) { @@ -689,27 +693,29 @@ TypedValue Right(const std::vector &args, Context *ctx) { return len <= str.size() ? str.substr(str.size() - len, len) : str; } throw QueryRuntimeException( - "second argument of right must be a non-negative integer"); + "Second argument of 'right' must be a non-negative integer."); } default: - throw QueryRuntimeException("first argument of right must be a string"); + throw QueryRuntimeException( + "First argument of 'right' must be a string."); } } -#define WRAP_STRING_FUNCTION(name, lowercased_name, function) \ - TypedValue name(const std::vector &args, Context *) { \ - if (args.size() != 1U) { \ - throw QueryRuntimeException(#lowercased_name " requires one argument"); \ - } \ - switch (args[0].type()) { \ - case TypedValue::Type::Null: \ - return TypedValue::Null; \ - case TypedValue::Type::String: \ - return function(args[0].ValueString()); \ - default: \ - throw QueryRuntimeException(#lowercased_name \ - " argument should be a string"); \ - } \ +#define WRAP_STRING_FUNCTION(name, lowercased_name, function) \ + TypedValue name(const std::vector &args, Context *) { \ + if (args.size() != 1U) { \ + throw QueryRuntimeException("'" #lowercased_name \ + "' requires exactly one argument."); \ + } \ + switch (args[0].type()) { \ + case TypedValue::Type::Null: \ + return TypedValue::Null; \ + case TypedValue::Type::String: \ + return function(args[0].ValueString()); \ + default: \ + throw QueryRuntimeException("'" #lowercased_name \ + "' argument should be a string."); \ + } \ } WRAP_STRING_FUNCTION(LTrim, lTrim, utils::LTrim); @@ -721,17 +727,19 @@ WRAP_STRING_FUNCTION(ToUpper, toUpper, utils::ToUpperCase); TypedValue Replace(const std::vector &args, Context *ctx) { if (args.size() != 3U) { - throw QueryRuntimeException("replace requires three arguments"); + throw QueryRuntimeException("'replace' requires three arguments."); } if (!args[0].IsNull() && !args[0].IsString()) { - throw QueryRuntimeException("first argument of replace should be a string"); + throw QueryRuntimeException( + "First argument of 'replace' should be a string."); } if (!args[1].IsNull() && !args[1].IsString()) { throw QueryRuntimeException( - "second argument of replace should be a string"); + "Second argument of 'replace' should be a string."); } if (!args[2].IsNull() && !args[2].IsString()) { - throw QueryRuntimeException("third argument of replace should be a string"); + throw QueryRuntimeException( + "Third argument of 'replace' should be a string."); } if (args[0].IsNull() || args[1].IsNull() || args[2].IsNull()) { return TypedValue::Null; @@ -742,13 +750,15 @@ TypedValue Replace(const std::vector &args, Context *ctx) { TypedValue Split(const std::vector &args, Context *ctx) { if (args.size() != 2U) { - throw QueryRuntimeException("split requires two arguments"); + throw QueryRuntimeException("'split' requires two arguments."); } if (!args[0].IsNull() && !args[0].IsString()) { - throw QueryRuntimeException("first argument of split should be a string"); + throw QueryRuntimeException( + "First argument of 'split' should be a string."); } if (!args[1].IsNull() && !args[1].IsString()) { - throw QueryRuntimeException("second argument of split should be a string"); + throw QueryRuntimeException( + "Second argument of 'split' should be a string."); } if (args[0].IsNull() || args[1].IsNull()) { return TypedValue::Null; @@ -763,19 +773,19 @@ TypedValue Split(const std::vector &args, Context *ctx) { TypedValue Substring(const std::vector &args, Context *) { if (args.size() != 2U && args.size() != 3U) { - throw QueryRuntimeException("substring requires two or three arguments"); + throw QueryRuntimeException("'substring' requires two or three arguments."); } if (!args[0].IsNull() && !args[0].IsString()) { throw QueryRuntimeException( - "first argument of substring should be a string"); + "First argument of 'substring' should be a string."); } if (!args[1].IsInt() || args[1].ValueInt() < 0) { throw QueryRuntimeException( - "second argument of substring should be a non-negative integer"); + "Second argument of 'substring' should be a non-negative integer."); } if (args.size() == 3U && (!args[2].IsInt() || args[2].ValueInt() < 0)) { throw QueryRuntimeException( - "third argument of substring should be a non-negative integer"); + "Third argument of 'substring' should be a non-negative integer."); } if (args[0].IsNull()) { return TypedValue::Null; diff --git a/src/query/interpret/eval.hpp b/src/query/interpret/eval.hpp index 540eaeb9a..b1b4e9517 100644 --- a/src/query/interpret/eval.hpp +++ b/src/query/interpret/eval.hpp @@ -80,20 +80,20 @@ class ExpressionEvaluator : public TreeVisitor { try { \ return val1 CPP_OP val2; \ } catch (const TypedValueException &) { \ - throw QueryRuntimeException("Invalid types: {} and {} for '{}'", \ + throw QueryRuntimeException("Invalid types: {} and {} for '{}'.", \ val1.type(), val2.type(), #CYPHER_OP); \ } \ } -#define UNARY_OPERATOR_VISITOR(OP_NODE, CPP_OP, CYPHER_OP) \ - TypedValue Visit(OP_NODE &op) override { \ - auto val = op.expression_->Accept(*this); \ - try { \ - return CPP_OP val; \ - } catch (const TypedValueException &) { \ - throw QueryRuntimeException("Invalid type {} for '{}'", val.type(), \ - #CYPHER_OP); \ - } \ +#define UNARY_OPERATOR_VISITOR(OP_NODE, CPP_OP, CYPHER_OP) \ + TypedValue Visit(OP_NODE &op) override { \ + auto val = op.expression_->Accept(*this); \ + try { \ + return CPP_OP val; \ + } catch (const TypedValueException &) { \ + throw QueryRuntimeException("Invalid type {} for '{}'.", val.type(), \ + #CYPHER_OP); \ + } \ } BINARY_OPERATOR_VISITOR(OrOperator, ||, OR); @@ -127,7 +127,7 @@ class ExpressionEvaluator : public TreeVisitor { try { return value1 && value2; } catch (const TypedValueException &) { - throw QueryRuntimeException("Invalid types: {} and {} for 'AND'", + throw QueryRuntimeException("Invalid types: {} and {} for AND.", value1.type(), value2.type()); } } @@ -139,8 +139,8 @@ class ExpressionEvaluator : public TreeVisitor { } if (condition.type() != TypedValue::Type::Bool) { // At the moment IfOperator is used only in CASE construct. - throw QueryRuntimeException( - "'CASE' expected boolean expression, but got {}", condition.type()); + throw QueryRuntimeException("CASE expected boolean expression, got {}.", + condition.type()); } if (condition.Value()) { return if_operator.then_expression_->Accept(*this); @@ -157,7 +157,7 @@ class ExpressionEvaluator : public TreeVisitor { // Exceptions have higher priority than returning nulls when list expression // is not null. if (_list.type() != TypedValue::Type::List) { - throw QueryRuntimeException("'IN' expected a list, but got {}", + throw QueryRuntimeException("IN expected a list, got {}.", _list.type()); } auto list = _list.Value>(); @@ -190,14 +190,14 @@ class ExpressionEvaluator : public TreeVisitor { if (!lhs.IsList() && !lhs.IsMap() && !lhs.IsVertex() && !lhs.IsEdge() && !lhs.IsNull()) throw QueryRuntimeException( - "Expected a list, a map, a vertex or an edge to index with '[]', but " - "got {}", + "Expected a list, a map, a node or an edge to index with '[]', got " + "{}.", lhs.type()); if (lhs.IsNull() || index.IsNull()) return TypedValue::Null; if (lhs.IsList()) { if (!index.IsInt()) throw QueryRuntimeException( - "Expected an int as a list index, but got {}", index.type()); + "Expected an integer as a list index, got {}.", index.type()); auto index_int = index.Value(); const auto &list = lhs.Value>(); if (index_int < 0) { @@ -210,8 +210,8 @@ class ExpressionEvaluator : public TreeVisitor { if (lhs.IsMap()) { if (!index.IsString()) - throw QueryRuntimeException( - "Expected a string as a map index, but got {}", index.type()); + throw QueryRuntimeException("Expected a string as a map index, got {}.", + index.type()); const auto &map = lhs.Value>(); auto found = map.find(index.Value()); if (found == map.end()) return TypedValue::Null; @@ -221,7 +221,7 @@ class ExpressionEvaluator : public TreeVisitor { if (lhs.IsVertex()) { if (!index.IsString()) throw QueryRuntimeException( - "Expected a string as a property name, but got {}", index.type()); + "Expected a string as a property name, got {}.", index.type()); return lhs.Value().PropsAt( context_->db_accessor_.Property(index.Value())); } @@ -229,7 +229,7 @@ class ExpressionEvaluator : public TreeVisitor { if (lhs.IsEdge()) { if (!index.IsString()) throw QueryRuntimeException( - "Expected a string as a property name, but got {}", index.type()); + "Expected a string as a property name, got {}.", index.type()); return lhs.Value().PropsAt( context_->db_accessor_.Property(index.Value())); } @@ -249,7 +249,7 @@ class ExpressionEvaluator : public TreeVisitor { is_null = true; } else if (bound.type() != TypedValue::Type::Int) { throw QueryRuntimeException( - "Expected an int for a bound in list slicing, but got {}", + "Expected an integer for a bound in list slicing, got {}.", bound.type()); } return bound; @@ -264,7 +264,7 @@ class ExpressionEvaluator : public TreeVisitor { if (_list.type() == TypedValue::Type::Null) { is_null = true; } else if (_list.type() != TypedValue::Type::List) { - throw QueryRuntimeException("Expected a list to slice, but got {}", + throw QueryRuntimeException("Expected a list to slice, got {}.", _list.type()); } @@ -313,7 +313,7 @@ class ExpressionEvaluator : public TreeVisitor { } default: throw QueryRuntimeException( - "Expected Node, Edge or Map for property lookup"); + "Only nodes, edges and maps have properties to be looked-up."); } } @@ -332,7 +332,7 @@ class ExpressionEvaluator : public TreeVisitor { return true; } default: - throw QueryRuntimeException("Expected Node in labels test"); + throw QueryRuntimeException("Only nodes have labels."); } } @@ -379,7 +379,7 @@ class ExpressionEvaluator : public TreeVisitor { return TypedValue::Null; } if (list_value.type() != TypedValue::Type::List) { - throw QueryRuntimeException("'REDUCE' expected a list, but got {}", + throw QueryRuntimeException("REDUCE expected a list, got {}.", list_value.type()); } const auto &list = list_value.Value>(); @@ -402,7 +402,7 @@ class ExpressionEvaluator : public TreeVisitor { return TypedValue::Null; } if (list_value.type() != TypedValue::Type::List) { - throw QueryRuntimeException("'EXTRACT' expected a list, but got {}", + throw QueryRuntimeException("EXTRACT expected a list, got {}.", list_value.type()); } const auto &list = list_value.Value>(); @@ -427,7 +427,7 @@ class ExpressionEvaluator : public TreeVisitor { return TypedValue::Null; } if (list_value.type() != TypedValue::Type::List) { - throw QueryRuntimeException("'ALL' expected a list, but got {}", + throw QueryRuntimeException("ALL expected a list, got {}.", list_value.type()); } const auto &list = list_value.Value>(); @@ -437,8 +437,7 @@ class ExpressionEvaluator : public TreeVisitor { auto result = all.where_->expression_->Accept(*this); if (!result.IsNull() && result.type() != TypedValue::Type::Bool) { throw QueryRuntimeException( - "Predicate of 'ALL' needs to evaluate to 'Boolean', but it " - "resulted in '{}'", + "Predicate of ALL must evaluate to boolean, got {}.", result.type()); } if (result.IsNull() || !result.Value()) { @@ -454,7 +453,7 @@ class ExpressionEvaluator : public TreeVisitor { return TypedValue::Null; } if (list_value.type() != TypedValue::Type::List) { - throw QueryRuntimeException("'SINGLE' expected a list, but got {}", + throw QueryRuntimeException("SINGLE expected a list, got {}.", list_value.type()); } const auto &list = list_value.Value>(); @@ -465,8 +464,7 @@ class ExpressionEvaluator : public TreeVisitor { auto result = single.where_->expression_->Accept(*this); if (!result.IsNull() && result.type() != TypedValue::Type::Bool) { throw QueryRuntimeException( - "Predicate of 'SINGLE' needs to evaluate to 'Boolean', but it " - "resulted in '{}'", + "Predicate of SINGLE must evaluate to boolean, got {}.", result.type()); } if (result.IsNull() || !result.Value()) { diff --git a/src/query/interpreter.cpp b/src/query/interpreter.cpp index 3914e7235..7dc93e6d2 100644 --- a/src/query/interpreter.cpp +++ b/src/query/interpreter.cpp @@ -46,7 +46,7 @@ Interpreter::Results Interpreter::operator()( auto param_it = params.find(param_pair.second); if (param_it == params.end()) { throw query::UnprovidedParameterError( - fmt::format("Parameter ${} not provided", param_pair.second)); + fmt::format("Parameter ${} not provided.", param_pair.second)); } ctx.parameters_.Add(param_pair.first, param_it->second); } diff --git a/src/query/plan/distributed_ops.cpp b/src/query/plan/distributed_ops.cpp index d077c94cb..011af3424 100644 --- a/src/query/plan/distributed_ops.cpp +++ b/src/query/plan/distributed_ops.cpp @@ -208,13 +208,13 @@ class RemotePuller { break; case distributed::PullState::SERIALIZATION_ERROR: throw mvcc::SerializationError( - "Serialization error occured during PullRemote !"); + "Serialization error occured during PullRemote!"); case distributed::PullState::LOCK_TIMEOUT_ERROR: throw utils::LockTimeoutException( - "LockTimeout error occured during PullRemote !"); + "LockTimeout error occured during PullRemote!"); case distributed::PullState::UPDATE_DELETED_ERROR: throw QueryRuntimeException( - "RecordDeleted error ocured during PullRemote !"); + "RecordDeleted error ocured during PullRemote!"); case distributed::PullState::RECONSTRUCTION_ERROR: throw query::ReconstructionException(); case distributed::PullState::UNABLE_TO_DELETE_VERTEX_ERROR: @@ -223,7 +223,7 @@ class RemotePuller { throw HintedAbortError(); case distributed::PullState::QUERY_ERROR: throw QueryRuntimeException( - "Query runtime error occurred during PullRemote !"); + "Query runtime error occurred during PullRemote!"); } } } @@ -501,23 +501,23 @@ class SynchronizeCursor : public Cursor { continue; case distributed::PullState::CURSOR_IN_PROGRESS: throw QueryRuntimeException( - "Expected exhausted cursor after remote pull accumulate"); + "Expected exhausted cursor after remote pull accumulate!"); case distributed::PullState::SERIALIZATION_ERROR: throw mvcc::SerializationError( "Failed to perform remote accumulate due to " - "SerializationError"); + "SerializationError!"); case distributed::PullState::UPDATE_DELETED_ERROR: throw QueryRuntimeException( "Failed to perform remote accumulate due to " - "RecordDeletedError"); + "RecordDeletedError!"); case distributed::PullState::LOCK_TIMEOUT_ERROR: throw utils::LockTimeoutException( "Failed to perform remote accumulate due to " - "LockTimeoutException"); + "LockTimeoutException!"); case distributed::PullState::RECONSTRUCTION_ERROR: throw QueryRuntimeException( "Failed to perform remote accumulate due to " - "ReconstructionError"); + "ReconstructionError!"); case distributed::PullState::UNABLE_TO_DELETE_VERTEX_ERROR: throw RemoveAttachedVertexException(); case distributed::PullState::HINTED_ABORT_ERROR: @@ -525,7 +525,7 @@ class SynchronizeCursor : public Cursor { case distributed::PullState::QUERY_ERROR: throw QueryRuntimeException( "Failed to perform remote accumulate due to Query runtime " - "error"); + "error!"); } } @@ -541,15 +541,15 @@ class SynchronizeCursor : public Cursor { switch (future.get()) { case distributed::UpdateResult::SERIALIZATION_ERROR: throw mvcc::SerializationError( - "Failed to apply deferred updates due to SerializationError"); + "Failed to apply deferred updates due to SerializationError!"); case distributed::UpdateResult::UNABLE_TO_DELETE_VERTEX_ERROR: throw RemoveAttachedVertexException(); case distributed::UpdateResult::UPDATE_DELETED_ERROR: throw QueryRuntimeException( - "Failed to apply deferred updates due to RecordDeletedError"); + "Failed to apply deferred updates due to RecordDeletedError!"); case distributed::UpdateResult::LOCK_TIMEOUT_ERROR: throw utils::LockTimeoutException( - "Failed to apply deferred update due to LockTimeoutException"); + "Failed to apply deferred update due to LockTimeoutException!"); case distributed::UpdateResult::DONE: break; } diff --git a/src/query/plan/operator.cpp b/src/query/plan/operator.cpp index 35c3618d2..5399a5660 100644 --- a/src/query/plan/operator.cpp +++ b/src/query/plan/operator.cpp @@ -93,7 +93,8 @@ bool EvaluateFilter(ExpressionEvaluator &evaluator, Expression *filter) { if (result.IsNull()) return false; if (result.type() != TypedValue::Type::Bool) throw QueryRuntimeException( - "Filter expression must be a bool or null, but got {}.", result.type()); + "Filter expression must evaluate to bool or null, got {}.", + result.type()); return result.Value(); } @@ -885,7 +886,7 @@ class ExpandVariableCursor : public Cursor { auto value = EvaluateInt(&evaluator, bound, "Variable expansion bound"); if (value < 0) throw QueryRuntimeException( - "Variable expansion bound must be positive or zero"); + "Variable expansion bound must be a non-negative integer."); return value; }; @@ -1281,7 +1282,7 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor { break; default: throw QueryRuntimeException( - "Expansion condition must be boolean or null"); + "Expansion condition must evaluate to boolean or null."); } } to_visit_next_.emplace_back(edge, vertex); @@ -1331,8 +1332,7 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor { : std::numeric_limits::max(); if (upper_bound_ < 1) throw QueryRuntimeException( - "Max depth in breadth-first expansion must be greater then " - "zero"); + "Maximum depth in breadth-first expansion must be at least 1."); // go back to loop start and see if we expanded anything continue; @@ -1433,11 +1433,11 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor { self_.weight_lambda_->expression->Accept(evaluator); if (!typed_weight.IsNumeric()) { - throw QueryRuntimeException("Calculated weight must be numeric, got {}", - typed_weight.type()); + throw QueryRuntimeException( + "Calculated weight must be numeric, got {}.", typed_weight.type()); } if ((typed_weight < 0).Value()) { - throw QueryRuntimeException("Calculated weight can't be negative!"); + throw QueryRuntimeException("Calculated weight must be non-negative!"); } auto next_state = create_state(vertex, depth); @@ -1491,8 +1491,8 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor { } if (upper_bound_ < 1) throw QueryRuntimeException( - "Max depth in weighted shortest path expansion must be greater " - "than zero"); + "Maximum depth in weighted shortest path expansion must be at " + "least 1."); // Clear existing data structures. previous_.clear(); @@ -1880,7 +1880,7 @@ bool Delete::DeleteCursor::Pull(Frame &frame, Context &context) { break; // check we're not trying to delete anything except vertices and edges default: - throw QueryRuntimeException("Can only delete edges and vertices"); + throw QueryRuntimeException("Only edges and vertices can be deleted."); } return true; @@ -1935,7 +1935,7 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, Context &context) { // TODO: fix above described bug default: throw QueryRuntimeException( - "Properties can only be set on Vertices and Edges"); + "Properties can only be set on edges and vertices."); } return true; } @@ -1983,7 +1983,7 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, Context &context) { break; default: throw QueryRuntimeException( - "Properties can only be set on Vertices and Edges"); + "Properties can only be set on edges and vertices."); } return true; } @@ -2026,7 +2026,8 @@ void SetProperties::SetPropertiesCursor::Set(TRecordAccessor &record, } default: throw QueryRuntimeException( - "Can only set Vertices, Edges and maps as properties"); + "Right-hand side in SET expression must be a node, an edge or a " + "map."); } } @@ -2069,7 +2070,7 @@ bool SetLabels::SetLabelsCursor::Pull(Frame &frame, Context &context) { try { for (auto label : self_.labels_) vertex.add_label(label); } catch (const RecordDeletedError &) { - throw QueryRuntimeException("Trying to set labels on a deleted Vertex"); + throw QueryRuntimeException("Trying to set labels on a deleted node."); } return true; @@ -2111,7 +2112,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, lhs.Value().PropsErase(self_.lhs_->property_); } catch (const RecordDeletedError &) { throw QueryRuntimeException( - "Trying to remove properties from a deleted Vertex"); + "Trying to remove properties from a deleted node."); } break; case TypedValue::Type::Edge: @@ -2119,7 +2120,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, lhs.Value().PropsErase(self_.lhs_->property_); } catch (const RecordDeletedError &) { throw QueryRuntimeException( - "Trying to remove properties from a deleted Edge"); + "Trying to remove properties from a deleted edge."); } break; case TypedValue::Type::Null: @@ -2127,7 +2128,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, break; default: throw QueryRuntimeException( - "Properties can only be removed on Vertices and Edges"); + "Properties can only be removed from vertices and edges."); } return true; } @@ -2168,7 +2169,7 @@ bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, Context &context) { for (auto label : self_.labels_) vertex.remove_label(label); } catch (const RecordDeletedError &) { throw QueryRuntimeException( - "Trying to remove labels from a deleted Vertex"); + "Trying to remove labels from a deleted node."); } return true; @@ -2497,7 +2498,7 @@ void Aggregate::AggregateCursor::Update( case Aggregation::Op::COLLECT_MAP: auto key = agg_elem_it->key->Accept(evaluator); if (key.type() != TypedValue::Type::String) - throw QueryRuntimeException("Map key must be a string"); + throw QueryRuntimeException("Map key must be a string."); value_it->Value>().emplace( key.Value(), input_value); break; @@ -2519,7 +2520,7 @@ void Aggregate::AggregateCursor::Update( // safe to assume a bool TypedValue if (comparison_result.Value()) *value_it = input_value; } catch (const TypedValueException &) { - throw QueryRuntimeException("Unable to get MIN of '{}' and '{}'", + throw QueryRuntimeException("Unable to get MIN of '{}' and '{}'.", input_value.type(), value_it->type()); } break; @@ -2531,7 +2532,7 @@ void Aggregate::AggregateCursor::Update( TypedValue comparison_result = input_value > *value_it; if (comparison_result.Value()) *value_it = input_value; } catch (const TypedValueException &) { - throw QueryRuntimeException("Unable to get MAX of '{}' and '{}'", + throw QueryRuntimeException("Unable to get MAX of '{}' and '{}'.", input_value.type(), value_it->type()); } break; @@ -2549,7 +2550,7 @@ void Aggregate::AggregateCursor::Update( case Aggregation::Op::COLLECT_MAP: auto key = agg_elem_it->key->Accept(evaluator); if (key.type() != TypedValue::Type::String) - throw QueryRuntimeException("Map key must be a string"); + throw QueryRuntimeException("Map key must be a string."); value_it->Value>().emplace( key.Value(), input_value); break; @@ -2574,8 +2575,8 @@ void Aggregate::AggregateCursor::EnsureOkForMinMax( return; default: throw QueryRuntimeException( - "Only Bool, Int, Double and String values are allowed in " - "MIN and MAX aggregations"); + "Only boolean, numeric and string values are allowed in " + "MIN and MAX aggregations."); } } void Aggregate::AggregateCursor::EnsureOkForAvgSum( @@ -2586,7 +2587,7 @@ void Aggregate::AggregateCursor::EnsureOkForAvgSum( return; default: throw QueryRuntimeException( - "Only numeric values allowed in SUM and AVG aggregations"); + "Only numeric values allowed in SUM and AVG aggregations."); } } @@ -2631,12 +2632,13 @@ bool Skip::SkipCursor::Pull(Frame &frame, Context &context) { ExpressionEvaluator evaluator(frame, &context, GraphView::OLD); TypedValue to_skip = self_.expression_->Accept(evaluator); if (to_skip.type() != TypedValue::Type::Int) - throw QueryRuntimeException("Result of SKIP expression must be an int"); + throw QueryRuntimeException( + "Number of elements to skip must be an integer."); to_skip_ = to_skip.Value(); if (to_skip_ < 0) throw QueryRuntimeException( - "Result of SKIP expression must be greater or equal to zero"); + "Number of elements to skip must be non-negative."); } if (skipped_++ < to_skip_) continue; @@ -2686,12 +2688,13 @@ bool Limit::LimitCursor::Pull(Frame &frame, Context &context) { ExpressionEvaluator evaluator(frame, &context, GraphView::OLD); TypedValue limit = self_.expression_->Accept(evaluator); if (limit.type() != TypedValue::Type::Int) - throw QueryRuntimeException("Result of LIMIT expression must be an int"); + throw QueryRuntimeException( + "Limit on number of returned elements must be an integer."); limit_ = limit.Value(); if (limit_ < 0) throw QueryRuntimeException( - "Result of LIMIT expression must be greater or equal to zero"); + "Limit on number of returned elements must be non-negative."); } // check we have not exceeded the limit before pulling @@ -2976,8 +2979,9 @@ bool Unwind::UnwindCursor::Pull(Frame &frame, Context &context) { ExpressionEvaluator evaluator(frame, &context, GraphView::OLD); TypedValue input_value = self_.input_expression_->Accept(evaluator); if (input_value.type() != TypedValue::Type::List) - throw QueryRuntimeException("UNWIND only accepts list values, got '{}'", - input_value.type()); + throw QueryRuntimeException( + "Argument of UNWIND must be a list, but '{}' was provided.", + input_value.type()); input_value_ = input_value.Value>(); input_value_it_ = input_value_.begin(); } @@ -3377,7 +3381,8 @@ class AuthHandlerCursor : public Cursor { auto password_tv = self_.password()->Accept(evaluator); if (!password_tv.IsString() && !password_tv.IsNull()) { throw QueryRuntimeException( - "Password must be a string or null, not '{}'!", password_tv.type()); + "Expected string or null for password, got {}.", + password_tv.type()); } if (password_tv.IsString()) { password = password_tv.ValueString(); @@ -3391,7 +3396,7 @@ class AuthHandlerCursor : public Cursor { std::lock_guard lock(auth.WithLock()); auto user = auth.AddUser(self_.user(), password); if (!user) { - throw QueryRuntimeException("User or role '{}' already exists!", + throw QueryRuntimeException("User or role '{}' already exists.", self_.user()); } return false; @@ -3401,10 +3406,10 @@ class AuthHandlerCursor : public Cursor { std::lock_guard lock(auth.WithLock()); auto user = auth.GetUser(self_.user()); if (!user) { - throw QueryRuntimeException("User '{}' doesn't exist!", self_.user()); + throw QueryRuntimeException("User '{}' doesn't exist.", self_.user()); } if (!auth.RemoveUser(self_.user())) { - throw QueryRuntimeException("Couldn't remove user '{}'!", + throw QueryRuntimeException("Couldn't remove user '{}'.", self_.user()); } return false; @@ -3414,7 +3419,7 @@ class AuthHandlerCursor : public Cursor { std::lock_guard lock(auth.WithLock()); auto user = auth.GetUser(self_.user()); if (!user) { - throw QueryRuntimeException("User '{}' doesn't exist!", self_.user()); + throw QueryRuntimeException("User '{}' doesn't exist.", self_.user()); } user->UpdatePassword(password); auth.SaveUser(*user); @@ -3425,7 +3430,7 @@ class AuthHandlerCursor : public Cursor { std::lock_guard lock(auth.WithLock()); auto role = auth.AddRole(self_.role()); if (!role) { - throw QueryRuntimeException("User or role '{}' already exists!", + throw QueryRuntimeException("User or role '{}' already exists.", self_.role()); } return false; @@ -3435,10 +3440,10 @@ class AuthHandlerCursor : public Cursor { std::lock_guard lock(auth.WithLock()); auto role = auth.GetRole(self_.role()); if (!role) { - throw QueryRuntimeException("Role '{}' doesn't exist!", self_.role()); + throw QueryRuntimeException("Role '{}' doesn't exist.", self_.role()); } if (!auth.RemoveRole(self_.role())) { - throw QueryRuntimeException("Couldn't remove role '{}'!", + throw QueryRuntimeException("Couldn't remove role '{}'.", self_.role()); } return false; @@ -3478,15 +3483,15 @@ class AuthHandlerCursor : public Cursor { std::lock_guard lock(auth.WithLock()); auto user = auth.GetUser(self_.user()); if (!user) { - throw QueryRuntimeException("User '{}' doesn't exist!", self_.user()); + throw QueryRuntimeException("User '{}' doesn't exist.", self_.user()); } auto role = auth.GetRole(self_.role()); if (!role) { - throw QueryRuntimeException("Role '{}' doesn't exist!", self_.role()); + throw QueryRuntimeException("Role '{}' doesn't exist.", self_.role()); } if (user->role()) { throw QueryRuntimeException( - "User '{}' is already a member of role '{}'!", self_.user(), + "User '{}' is already a member of role '{}'.", self_.user(), user->role()->rolename()); } user->SetRole(*role); @@ -3498,7 +3503,7 @@ class AuthHandlerCursor : public Cursor { std::lock_guard lock(auth.WithLock()); auto user = auth.GetUser(self_.user()); if (!user) { - throw QueryRuntimeException("User '{}' doesn't exist!", self_.user()); + throw QueryRuntimeException("User '{}' doesn't exist.", self_.user()); } user->ClearRole(); auth.SaveUser(*user); @@ -3512,7 +3517,7 @@ class AuthHandlerCursor : public Cursor { auto user = auth.GetUser(self_.user_or_role()); auto role = auth.GetRole(self_.user_or_role()); if (!user && !role) { - throw QueryRuntimeException("User or role '{}' doesn't exist!", + throw QueryRuntimeException("User or role '{}' doesn't exist.", self_.user_or_role()); } auto permissions = GetAuthPermissions(); @@ -3554,7 +3559,7 @@ class AuthHandlerCursor : public Cursor { auto user = auth.GetUser(self_.user_or_role()); auto role = auth.GetRole(self_.user_or_role()); if (!user && !role) { - throw QueryRuntimeException("User or role '{}' doesn't exist!", + throw QueryRuntimeException("User or role '{}' doesn't exist.", self_.user_or_role()); } if (user) { @@ -3580,7 +3585,7 @@ class AuthHandlerCursor : public Cursor { std::lock_guard lock(auth.WithLock()); auto user = auth.GetUser(self_.user()); if (!user) { - throw QueryRuntimeException("User '{}' doesn't exist!", self_.user()); + throw QueryRuntimeException("User '{}' doesn't exist.", self_.user()); } if (user->role()) { frame[self_.role_symbol()] = user->role()->rolename(); @@ -3596,7 +3601,7 @@ class AuthHandlerCursor : public Cursor { std::lock_guard lock(auth.WithLock()); auto role = auth.GetRole(self_.role()); if (!role) { - throw QueryRuntimeException("Role '{}' doesn't exist!", + throw QueryRuntimeException("Role '{}' doesn't exist.", self_.role()); } users_.emplace(auth.AllUsersForRole(self_.role())); diff --git a/tests/integration/apollo_runs.yaml b/tests/integration/apollo_runs.yaml index 1ceddd562..cae9ff3f5 100644 --- a/tests/integration/apollo_runs.yaml +++ b/tests/integration/apollo_runs.yaml @@ -36,7 +36,7 @@ - name: integration__auth cd: auth - commands: TIMEOUT=600 ./runner.py + commands: TIMEOUT=820 ./runner.py infiles: - runner.py # runner script - ../../../build_debug/memgraph # memgraph binary diff --git a/tests/unit/query_expression_evaluator.cpp b/tests/unit/query_expression_evaluator.cpp index efc69b08f..005dbcfa8 100644 --- a/tests/unit/query_expression_evaluator.cpp +++ b/tests/unit/query_expression_evaluator.cpp @@ -1403,7 +1403,7 @@ TEST(ExpressionEvaluator, FunctionAssert) { try { EvaluateFunction("ASSERT", {false, "bbgba"}); } catch (QueryRuntimeException &e) { - ASSERT_TRUE(utils::EndsWith(e.what(), "bbgba")); + ASSERT_TRUE(std::string(e.what()).find("bbgba") != std::string::npos); } // Valid calls, assertion passes.