Created
December 21, 2016 09:51
-
-
Save jamiecook/023a17b1b7d82e59c931711a86d1016d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Selekt | |
grammar SQL | |
rule sql_query | |
space? select_statement (space order_by_clause)? (space limit_clause)? space? | |
end | |
rule select_statement | |
select_clause | |
(space from_clause)? | |
(space where_clause)? | |
(space group_by_clause)? | |
(space having_clause)? | |
(space named_window_clause)? | |
(space set_operator space select_statement)* | |
end | |
rule select_clause | |
SELECT space (DISTINCT space)? projection (comma projection)* | |
end | |
rule from_clause | |
FROM space source_with_joins (comma source_with_joins)* | |
/ | |
FROM space source_with_joins (comma source_with_joins)* | |
end | |
rule source_with_joins | |
source (space source_join)* | |
/ | |
'(' source (space source_join)* ')' | |
end | |
rule source | |
((table <TableReference>) (alias <Alias>)? / subquery (alias <Alias>)) <Source> | |
end | |
rule source_join | |
regular_join_type space source space join_clause | |
end | |
rule regular_join_type | |
((INNER / LEFT / RIGHT / FULL space OUTER) space)? JOIN | |
end | |
rule join_clause | |
ON space boolean_expression | |
/ | |
USING space? '(' space? identifier (comma identifier)* ')' | |
end | |
rule comma | |
space? ',' space? | |
end | |
rule subquery | |
'(' space? select_statement space? ')' | |
end | |
rule table | |
schema_table / schemaless_table | |
end | |
rule schemaless_table | |
identifier { | |
def schema_name | |
nil | |
end | |
def table_name | |
elements[0].value | |
end | |
} | |
end | |
rule schema_table | |
schema '.' identifier { | |
def schema_name | |
schema.value | |
end | |
def table_name | |
elements.last.value | |
end | |
} | |
end | |
rule schema | |
identifier | |
end | |
rule column | |
table_column / identifier | |
end | |
rule table_column | |
identifier '.' identifier | |
end | |
rule projection | |
'*' / table '.' '*' / expression alias? | |
end | |
rule alias | |
space (AS space)? identifier | |
end | |
rule where_clause | |
WHERE space expression | |
end | |
rule group_by_clause | |
GROUP space BY space expression (comma expression)* | |
end | |
rule having_clause | |
HAVING space expression | |
end | |
rule order_by_clause | |
ORDER space BY space order_expression (comma order_expression)* | |
end | |
rule limit_clause | |
LIMIT space integer (space OFFSET space integer)? | |
end | |
rule order_expression | |
expression (space (ASC / DESC) (space NULLS space (FIRST / LAST))?)? | |
end | |
rule expression | |
boolean_expression | |
end | |
rule single_expression | |
(interval_expression / case_expression / function_call / column / literal / subquery / '(' space? expression space? ')') | |
(space? '::' space? type)? | |
end | |
rule case_expression | |
CASE space | |
(expression space)? | |
(WHEN space expression space THEN space expression space)+ | |
(ELSE space expression space)? | |
END | |
end | |
rule interval_expression | |
INTERVAL space expression | |
end | |
rule type | |
unquoted_identifier | |
end | |
rule function_call | |
( | |
COUNT '(' space? (DISTINCT space)? ('*' / expression) space? ')' | |
/ | |
unquoted_identifier '(' (space? expression (comma expression)*)? space? ')' | |
) | |
(space OVER (space? window_clause / space identifier))? | |
end | |
rule window_clause | |
'(' space? | |
(partition_by_clause space)? | |
order_by_clause | |
space? ')' | |
end | |
rule named_window_clause | |
WINDOW space identifier space AS space? window_clause | |
end | |
rule partition_by_clause | |
PARTITION space BY space expression (comma expression)* | |
end | |
rule arithmetic_expression | |
single_expression (space? arithmetic_operator space? single_expression)* | |
end | |
rule arithmetic_operator | |
'+' / '-' / '*' / '/' / '%' / '||' | |
end | |
rule comparison_expression | |
EXISTS space? subquery | |
/ | |
arithmetic_expression space IS (space NOT)? space boolean | |
/ | |
arithmetic_expression space (NOT space)? IN space list_of_values | |
/ | |
arithmetic_expression (space? comparison_operator space? arithmetic_expression)? | |
end | |
rule list_of_values | |
subquery | |
/ | |
'(' space? expression (comma expression)* space? ')' | |
end | |
rule comparison_operator | |
'<=' / '>=' / '<>' / '>' / '<' / '!=' / '=' / LIKE / ILIKE | |
end | |
rule negatable_expression | |
(NOT space)? comparison_expression | |
end | |
rule boolean_expression | |
negatable_expression (space boolean_operator space negatable_expression)* | |
end | |
rule boolean_operator | |
AND / OR | |
end | |
rule set_operator | |
UNION (space ALL)? | |
end | |
rule space | |
[ \t\r\n]+ (comment space?)? | |
end | |
rule comment | |
'--' [^\r\n]* | |
end | |
rule identifier | |
quoted_identifier / single_quoted_identifier / unquoted_identifier !{|seq| seq[0].reserved? } { | |
def value | |
elements.first.value | |
end | |
} | |
end | |
rule unquoted_identifier | |
[A-Za-z] [_A-Za-z0-9]* | |
{ | |
def value | |
text_value | |
end | |
def reserved? | |
Selekt::RESERVED_SQL_KEYWORDS.include?(text_value.downcase) | |
end | |
} | |
end | |
rule quoted_identifier | |
'"' body:('""' / [^"])* '"' { | |
def value | |
body.text_value.gsub('""', '"') | |
end | |
} | |
end | |
rule single_quoted_identifier | |
"'" body:("''" / [^'])* "'" { | |
def value | |
body.text_value.gsub("''", "'") | |
end | |
} | |
end | |
rule literal | |
string / float / integer / boolean | |
end | |
rule string | |
"'" ("''" / [^'])* "'" | |
end | |
rule boolean | |
TRUE / FALSE / NULL | |
end | |
rule integer | |
"-"? [0-9]+ | |
end | |
rule float | |
"-"? [0-9]* '.' [0-9]+ | |
end | |
rule SELECT | |
[Ss] [Ee] [Ll] [Ee] [Cc] [Tt] | |
end | |
rule DISTINCT | |
[Dd] [Ii] [Ss] [Tt] [Ii] [Nn] [Cc] [Tt] | |
end | |
rule FROM | |
[Ff] [Rr] [Oo] [Mm] | |
end | |
rule HAVING | |
[Hh] [Aa] [Vv] [Ii] [Nn] [Gg] | |
end | |
rule ORDER | |
[Oo] [Rr] [Dd] [Ee] [Rr] | |
end | |
rule ASC | |
[Aa] [Ss] [Cc] | |
end | |
rule DESC | |
[Dd] [Ee] [Ss] [Cc] | |
end | |
rule NULLS | |
[Nn] [Uu] [Ll] [Ll] [Ss] | |
end | |
rule FIRST | |
[Ff] [Ii] [Rr] [Ss] [Tt] | |
end | |
rule LAST | |
[Ll] [Aa] [Ss] [Tt] | |
end | |
rule AS | |
[Aa] [Ss] | |
end | |
rule JOIN | |
[Jj] [Oo] [Ii] [Nn] | |
end | |
rule FULL | |
[Ff] [Uu] [Ll] [Ll] | |
end | |
rule OUTER | |
[Oo] [Uu] [Tt] [Ee] [Rr] | |
end | |
rule INNER | |
[Ii] [Nn] [Nn] [Ee] [Rr] | |
end | |
rule LEFT | |
[Ll] [Ee] [Ff] [Tt] | |
end | |
rule RIGHT | |
[Rr] [Ii] [Gg] [Hh] [Tt] | |
end | |
rule ON | |
[Oo] [Nn] | |
end | |
rule USING | |
[Uu] [Ss] [Ii] [Nn] [Gg] | |
end | |
rule WHERE | |
[Ww] [Hh] [Ee] [Rr] [Ee] | |
end | |
rule GROUP | |
[Gg] [Rr] [Oo] [Uu] [Pp] | |
end | |
rule BY | |
[Bb] [Yy] | |
end | |
rule LIMIT | |
[Ll] [Ii] [Mm] [Ii] [Tt] | |
end | |
rule OFFSET | |
[Oo] [Ff] [Ff] [Ss] [Ee] [Tt] | |
end | |
rule UNION | |
[Uu] [Nn] [Ii] [Oo] [Nn] | |
end | |
rule ALL | |
[Aa] [Ll] [Ll] | |
end | |
rule COUNT | |
[Cc] [Oo] [Uu] [Nn] [Tt] | |
end | |
rule OVER | |
[Oo] [Vv] [Ee] [Rr] | |
end | |
rule PARTITION | |
[Pp] [Aa] [Rr] [Tt] [Ii] [Tt] [Ii] [Oo] [Nn] | |
end | |
rule WINDOW | |
[Ww] [Ii] [Nn] [Dd] [Oo] [Ww] | |
end | |
rule CASE | |
[Cc] [Aa] [Ss] [Ee] | |
end | |
rule WHEN | |
[Ww] [Hh] [Ee] [Nn] | |
end | |
rule THEN | |
[Tt] [Hh] [Ee] [Nn] | |
end | |
rule ELSE | |
[Ee] [Ll] [Ss] [Ee] | |
end | |
rule END | |
[Ee] [Nn] [Dd] | |
end | |
rule INTERVAL | |
[Ii] [Nn] [Tt] [Ee] [Rr] [Vv] [Aa] [Ll] | |
end | |
rule IS | |
[Ii] [Ss] | |
end | |
rule IN | |
[Ii] [Nn] | |
end | |
rule EXISTS | |
[Ee] [Xx] [Ii] [Ss] [Tt] [Ss] | |
end | |
rule NOT | |
[Nn] [Oo] [Tt] | |
end | |
rule AND | |
[Aa] [Nn] [Dd] | |
end | |
rule OR | |
[Oo] [Rr] | |
end | |
rule TRUE | |
[Tt] [Rr] [Uu] [Ee] | |
end | |
rule FALSE | |
[Ff] [Aa] [Ll] [Ss] [Ee] | |
end | |
rule NULL | |
[Nn] [Uu] [Ll] [Ll] | |
end | |
rule LIKE | |
[Ll] [Ii] [Kk] [Ee] | |
end | |
rule ILIKE | |
[Ii] [Ll] [Ii] [Kk] [Ee] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment