module SQLiterate
grammar Expression include Space include Identifier include Keywords include Literals include Operator rule scalar_expression disjunction_expression end rule disjunction_expression e:conjunction_expression r:( space or_kw space e:conjunction_expression )* <Node::DisjunctionExpression> end rule conjunction_expression e:negation_expression r:( space and_kw space e:negation_expression )* <Node::ConjunctionExpression> end rule negation_expression not_kw space e:equality_expression <Node::NegationExpression> / equality_expression end rule equality_expression e:between_expression r:( space '=' space e:between_expression )* <Node::EqualityExpression> end rule between_expression e:set_predicate_expression r:( space ( not_kw space )? between_kw space ( symmetric_kw space )? l:set_predicate_expression space and_kw space r:set_predicate_expression )* <Node::BetweenExpression> end rule set_predicate_expression exists_expression / e:test_expression space set_predicate_operator space set_constructor <Node::SetPredicateExpression> / test_expression end rule set_constructor '(' space e:query_expression space ')' / '(' space e:expressions_list space ')' <Node::SetConstructor> end rule exists_expression exists_kw space '(' space query_expression space ')' <Node::ExistsExpression> end rule test_expression l:gen_expression space binary_test_operator space r:gen_expression <Node::TestExpression::Binary> / e:gen_expression space unary_test_operator <Node::TestExpression::Unary> / gen_expression end rule gen_expression h:( gen_operator space )* gen_value r:( o:( space gen_operator )+ space gen_value )* t:( space gen_operator )* <Node::GenExpression> end rule gen_value literal_value <Node::GenValue::Literal> / function_call / field_selection r:( space '[' space range_expression space ']' )+ <Node::GenValue::Subscript> / field_selection / case_expression end rule case_expression case_kw required_space case_when_section r:( space case_when_section )* space case_else_section space end_kw <Node::CaseExpression> end rule case_when_section when_kw space w:scalar_expression space then_kw space t:scalar_expression <Node::CaseWhenSection> end rule case_else_section ( else_kw space scalar_expression / space ) <Node::CaseElseSection> end rule function_call type_cast / function_name space '(' space function_params space ')' <Node::FunctionCall> end rule type_cast cast_kw space '(' space scalar_expression space as_kw space type_name space ')' <Node::TypeCast> end rule function_name qualified_name / identifier end rule function_params aggregate_expression / expressions_list / void_expression end rule void_expression space <Node::VoidExpression> end rule aggregate_expression all_columns <Node::AllColumns> / (aggregate_specifier space)? expressions_list space order_by_clause <Node::AggregateExpression> end rule aggregate_specifier all_kw / distinct_kw end rule ordering_specifier ( asc_kw / desc_kw )? ( space nulls_kw required_space ( first_kw / last_kw ) )? end rule order_by_clause ( order_by_kw space sort_expressions_list / space ) <Node::OrderByClause> end rule sort_expressions_list sort_expression r:( space ',' space sort_expression)* <Node::SortExpressionsList> end rule sort_expression scalar_expression space ordering_specifier <Node::SortExpression> end rule expressions_list scalar_expression r:( space ',' space scalar_expression)* <Node::ExpressionsList> end rule range_expression b:scalar_expression space ':' space e:scalar_expression <Node::RangeExpression> / scalar_expression end rule field_selection row_value space '.' space field_identifier <Node::FieldSelection> / row_value end rule field_identifier all_fields / identifier end rule row_value '(' space query_expression space ')' <Node::RowValue::Query> / '(' space scalar_expression space ')' <Node::RowValue::Expression> / positional_param <Node::RowValue::Positional> / identifier <Node::RowValue::Identifier> end rule query_expression query_value r:( space set_operation space query_value )* <Node::QueryExpression> end rule set_operation ( union_kw / intersect_kw / except_kw ) ( required_space all_kw )? end rule query_value '(' space query_expression space ')' <Node::QueryValue::Expression> / select_query <Node::QueryValue::Select> end rule select_query select_kw space distinct_clause space select_list space table_expression space order_by_clause space limit_clause space offset_clause <Node::SelectQuery> end rule distinct_clause aggregate_specifier ( required_space on_kw space '(' space expressions_list space ')' )? / space end rule select_list all_columns / named_expressions_list end rule named_expressions_list named_expression r:( space ',' space named_expression)* <Node::NamedExpressionsList> end rule named_expression scalar_expression ( space (as_kw space)? column_name )? <Node::NamedExpression> end rule table_reference (table_spec space (as_kw space)? table_name space column_list? / qualified_name) <Node::TableReference> end rule all_columns '*' <Node::AllColumns> end rule table_expression from_clause space where_clause space group_by_clause <Node::TableExpression> end rule from_clause ( from_kw space table_references / space ) <Node::FromClause> end rule where_clause ( where_kw space scalar_expression / space ) <Node::WhereClause> end rule group_by_clause ( group_by_kw space expressions_list space having_clause / space ) <Node::GroupByClause> end rule having_clause ( having_kw space scalar_expression / space ) <Node::HavingClause> end rule table_references table_joins r:( space ',' space table_joins )* <Node::TableReferences> end rule table_joins table_reference r:( space joined_table )* <Node::TableJoins> end rule table_reference (table_spec space (as_kw space)? table_name space column_list? / qualified_name) <Node::TableReference> end rule table_spec '(' space query_expression space ')' <Node::TableSpec::Query> / '(' space table_joins space ')' <Node::TableSpec::Joins> / qualified_name <Node::TableSpec::Table> end rule joined_table natural_join / predicate_join / columns_join end rule natural_join natural_kw space join_type space join_kw space table_reference <Node::Join> end rule predicate_join join_type space join_kw space table_reference space on_kw space scalar_expression <Node::Join> end rule columns_join join_type space join_kw space table_reference space using_kw space column_list <Node::Join> end rule join_type (left_kw / right_kw / full_kw) (space outer_kw)? / inner_kw / space end rule column_list '(' column_name r:( space ',' space column_name)* ')' end rule limit_clause ( limit_kw required_space all_kw / limit_kw space scalar_expression / space ) <Node::LimitClause> end rule offset_clause ( offset_kw space scalar_expression / space ) <Node::OffsetClause> end end
end