Docs / EventSourcingDB / Errors / query-too-deep

query-too-deep

An EventQL query nests more than 256 levels, or holds a chain of more than 10,000 operands.

  • Routes: run-eventql-query, write-events, and format-eventql-query
  • Description: query is too deep: it may nest at most 256 levels for a query that nests too deeply, and query is too deep: a chain of operators may hold at most 10000 operands for a chain that is too long. For the query of a precondition, the text starts with /preconditions/<index>: , with the place of the precondition in its list, counting from 0.
  • Details: When running or formatting a query, none; details is an empty object. For a precondition, precondition, the place of the precondition in its list, counting from 0.

Why It Happens#

The parser of EventQL descends a step deeper for every level that a query nests, and the evaluator for every operand of a chain of operators, so a query that goes too deep would take more of the stack than the server has. EventSourcingDB therefore counts the levels and the chains of a query before it parses it, and refuses one beyond either bound, as the syntax of EventQL describes:

  • A level opens with every parenthesis, bracket, and brace, whether around an expression, the arguments of a function, an array, an index, a map, or a subquery, and with every prefix operator, NOT and -, in front of an operand.
  • A chain is what binary operators join, whatever their precedence, as in 1 + 2 * 3, together with every field, index, and cast that follows an operand, each of which counts as one operand more. A comma, a colon, and the keyword of a clause end a chain, and a chain within brackets counts towards the chain around them.

A query written by hand rarely comes near either bound. A typical cause is a query that a program builds, for example by joining a comparison for each of thousands of values with OR.

Since a query is counted before it is parsed, the bounds hold for one that does not parse as well: a query with more than 256 parentheses that are never closed is reported this way rather than as query-malformed. For a precondition, the query is counted only when the write evaluates it, after the preconditions on subjects. So if one of those does not hold, the write reports precondition-violated first.

The route format-eventql-query belongs to the management UI, which formats the queries of its EventQL editor through it, and answers with a single envelope, the error itself, rather than a stream, as for query-malformed.

How to Fix It#

Flatten the query: leave out parentheses that change nothing, and compare a field with many values at once through an array and CONTAINS, as in WHERE ["/books/23", "/books/42"] CONTAINS e.subject, rather than joining a comparison for each value with OR. The elements of an array are separated by commas, so they form no chain. Sending the same query again fails the same way, since the error depends on the query alone.

Example#

To run the query FROM e IN events PROJECT INTO 1 + 1 + … + 1, with 10,001 operands, as a program might build it, EventSourcingDB answers with this error, as a line of the stream, and then ends the stream with its end item:

{
  "type": "error",
  "data": {
    "code": "https://docs.eventsourcingdb.io/errors/query-too-deep",
    "description": "query is too deep: a chain of operators may hold at most 10000 operands",
    "details": {}
  }
}