| 1 |
/* Context-free grammar for Doctrine Query Language |
|---|
| 2 |
* |
|---|
| 3 |
* Document syntax: |
|---|
| 4 |
* - non-terminals begin with an upper case character |
|---|
| 5 |
* - terminals begin with a lower case character |
|---|
| 6 |
* - parentheses (...) are used for grouping |
|---|
| 7 |
* - square brackets [...] are used for defining an optional part, eg. zero or |
|---|
| 8 |
* one time time |
|---|
| 9 |
* - curly brackets {...} are used for repetion, eg. zero or more times |
|---|
| 10 |
* - double quotation marks "..." define a terminal string |
|---|
| 11 |
* - a vertical bar | represents an alternative |
|---|
| 12 |
* |
|---|
| 13 |
* At a first glance we'll support SQL-99 based queries |
|---|
| 14 |
* Initially Select and Sub-select DQL will not support LIMIT and OFFSET (due to limit-subquery algorithm) |
|---|
| 15 |
*/ |
|---|
| 16 |
|
|---|
| 17 |
QueryLanguage = SelectStatement | UpdateStatement | DeleteStatement |
|---|
| 18 |
|
|---|
| 19 |
SelectStatement = SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] |
|---|
| 20 |
UpdateStatement = UpdateClause [WhereClause] |
|---|
| 21 |
DeleteStatement = DeleteClause [WhereClause] |
|---|
| 22 |
|
|---|
| 23 |
Subselect = SimpleSelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] |
|---|
| 24 |
SelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression {"," SelectExpression} |
|---|
| 25 |
SimpleSelectClause = "SELECT" ["ALL" | "DISTINCT"] SelectExpression |
|---|
| 26 |
DeleteClause = "DELETE" ["FROM"] VariableDeclaration |
|---|
| 27 |
WhereClause = "WHERE" ConditionalExpression |
|---|
| 28 |
FromClause = "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration} |
|---|
| 29 |
HavingClause = "HAVING" ConditionalExpression |
|---|
| 30 |
GroupByClause = "GROUP" "BY" GroupByItem {"," GroupByItem} |
|---|
| 31 |
OrderByClause = "ORDER" "BY" OrderByItem {"," OrderByItem} |
|---|
| 32 |
LimitClause = "LIMIT" integer |
|---|
| 33 |
OffsetClause = "OFFSET" integer |
|---|
| 34 |
UpdateClause = "UPDATE" VariableDeclaration "SET" UpdateItem {"," UpdateItem} |
|---|
| 35 |
|
|---|
| 36 |
OrderByItem = Expression ["ASC" | "DESC"] |
|---|
| 37 |
GroupByItem = PathExpression |
|---|
| 38 |
UpdateItem = PathExpression "=" (Expression | "NULL") |
|---|
| 39 |
|
|---|
| 40 |
IdentificationVariableDeclaration = RangeVariableDeclaration [IndexBy] {Join [IndexBy]} |
|---|
| 41 |
RangeVariableDeclaration = identifier {"." identifier} [["AS"] IdentificationVariable] |
|---|
| 42 |
VariableDeclaration = identifier [["AS"] IdentificationVariable] |
|---|
| 43 |
IdentificationVariable = identifier |
|---|
| 44 |
|
|---|
| 45 |
Join = ["LEFT" | "INNER"] "JOIN" RangeVariableDeclaration [("ON" | "WITH") ConditionalExpression] |
|---|
| 46 |
IndexBy = "INDEX" "BY" identifier |
|---|
| 47 |
|
|---|
| 48 |
ConditionalExpression = ConditionalTerm {"OR" ConditionalTerm} |
|---|
| 49 |
ConditionalTerm = ConditionalFactor {"AND" ConditionalFactor} |
|---|
| 50 |
ConditionalFactor = ["NOT"] ConditionalPrimary |
|---|
| 51 |
ConditionalPrimary = SimpleConditionalExpression | "(" ConditionalExpression ")" |
|---|
| 52 |
SimpleConditionalExpression |
|---|
| 53 |
= Expression (ComparisonExpression | BetweenExpression | LikeExpression |
|---|
| 54 |
| InExpression | NullComparisonExpression) | ExistsExpression |
|---|
| 55 |
|
|---|
| 56 |
Atom = string | integer | float | boolean | input_parameter |
|---|
| 57 |
|
|---|
| 58 |
Expression = Term {("+" | "-") Term} |
|---|
| 59 |
Term = Factor {("*" | "/") Factor} |
|---|
| 60 |
Factor = [("+" | "-")] Primary |
|---|
| 61 |
Primary = PathExpression | Atom | "(" Expression ")" | Function | AggregateExpression |
|---|
| 62 |
|
|---|
| 63 |
SelectExpression = (PathExpressionEndingWithAsterisk | Expression | "(" Subselect ")" ) [["AS"] FieldIdentificationVariable] |
|---|
| 64 |
PathExpression = identifier {"." identifier} |
|---|
| 65 |
PathExpressionEndingWithAsterisk = {identifier "."} "*" |
|---|
| 66 |
FieldIdentificationVariable = identifier |
|---|
| 67 |
|
|---|
| 68 |
AggregateExpression = ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] Expression ")" |
|---|
| 69 |
| "COUNT" "(" ["DISTINCT"] (Expression | "*") ")" |
|---|
| 70 |
|
|---|
| 71 |
QuantifiedExpression = ("ALL" | "ANY" | "SOME") "(" Subselect ")" |
|---|
| 72 |
BetweenExpression = ["NOT"] "BETWEEN" Expression "AND" Expression |
|---|
| 73 |
ComparisonExpression = ComparisonOperator ( QuantifiedExpression | Expression | "(" Subselect ")" ) |
|---|
| 74 |
InExpression = ["NOT"] "IN" "(" (Atom {"," Atom} | Subselect) ")" |
|---|
| 75 |
LikeExpression = ["NOT"] "LIKE" Expression ["ESCAPE" string] |
|---|
| 76 |
NullComparisonExpression = "IS" ["NOT"] "NULL" |
|---|
| 77 |
ExistsExpression = "EXISTS" "(" Subselect ")" |
|---|
| 78 |
|
|---|
| 79 |
ComparisonOperator = "=" | "<" | "<=" | "<>" | ">" | ">=" | "!=" |
|---|
| 80 |
|
|---|
| 81 |
Function = identifier "(" [Expression {"," Expression}] ")" |
|---|