#pragma once #include "utils/exceptions.hpp" #include namespace query { /** * @brief Base class of all query language related exceptions. All exceptions * derived from this one will be interpreted as ClientError-s, i. e. if client * executes same query again without making modifications to the database data, * query will fail again. */ class QueryException : public utils::BasicException { using utils::BasicException::BasicException; }; class LexingException : public QueryException { public: using QueryException::QueryException; LexingException() : QueryException("") {} }; class SyntaxException : public QueryException { public: using QueryException::QueryException; SyntaxException() : QueryException("") {} }; // TODO: Figure out what information to put in exception. // Error reporting is tricky since we get stripped query and position of error // in original query is not same as position of error in stripped query. Most // correct approach would be to do semantic analysis with original query even // for already hashed queries, but that has obvious performance issues. Other // approach would be to report some of the semantic errors in runtime of the // query and only report line numbers of semantic errors (not position in the // line) if multiple line strings are not allowed by grammar. We could also // print whole line that contains error instead of specifying line number. class SemanticException : public QueryException { public: using QueryException::QueryException; SemanticException() : QueryException("") {} }; class UnboundVariableError : public SemanticException { public: explicit UnboundVariableError(const std::string &name) : SemanticException("Unbound variable: " + name + ".") {} }; class RedeclareVariableError : public SemanticException { public: explicit RedeclareVariableError(const std::string &name) : SemanticException("Redeclaring variable: " + name + ".") {} }; class TypeMismatchError : public SemanticException { public: TypeMismatchError(const std::string &name, const std::string &datum, const std::string &expected) : SemanticException(fmt::format( "Type mismatch: {} already defined as {}, expected {}.", name, datum, expected)) {} }; class UnprovidedParameterError : public QueryException { public: using QueryException::QueryException; }; class ProfileInMulticommandTxException : public QueryException { public: using QueryException::QueryException; ProfileInMulticommandTxException() : QueryException("PROFILE not allowed in multicommand transactions.") {} }; class IndexInMulticommandTxException : public QueryException { public: using QueryException::QueryException; IndexInMulticommandTxException() : QueryException( "Index manipulation not allowed in multicommand transactions.") {} }; /** * An exception for an illegal operation that can not be detected * before the query starts executing over data. */ class QueryRuntimeException : public QueryException { public: using QueryException::QueryException; }; // This one is inherited from BasicException and will be treated as // TransientError, i. e. client will be encouraged to retry execution because it // could succeed if executed again. class HintedAbortError : public utils::BasicException { public: using utils::BasicException::BasicException; HintedAbortError() : utils::BasicException( "Transaction was asked to abort, most likely because it was " "executing longer than time specified by " "--query-execution-time-sec flag.") {} }; class ReconstructionException : public QueryException { public: ReconstructionException() : QueryException( "Record invalid after WITH clause. Most likely deleted by a " "preceeding DELETE.") {} }; class RemoveAttachedVertexException : public QueryRuntimeException { public: RemoveAttachedVertexException() : QueryRuntimeException( "Failed to remove node because of it's existing " "connections. Consider using DETACH DELETE.") {} }; class UserModificationInMulticommandTxException : public QueryException { public: UserModificationInMulticommandTxException() : QueryException( "Authentication clause not allowed in multicommand transactions.") { } }; class StreamClauseInMulticommandTxException : public QueryException { public: StreamClauseInMulticommandTxException() : QueryException( "Stream clause not allowed in multicommand transactions.") {} }; } // namespace query