/* Context-free grammar for Doctrine Query Language * * Document syntax: * - non-terminals begin with an upper case character * - terminals begin with a lower case character * - parentheses (...) are used for grouping * - square brackets [...] are used for defining an optional part, eg. zero or * one time time * - curly brackets {...} are used for repetion, eg. zero or more times * - double quotation marks "..." define a terminal string * - a vertical bar represents an alternative */ QueryLanguage = SelectStatement | UpdateStatement | DeleteStatement SelectStatement = [SelectClause] FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause] UpdateStatement = UpdateClause [WhereClause] [OrderByClause] [LimitClause] DeleteStatement = DeleteClause [WhereClause] [OrderByClause] [LimitClause] Subselect = SimpleSelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] [LimitClause] [OffsetClause] SelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression {"," SelectExpression} SimpleSelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression DeleteClause = "DELETE" "FROM" RangeVariableDeclaration WhereClause = "WHERE" ConditionalExpression FromClause = "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration} HavingClause = "HAVING" ConditionalExpression GroupByClause = "GROUP" "BY" GroupByItem {"," GroupByItem} OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem} LimitClause = "LIMIT" Expression ["OFFSET" Expression] UpdateClause = "UPDATE" RangeVariableDeclaration "SET" UpdateItem {"," UpdateItem} OrderByItem = Expression ["ASC" | "DESC"] GroupByItem = PathExpression UpdateItem = PathExpression "=" (Expression | "NULL") IdentificationVariableDeclaration = RangeVariableDeclaration {Join} RangeVariableDeclaration = PathExpression [["AS"] IdentificationVariable] Join = ["LEFT" | "INNER"] "JOIN" RangeVariableDeclaration [("ON" | "WITH") ConditionalExpression] [IndexBy] IndexBy = "INDEX" "BY" PathExpression ConditionalExpression = ConditionalTerm {"OR" ConditionalTerm} ConditionalTerm = ConditionalFactor {"AND" ConditionalFactor} ConditionalFactor = ["NOT"] ConditionalPrimary ConditionalPrimary = SimpleConditionalExpression | "(" ConditionalExpression ")" SimpleConditionalExpression = Expression (ComparisonExpression | BetweenExpression | LikeExpression | InExpression | NullComparisonExpression) | ExistsExpression Atom = string_literal | numeric_constant | input_parameter Expression = Term {("+" | "-") Term} Term = Factor {("*" | "/") Factor} Factor = [("+" | "-")] Primary Primary = PathExpression | Atom | "(" Expression ")" | Function | AggregateExpression SelectExpression = (PathExpressionEndingWithAsterisk | Expression | "(" Subselect ")" ) [["AS"] IdentificationVariable] PathExpression = identifier {"." identifier} PathExpressionEndingWithAsterisk = {identifier "."} "*" AggregateExpression = ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] Expression ")" | "COUNT" "(" ["DISTINCT"] (Expression | "*") ")" QuantifiedExpression = ("ALL" | "ANY" | "SOME") "(" Subselect ")" BetweenExpression = ["NOT"] "BETWEEN" Expression "AND" Expression ComparisonExpression = ComparisonOperator ( QuantifiedExpression | Expression | "(" Subselect ")" ) InExpression = ["NOT"] "IN" "(" (Atom {"," Atom} | Subselect) ")" LikeExpression = ["NOT"] "LIKE" Expression ["ESCAPE" string_literal] NullComparisonExpression = "IS" ["NOT"] "NULL" ExistsExpression = ["NOT"] "EXISTS" "(" Subselect ")" Function = identifier "(" [Expression {"," Expression}] ")"