SelectStatement <- SelectOrParens (SetopClause SelectStatement)* ResultModifiers SetopClause <- ('UNION' / 'EXCEPT' / 'INTERSECT') DistinctOrAll? ByName? ByName <- 'BY' 'NAME' SelectOrParens <- BaseSelect / Parens(SelectStatement) BaseSelect <- WithClause? (OptionalParensSimpleSelect / ValuesClause / DescribeStatement / TableStatement / PivotStatement / UnpivotStatement) ResultModifiers ResultModifiers <- OrderByClause? LimitClause? OffsetClause? TableStatement <- 'TABLE' BaseTableName OptionalParensSimpleSelect <- Parens(SimpleSelect) / SimpleSelect SimpleSelect <- SelectFrom WhereClause? GroupByClause? HavingClause? WindowClause? QualifyClause? SampleClause? SelectFrom <- (SelectClause FromClause?) / (FromClause SelectClause?) WithStatement <- ColIdOrString InsertColumnList? UsingKey? 'AS' Materialized? SubqueryReference UsingKey <- 'USING' 'KEY' Parens(List(ColId)) Materialized <- 'NOT'? 'MATERIALIZED' WithClause <- 'WITH' Recursive? List(WithStatement) Recursive <- 'RECURSIVE' SelectClause <- 'SELECT' DistinctClause? TargetList TargetList <- List(AliasedExpression) ColumnAliases <- Parens(List(ColIdOrString)) DistinctClause <- ('DISTINCT' DistinctOn?) / 'ALL' DistinctOn <- 'ON' Parens(List(Expression)) InnerTableRef <- ValuesRef / TableFunction / TableSubquery / BaseTableRef / ParensTableRef TableRef <- InnerTableRef JoinOrPivot* TableAlias? TableSubquery <- Lateral? SubqueryReference TableAlias? BaseTableRef <- TableAliasColon? BaseTableName TableAlias? AtClause? TableAliasColon <- ColIdOrString ':' ValuesRef <- ValuesClause TableAlias? ParensTableRef <- TableAliasColon? Parens(TableRef) JoinOrPivot <- JoinClause / TablePivotClause / TableUnpivotClause TablePivotClause <- 'PIVOT' Parens(TargetList 'FOR' PivotValueLists GroupByClause?) TableAlias? TableUnpivotClause <- 'UNPIVOT' IncludeExcludeNulls? Parens(UnpivotHeader 'FOR' PivotValueLists) TableAlias? PivotHeader <- BaseExpression PivotValueLists <- PivotValueList PivotValueList* PivotValueList <- PivotHeader 'IN' PivotTargetList PivotTargetList <- Identifier / Parens(TargetList) Lateral <- 'LATERAL' BaseTableName <- CatalogReservedSchemaTable / SchemaReservedTable / TableName SchemaReservedTable <- SchemaQualification ReservedTableName CatalogReservedSchemaTable <- CatalogQualification ReservedSchemaQualification ReservedTableName TableFunction <- TableFunctionLateralOpt / TableFunctionAliasColon TableFunctionLateralOpt <- Lateral? QualifiedTableFunction TableFunctionArguments WithOrdinality? TableAlias? TableFunctionAliasColon <- TableAliasColon QualifiedTableFunction TableFunctionArguments WithOrdinality? WithOrdinality <- 'WITH' 'ORDINALITY' QualifiedTableFunction <- CatalogQualification? SchemaQualification? TableFunctionName TableFunctionArguments <- Parens(List(FunctionArgument)?) FunctionArgument <- NamedParameter / Expression NamedParameter <- TypeName Type? NamedParameterAssignment Expression NamedParameterAssignment <- ':=' / '=>' TableAlias <- 'AS'? (Identifier / StringLiteral) ColumnAliases? AtClause <- 'AT' Parens(AtSpecifier) AtSpecifier <- AtUnit '=>' Expression AtUnit <- 'VERSION' / 'TIMESTAMP' JoinClause <- RegularJoinClause / JoinWithoutOnClause RegularJoinClause <- 'ASOF'? JoinType? 'JOIN' TableRef JoinQualifier JoinWithoutOnClause <- JoinPrefix 'JOIN' TableRef JoinQualifier <- OnClause / UsingClause OnClause <- 'ON' Expression UsingClause <- 'USING' Parens(List(ColumnName)) OuterJoinType <- 'FULL' / 'LEFT' / 'RIGHT' JoinType <- (OuterJoinType 'OUTER'?) / 'SEMI' / 'ANTI' / 'INNER' JoinPrefix <- 'CROSS' / ('NATURAL' JoinType?) / 'POSITIONAL' FromClause <- 'FROM' List(TableRef) WhereClause <- 'WHERE' Expression GroupByClause <- 'GROUP' 'BY' GroupByExpressions HavingClause <- 'HAVING' Expression QualifyClause <- 'QUALIFY' Expression SampleClause <- (TableSample / UsingSample) SampleEntry UsingSample <- 'USING' 'SAMPLE' TableSample <- 'TABLESAMPLE' WindowClause <- 'WINDOW' List(WindowDefinition) WindowDefinition <- Identifier 'AS' WindowFrameDefinition SampleEntry <- SampleEntryFunction / SampleEntryCount SampleEntryCount <- SampleCount Parens(SampleProperties)? SampleEntryFunction <- SampleFunction? Parens(SampleCount) RepeatableSample? SampleFunction <- ColId SampleProperties <- ColId (',' NumberLiteral)? RepeatableSample <- 'REPEATABLE' Parens(NumberLiteral) SampleCount <- Expression SampleUnit? SampleUnit <- '%' / 'PERCENT' / 'ROWS' GroupByExpressions <- GroupByList / 'ALL' GroupByList <- List(GroupByExpression) GroupByExpression <- EmptyGroupingItem / CubeOrRollupClause / GroupingSetsClause / Expression EmptyGroupingItem <- '(' ')' CubeOrRollupClause <- CubeOrRollup Parens(List(Expression)) CubeOrRollup <- 'CUBE' / 'ROLLUP' GroupingSetsClause <- 'GROUPING' 'SETS' Parens(GroupByList) SubqueryReference <- Parens(SelectStatement) OrderByExpression <- Expression DescOrAsc? NullsFirstOrLast? DescOrAsc <- 'DESC' / 'DESCENDING' / 'ASC' / 'ASCENDING' NullsFirstOrLast <- 'NULLS' 'FIRST' / 'LAST' OrderByClause <- 'ORDER' 'BY' OrderByExpressions OrderByExpressions <- List(OrderByExpression) / OrderByAll OrderByAll <- 'ALL' DescOrAsc? NullsFirstOrLast? LimitClause <- 'LIMIT' LimitValue OffsetClause <- 'OFFSET' OffsetValue LimitValue <- 'ALL' / (NumberLiteral 'PERCENT') / (Expression '%'?) OffsetValue <- Expression RowOrRows? RowOrRows <- 'ROW' / 'ROWS' AliasedExpression <- (ColId ':' Expression) / (Expression 'AS' ColLabelOrString) / (Expression Identifier?) ValuesClause <- 'VALUES' List(ValuesExpressions) ValuesExpressions <- Parens(List(Expression))