-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsql-with-match.gram
124 lines (98 loc) · 4.16 KB
/
sql-with-match.gram
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
Statements <- (SingleStatement (';' SingleStatement )* ';'*)
SingleStatement <- SelectStatement
SelectStatement <- SimpleSelect (SetopClause SimpleSelect)*
SetopClause <- ('UNION'i / 'EXCEPT'i / 'INTERSECT'i) 'ALL'i?
SimpleSelect <- WithClause? SelectClause FromClause? WhereClause? GroupByClause? HavingClause? OrderByClause? LimitClause?
WithStatement <- Identifier 'AS'i SubqueryReference
WithClause <- 'WITH'i List(WithStatement)
SelectClause <- 'SELECT'i ('*' / List(AliasedExpression))
ColumnAliases <- Parens(List(Identifier))
Name <- (Identifier? ':' Identifier) / Identifier
Edge <- ('-' / '<-') '[' Name ']' ('->' / '-')
Pattern <- Parens(Name WhereClause?) Edge Parens(Name WhereClause?)
PropertyGraphReference <- 'GRAPH_TABLE'i '(' Identifier ','
'MATCH'i List(Pattern) 'COLUMNS'i Parens(List(ColumnReference)) ')' Identifier?
TableReference <-
PropertyGraphReference /
(SubqueryReference 'AS'i? Identifier ColumnAliases?) /
(Identifier ('AS'i? Identifier)?)
ExplicitJoin <- ('LEFT'i / 'FULL'i)? 'OUTER'i? 'JOIN'i TableReference 'ON'i Expression
FromClause <- 'FROM'i TableReference ((',' TableReference) / ExplicitJoin)*
WhereClause <- 'WHERE'i Expression
GroupByClause <- 'GROUP'i 'BY'i List(Expression)
HavingClause <- 'HAVING'i Expression
SubqueryReference <- Parens(SelectStatement)
OrderByExpression <- Expression ('DESC'i / 'ASC'i)? ('NULLS'i 'FIRST'i / 'LAST'i)?
OrderByClause <- 'ORDER'i 'BY'i List(OrderByExpression)
LimitClause <- 'LIMIT'i NumberLiteral
ReservedKeyword <-
'SELECT'i /
'FROM'i /
'WHERE'i /
'GROUP'i 'BY'i /
'HAVING'i /
'UNION'i /
'ORDER'i 'BY'i /
'WHEN'i /
'JOIN'i /
'ON'i /
'INTERSECT'i # TODO expand on this
PlainIdentifier <- !ReservedKeyword <[a-z_]i[a-z0-9_]i*> # unqoted identifier can't be top-level keyword
QuotedIdentifier <- '"' [^"]* '"'
Identifier <- QuotedIdentifier / PlainIdentifier
NumberLiteral <- < [+-]?[0-9]*([.][0-9]*)? >
StringLiteral <- '\'' [^\']* '\''
TypeSpecifier <- Identifier (Parens(List(NumberLiteral)))?
ColumnReference <- (Identifier '.')?Identifier
FunctionExpression <- Identifier Parens(List(Expression))
ParenthesisExpression <- Parens(Expression)
LiteralExpression <- StringLiteral / NumberLiteral
CastExpression <- 'CAST'i Parens(Expression 'AS'i TypeSpecifier)
ExtractExpression <- 'EXTRACT'i Parens(ColumnReference 'FROM'i Expression)
CountStarExpression <- 'COUNT'i Parens('*')
SubqueryExpression <- 'NOT'i? 'EXISTS'i? SubqueryReference
CaseExpression <- 'CASE'i ColumnReference? 'WHEN'i Expression 'THEN'i Expression ('ELSE'i Expression)? 'END'i # TODO strict
DateExpression <- 'DATE'i Expression
DistinctExpression <- 'DISTINCT'i Expression
SubstringExpression <- 'SUBSTRING'i Parens(Expression 'FROM'i NumberLiteral 'FOR'i NumberLiteral)
LiteralListExpression <- Parens(List(Expression))
FrameClause <- 'ROWS'i 'BETWEEN'i (('UNBOUNDED'i 'PRECEDING'i)) 'AND' (('CURRENT'i 'ROW'i))
WindowExpression <- Parens(('PARTITION'i 'BY'i List(Expression))? OrderByClause? FrameClause?)
IsNullExpression <- ColumnReference 'IS'i 'NOT'i? 'NULL'i # TODO
SingleExpression <-
SubqueryExpression /
LiteralListExpression /
ParenthesisExpression /
DateExpression /
DistinctExpression /
SubstringExpression /
IsNullExpression /
CaseExpression /
CountStarExpression /
CastExpression /
ExtractExpression /
WindowExpression /
FunctionExpression /
ColumnReference /
LiteralExpression
ArithmeticOperator <- '+' / '-' / '*' / '/'
LikeOperator <- 'NOT'i? 'LIKE'i
InOperator <- 'NOT'i? 'IN'i !'T'i # special handling to not match INTERSECT
BooleanOperator <- ('OR'i !'D'i) / 'AND'i # special handling to not match ORDER BY
ComparisionOperator <- '=' / '<=' / '>=' / '<' / '>'
WindowOperator <- 'OVER'i
BetweenOperator <- 'BETWEEN'i
Operator <-
ArithmeticOperator /
ComparisionOperator /
BooleanOperator /
LikeOperator /
InOperator /
WindowOperator /
BetweenOperator
Expression <- SingleExpression (Operator SingleExpression)*
AliasedExpression <- Expression ('AS'i? Identifier)?
# internal definitions
%whitespace <- [ \t\n\r]*
List(D) <- D (',' D)*
Parens(D) <- '(' D ')'