blob: 6e773957cebf11478a2a38f916f7536fabe3f4eb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** Counterpart of hive's FromClauseParser.g. */
parser grammar FromClauseASTParser;
options
{
output=AST;
ASTLabelType=HiveParserASTNode;
backtrack=false;
k=3;
}
@members {
@Override
public Object recoverFromMismatchedSet(IntStream input,
RecognitionException re, BitSet follow) throws RecognitionException {
throw re;
}
@Override
public void displayRecognitionError(String[] tokenNames,
RecognitionException e) {
gParent.errors.add(new HiveASTParseError(gParent, e, tokenNames));
}
protected boolean useSQL11ReservedKeywordsForIdentifier() {
return gParent.useSQL11ReservedKeywordsForIdentifier();
}
}
@rulecatch {
catch (RecognitionException e) {
throw e;
}
}
//-----------------------------------------------------------------------------------
tableAllColumns
: STAR
-> ^(TOK_ALLCOLREF)
| tableName DOT STAR
-> ^(TOK_ALLCOLREF tableName)
;
// (table|column)
tableOrColumn
@init { gParent.pushMsg("table or column identifier", state); }
@after { gParent.popMsg(state); }
:
identifier -> ^(TOK_TABLE_OR_COL identifier)
;
expressionList
@init { gParent.pushMsg("expression list", state); }
@after { gParent.popMsg(state); }
:
expression (COMMA expression)* -> ^(TOK_EXPLIST expression+)
;
aliasList
@init { gParent.pushMsg("alias list", state); }
@after { gParent.popMsg(state); }
:
identifier (COMMA identifier)* -> ^(TOK_ALIASLIST identifier+)
;
//----------------------- Rules for parsing fromClause ------------------------------
// from [col1, col2, col3] table1, [col4, col5] table2
fromClause
@init { gParent.pushMsg("from clause", state); }
@after { gParent.popMsg(state); }
:
KW_FROM fromSource -> ^(TOK_FROM fromSource)
;
fromSource
@init { gParent.pushMsg("join source", state); }
@after { gParent.popMsg(state); }
:
virtualTableSource
|
uniqueJoinToken^ uniqueJoinSource (COMMA! uniqueJoinSource)+
|
joinSource
;
atomjoinSource
@init { gParent.pushMsg("joinSource", state); }
@after { gParent.popMsg(state); }
:
tableSource (lateralView^)*
|
(subQuerySource) => subQuerySource (lateralView^)*
|
partitionedTableFunction (lateralView^)*
|
LPAREN! joinSource RPAREN!
;
joinSource
:
atomjoinSource (joinToken^ joinSourcePart (KW_ON! expression {$joinToken.start.getType() != COMMA}? | KW_USING! columnParenthesesList {$joinToken.start.getType() != COMMA}?)?)*
;
joinSourcePart
@init { gParent.pushMsg("joinSourcePart", state); }
@after { gParent.popMsg(state); }
:
(tableSource | subQuerySource | partitionedTableFunction) (lateralView^)*
;
uniqueJoinSource
@init { gParent.pushMsg("unique join source", state); }
@after { gParent.popMsg(state); }
: KW_PRESERVE? uniqueJoinTableSource uniqueJoinExpr
;
uniqueJoinExpr
@init { gParent.pushMsg("unique join expression list", state); }
@after { gParent.popMsg(state); }
: LPAREN! expressionList RPAREN!
;
uniqueJoinToken
@init { gParent.pushMsg("unique join", state); }
@after { gParent.popMsg(state); }
: KW_UNIQUEJOIN -> TOK_UNIQUEJOIN;
joinToken
@init { gParent.pushMsg("join type specifier", state); }
@after { gParent.popMsg(state); }
:
KW_JOIN -> TOK_JOIN
| KW_INNER KW_JOIN -> TOK_JOIN
| COMMA -> TOK_JOIN
| KW_CROSS KW_JOIN -> TOK_CROSSJOIN
| KW_LEFT (KW_OUTER)? KW_JOIN -> TOK_LEFTOUTERJOIN
| KW_RIGHT (KW_OUTER)? KW_JOIN -> TOK_RIGHTOUTERJOIN
| KW_FULL (KW_OUTER)? KW_JOIN -> TOK_FULLOUTERJOIN
| KW_LEFT KW_SEMI KW_JOIN -> TOK_LEFTSEMIJOIN
;
lateralView
@init {gParent.pushMsg("lateral view", state); }
@after {gParent.popMsg(state); }
:
(KW_LATERAL KW_VIEW KW_OUTER) => KW_LATERAL KW_VIEW KW_OUTER function tableAlias (KW_AS identifier ((COMMA)=> COMMA identifier)*)?
-> ^(TOK_LATERAL_VIEW_OUTER ^(TOK_SELECT ^(TOK_SELEXPR function identifier* tableAlias)))
|
KW_LATERAL KW_VIEW function tableAlias (KW_AS identifier ((COMMA)=> COMMA identifier)*)?
-> ^(TOK_LATERAL_VIEW ^(TOK_SELECT ^(TOK_SELEXPR function identifier* tableAlias)))
;
tableAlias
@init {gParent.pushMsg("table alias", state); }
@after {gParent.popMsg(state); }
:
identifier -> ^(TOK_TABALIAS identifier)
;
tableBucketSample
@init { gParent.pushMsg("table bucket sample specification", state); }
@after { gParent.popMsg(state); }
:
KW_TABLESAMPLE LPAREN KW_BUCKET (numerator=Number) KW_OUT KW_OF (denominator=Number) (KW_ON expr+=expression (COMMA expr+=expression)*)? RPAREN -> ^(TOK_TABLEBUCKETSAMPLE $numerator $denominator $expr*)
;
splitSample
@init { gParent.pushMsg("table split sample specification", state); }
@after { gParent.popMsg(state); }
:
KW_TABLESAMPLE LPAREN (numerator=Number) (percent=KW_PERCENT|KW_ROWS) RPAREN
-> {percent != null}? ^(TOK_TABLESPLITSAMPLE TOK_PERCENT $numerator)
-> ^(TOK_TABLESPLITSAMPLE TOK_ROWCOUNT $numerator)
|
KW_TABLESAMPLE LPAREN (numerator=ByteLengthLiteral) RPAREN
-> ^(TOK_TABLESPLITSAMPLE TOK_LENGTH $numerator)
;
tableSample
@init { gParent.pushMsg("table sample specification", state); }
@after { gParent.popMsg(state); }
:
tableBucketSample |
splitSample
;
tableSource
@init { gParent.pushMsg("table source", state); }
@after { gParent.popMsg(state); }
: tabname=tableName props=tableProperties? ts=tableSample? (KW_AS? alias=identifier)?
-> ^(TOK_TABREF $tabname $props? $ts? $alias?)
;
uniqueJoinTableSource
@init { gParent.pushMsg("unique join table source", state); }
@after { gParent.popMsg(state); }
: tabname=tableName ts=tableSample? (KW_AS? alias=identifier)?
-> ^(TOK_TABREF $tabname $ts? $alias?)
;
tableName
@init { gParent.pushMsg("table name", state); }
@after { gParent.popMsg(state); }
:
(identifier DOT identifier DOT identifier) => cat=identifier DOT db=identifier DOT tab=identifier
-> ^(TOK_TABNAME $cat $db $tab)
|
db=identifier DOT tab=identifier
-> ^(TOK_TABNAME $db $tab)
|
tab=identifier
-> ^(TOK_TABNAME $tab)
;
viewName
@init { gParent.pushMsg("view name", state); }
@after { gParent.popMsg(state); }
:
(identifier DOT identifier DOT identifier) => cat=identifier DOT db=identifier DOT view=identifier
-> ^(TOK_TABNAME $cat $db $view)
|
db=identifier DOT view=identifier
-> ^(TOK_TABNAME $db $view)
|
view=identifier
-> ^(TOK_TABNAME $view)
;
subQuerySource
@init { gParent.pushMsg("subquery source", state); }
@after { gParent.popMsg(state); }
:
LPAREN queryStatementExpression RPAREN KW_AS? identifier -> ^(TOK_SUBQUERY queryStatementExpression identifier)
;
//---------------------- Rules for parsing PTF clauses -----------------------------
partitioningSpec
@init { gParent.pushMsg("partitioningSpec clause", state); }
@after { gParent.popMsg(state); }
:
partitionByClause orderByClause? -> ^(TOK_PARTITIONINGSPEC partitionByClause orderByClause?) |
orderByClause -> ^(TOK_PARTITIONINGSPEC orderByClause) |
distributeByClause sortByClause? -> ^(TOK_PARTITIONINGSPEC distributeByClause sortByClause?) |
sortByClause -> ^(TOK_PARTITIONINGSPEC sortByClause) |
clusterByClause -> ^(TOK_PARTITIONINGSPEC clusterByClause)
;
partitionTableFunctionSource
@init { gParent.pushMsg("partitionTableFunctionSource clause", state); }
@after { gParent.popMsg(state); }
:
subQuerySource |
tableSource |
partitionedTableFunction
;
partitionedTableFunction
@init { gParent.pushMsg("ptf clause", state); }
@after { gParent.popMsg(state); }
:
name=Identifier LPAREN KW_ON
((partitionTableFunctionSource) => (ptfsrc=partitionTableFunctionSource spec=partitioningSpec?))
((Identifier LPAREN expression RPAREN ) => Identifier LPAREN expression RPAREN ( COMMA Identifier LPAREN expression RPAREN)*)?
((RPAREN) => (RPAREN)) ((Identifier) => alias=Identifier)?
-> ^(TOK_PTBLFUNCTION $name $alias? $ptfsrc $spec? expression*)
;
//----------------------- Rules for parsing whereClause -----------------------------
// where a=b and ...
whereClause
@init { gParent.pushMsg("where clause", state); }
@after { gParent.popMsg(state); }
:
KW_WHERE searchCondition -> ^(TOK_WHERE searchCondition)
;
searchCondition
@init { gParent.pushMsg("search condition", state); }
@after { gParent.popMsg(state); }
:
expression
;
//-----------------------------------------------------------------------------------
//-------- Row Constructor ----------------------------------------------------------
//in support of SELECT * FROM (VALUES(1,2,3),(4,5,6),...) as FOO(a,b,c) and
// INSERT INTO <table> (col1,col2,...) VALUES(...),(...),...
// INSERT INTO <table> (col1,col2,...) SELECT * FROM (VALUES(1,2,3),(4,5,6),...) as Foo(a,b,c)
valueRowConstructor
@init { gParent.pushMsg("value row constructor", state); }
@after { gParent.popMsg(state); }
:
expressionsInParenthesis[false] -> ^(TOK_VALUE_ROW expressionsInParenthesis)
;
valuesTableConstructor
@init { gParent.pushMsg("values table constructor", state); }
@after { gParent.popMsg(state); }
:
valueRowConstructor (COMMA valueRowConstructor)* -> ^(TOK_VALUES_TABLE valueRowConstructor+)
;
/*
VALUES(1),(2) means 2 rows, 1 column each.
VALUES(1,2),(3,4) means 2 rows, 2 columns each.
VALUES(1,2,3) means 1 row, 3 columns
*/
valuesClause
@init { gParent.pushMsg("values clause", state); }
@after { gParent.popMsg(state); }
:
KW_VALUES! valuesTableConstructor
;
/*
This represents a clause like this:
(VALUES(1,2),(2,3)) as VirtTable(col1,col2)
*/
virtualTableSource
@init { gParent.pushMsg("virtual table source", state); }
@after { gParent.popMsg(state); }
:
LPAREN valuesClause RPAREN tableNameColList -> ^(TOK_VIRTUAL_TABLE tableNameColList valuesClause)
;
/*
e.g. as VirtTable(col1,col2)
Note that we only want literals as column names
*/
tableNameColList
@init { gParent.pushMsg("from source", state); }
@after { gParent.popMsg(state); }
:
KW_AS? identifier LPAREN identifier (COMMA identifier)* RPAREN -> ^(TOK_VIRTUAL_TABREF ^(TOK_TABNAME identifier) ^(TOK_COL_NAME identifier+))
;
//-----------------------------------------------------------------------------------