SELECT Syntax
select::= select-term [ set-op [ ALL ] ] [ order-by-clause | limit-clause | offset-clause ]

select-term::= subselect | "(" select ")"

subselect::= select-from | from-select

select-from::= select-clause [ from-clause | let-clause | where-clause | group-by-clause ]

from-select::= from-clause [ let-clause ] [ where-clause ] [ group-by-clause ] select-clause

SELECT Clause
select-clause::= SELECT [ ALL | DISTINCT ] ( result-expr [ , result-expr ]* | ( RAW | ELEMENT | VALUE ) expr [ [AS] alias ] )

FROM Clause
from-clause::= FROM from-term

from-term::= from-keyspace [ [ AS ] alias ] [ use-clause ] | "(" select ")" [ AS ] alias | expr [ [ AS ] alias] | from-term ( join-clause | nest-clause | unnest-clause )

from-keyspace::= [ namespace : ] keyspace

JOIN Clause
join-clause::= [ join-type ] JOIN from-keyspace [ [ AS ] alias ] join-predicate

join-type::= INNER | LEFT [ OUTER ]

join-predicate::= lookup-join-predicate | index-join-predicate

lookup-join-predicate::= ON [ PRIMARY ] KEYS expr

index-join-predicate::= ON [ PRIMARY ] KEY expr FOR alias

NEST Clause
nest-clause::= [ join-type ] NEST from-keyspace [ [ AS ] alias ] join-predicate

UNNEST Clause
unnest-clause::= [ join-type ] ( UNNEST | FLATTEN ) expr [ [ AS ] alias ]

USE Clause
use-clause::= use-keys-clause | use-index-clause

use-keys-clause::= USE [ PRIMARY ] KEYS expr

use-index-clause::= USE INDEX "(" index-ref [ "," index-ref ]* ")"

index-ref::= index-name [ index-using ]

index-name::= identifier

index-using::= USING ( VIEW | GSI )

LET Clause
let-clause::= LET alias "=" expr [ "," alias = expr ]*

WHERE Clause
where-clause::= WHERE cond

cond::= expr

GROUP BY Clause
group-by-clause::= GROUP BY expr [ "," expr ]* [ letting-clause ] [ having-clause ] | letting-clause

letting-clause::= LETTING alias "=" expr [ "," alias = expr ]*

having-clause::= HAVING cond

set-op::= UNION | INTERSECT | EXCEPT
