$Id$

	/**
	 * @see http://www.w3.org/Notation.html
	 *
	 * Specific definitions:
	 * RULE1 | RULE2	- alternation: returns first-matched rule
	 * RULE1 || RULE2	- greedy alternation: returns best-matched rule of rules list 
	**/

	<select> ::=
		[ <properties> ]
		"from" <identifier>
		[ "where" <where> ]
		[ "group by" <group_by> ]
		[ "order by" <order_by> ]
		[ "having" <having> ]
		[ "limit" <limit> ]
		[ "offset" <offset> ]

	<properties> ::= <property> * ( "," <property> )

	<where> ::= <logical_expression>

	<group_by> ::= <mixed_operand> * ( "," <mixed_operand> )

	<order_by> ::=
		<mixed_operand> [ "asc" | "desc" ]
		* ( "," <mixed_operand> [ "asc" | "desc" ] )

	<having> ::= <logical_expression>

	<limit> ::= <number> | <placeholder> 

	<offset> ::= <limit>

	<property> ::=
		(
			( ( "sum" | "avg" | "min" | "max" ) "(" <mixed_operand> ")" )
			| ( "count" "(" [ "distinct" ] <mixed_operand> ")" )
			| ( [ "distinct" ] <mixed_operand> )
		)
		[ "as" <identifier> ]

	<mixed_operand> ::= <arithmetic_expression> || <logical_expression>

	<logical_expression> ::=
		<logical_and_expression> [ "or" <logical_expression> ]

	<logical_and_expression> ::=
		<logical_term> [ "and" <logical_and_expression> ]
	
	<logical_term> ::=
		(
			<logical_operand>
			(
				( <comparison_operator> <logical_operand> )
				| ( "is" ( ( [ "not" ] <null> ) | <boolean> ) )
				| ( [ "not" ] "in" "(" <constant> * ( "," <constant> ) ")" )
				| ( [ "not" ] ( "like" | "ilike" | "similar to" ) <pattern> )
				| ( "between" <logical_operand> "and" <logical_operand> )
			)
		)
		| <logical_unary_operand>
		| ( "(" <logical_expression> ")" )
		| ( "not" <logical_term> )

	<logical_operand> ::= <arithmetic_expression> | <boolean> | <string> | <null>

	<logical_unary_operand> ::= <identifier> | <placeholder> | <boolean> | <null>

	<arithmetic_expression> ::=
		<arithmetic_mul_expression> [ ( "+" | "-" ) <arithmetic_expression> ]

	<arithmetic_mul_expression> ::=
		[ "-" ] <arithmetic_operand> [ ( "*" | "/" ) <arithmetic_mul_expression> ]

	<arithmetic_operand> ::=
		<identifier> | <number> | <placeholder> | ( "(" <arithmetic_expression> ")" )

	<identifier> ::= <name> | <aggregate_function>

	<constant> ::= <string> | ( [ "-" ] <number> ) | <placeholder> | <boolean> | <null>

	<pattern> ::= <string> | <placeholder>

	<aggregate_function> ::= "sum" | "avg" | "min" | "max" | "count"

	<comparison_operator> ::= "=" | "<" | ">" | "<>" | "!=" | "<=" | ">="

	<null> ::= "null"

	<boolean> ::= "true" | "false"

	<name> ::= ( <letter> | "_" ) * [ <letter> | <digit> | "_" ] * [ "." <name> ]

	<string> ::=
		( "\"" * <character> "\"" )
		| ( "'" * <character> "'" )
		| ( "`" * <character> "`" )

	<number> ::= [ <digit> ] [ "." ] * <digit> [ "e" [ "+" | "-" ] * <digit> ]

	<placeholder> ::= "$" 1 * <digit>


Examples:
	from User where id = $1

	count(id) as count, count(distinct Name) as distinctCount from User

	(id + -$1) / 2 as idExpression, distinct id from User
	where (Name not ilike 'user%') and id <= 10 and created between $2 and $3
	order by id desc, Name asc
	limit 10 offset $2

	from User having $1 > 0 group by id