WHITESPACE = _{ " "|"\t"|"\r"|"\n"|"\x0b"|"\x0c" }
COMMENT = _{
"--" ~ (!NEWLINE ~ ANY)* ~ NEWLINE |
"/*" ~ (!"*/" ~ ANY)* ~ "*/"
}
back_quoted = @{ "`" ~ (!"`" ~ ANY | "``")* ~ "`" }
single_quoted = @{ "'" ~ (!"'" ~ ANY | "''")* ~ "'" }
double_quoted = @{ "\"" ~ (!"\"" ~ ANY | "\"\"")* ~ "\"" }
ident = @{
back_quoted |
double_quoted |
"[" ~ (!"]" ~ ANY)* ~ "]" |
(ASCII_ALPHA|"_") ~ (ASCII_ALPHANUMERIC|"_")*
}
number = @{
^"0x" ~ ASCII_HEX_DIGIT+ |
(ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT*)? | "." ~ ASCII_DIGIT+) ~ (^"e" ~ ("+"|"-")? ~ ASCII_DIGIT+)?
}
b = _{ !(ASCII_ALPHANUMERIC|"_") }
kw_create = @{ ^"create" ~ b }
kw_table = @{ ^"table" ~ b }
kw_or = @{ ^"or" ~ b }
kw_and = @{ ^"and" ~ b }
kw_not = @{ ^"not" ~ b }
kw_is = @{ ^"is" ~ b }
kw_rownum = @{ ^"rownum" ~ b }
kw_null = @{ ^"null" ~ b }
kw_true = @{ ^"true" ~ b }
kw_false = @{ ^"false" ~ b }
kw_case = @{ ^"case" ~ b }
kw_when = @{ ^"when" ~ b }
kw_then = @{ ^"then" ~ b }
kw_else = @{ ^"else" ~ b }
kw_end = @{ ^"end" ~ b }
kw_timestamp = @{ ^"timestamp" ~ b }
kw_interval = @{ ^"interval" ~ b }
kw_week = @{ ^"week" ~ b }
kw_day = @{ ^"day" ~ b }
kw_hour = @{ ^"hour" ~ b }
kw_minute = @{ ^"minute" ~ b }
kw_second = @{ ^"second" ~ b }
kw_millisecond = @{ ^"millisecond" ~ b }
kw_microsecond = @{ ^"microsecond" ~ b }
kw_with = @{ ^"with" ~ b }
kw_time = @{ ^"time" ~ b }
kw_zone = @{ ^"zone" ~ b }
op_le = @{ "<=" }
op_lt = @{ "<" }
op_ge = @{ ">=" }
op_gt = @{ ">" }
op_eq = @{ "=" }
op_ne = @{ "<>" }
op_add = @{ "+" }
op_sub = @{ "-" }
op_concat = @{ "||" }
op_mul = @{ "*" }
op_float_div = @{ "/" }
balanced = _{
"(" ~ balanced* ~ ")" |
"[" ~ balanced* ~ "]" |
"{" ~ balanced* ~ "}" |
back_quoted |
single_quoted |
double_quoted |
!("("|"["|"{"|"`"|"'"|"\""|")"|"]"|"}") ~ ANY
}
qname = {
ident ~ ("." ~ ident){0,2}
}
column_definition = {
(!"{{" ~ balanced)+
}
table_options = {
")" ~ ANY*
}
create_table_content = _{
"(" ~ (column_definition | "{{" ~ expr ~ "}}")* ~ table_options
}
create_table = _{
SOI ~ kw_create ~ kw_table ~ qname ~ create_table_content
}
expr = {
("@" ~ ident ~ ":=")* ~ expr_or
}
expr_or = {
expr_and ~ (kw_or ~ expr_and)*
}
expr_and = {
expr_not ~ (kw_and ~ expr_not)*
}
expr_not = {
kw_not* ~ expr_cmp
}
is_not = { kw_is ~ kw_not }
expr_cmp = {
expr_add ~ ((is_not | kw_is | op_le | op_ge | op_ne | op_lt | op_gt | op_eq) ~ expr_add)?
}
expr_add = {
expr_mul ~ ((op_add | op_sub | op_concat) ~ expr_mul)*
}
expr_mul = {
expr_primary ~ ((op_mul | op_float_div) ~ expr_primary)*
}
expr_primary = {
kw_rownum | kw_null | kw_true | kw_false |
expr_group |
single_quoted | // string
number |
expr_unary |
expr_case_value_when |
expr_timestamp |
expr_interval |
expr_get_variable |
expr_function
}
expr_group = {
"(" ~ expr ~ ")"
}
expr_unary = {
(op_add | op_sub)+ ~ expr_primary
}
expr_case_value_when = {
kw_case ~ case_value_when_value ~
(kw_when ~ case_value_when_pattern ~ kw_then ~ case_value_when_result)+ ~
(kw_else ~ case_value_when_else)? ~
kw_end
}
case_value_when_value = { expr }
case_value_when_pattern = { expr }
case_value_when_result = { expr }
case_value_when_else = { expr }
expr_timestamp = {
kw_timestamp ~ (kw_with ~ kw_time ~ kw_zone)? ~ expr_primary
}
expr_interval = {
kw_interval ~ expr ~ (kw_week | kw_day | kw_hour | kw_minute | kw_second | kw_millisecond | kw_microsecond)
}
expr_get_variable = {
"@" ~ ident ~ !":="
}
expr_function = {
qname ~ "(" ~ (expr ~ ("," ~ expr)*)? ~ ")"
}