in flink-connector-hive/src/main/java/org/apache/flink/table/planner/delegation/hive/copy/HiveParserSemanticAnalyzer.java [892:1219]
public boolean doPhase1(
HiveParserASTNode ast,
HiveParserQB qb,
HiveParserBaseSemanticAnalyzer.Phase1Ctx ctx1,
HiveParserPlannerContext plannerCtx)
throws SemanticException {
boolean phase1Result = true;
HiveParserQBParseInfo qbp = qb.getParseInfo();
boolean skipRecursion = false;
if (ast.getToken() != null) {
skipRecursion = true;
switch (ast.getToken().getType()) {
case HiveASTParser.TOK_SELECTDI:
qb.countSelDi();
// fall through
case HiveASTParser.TOK_SELECT:
qb.countSel();
qbp.setSelExprForClause(ctx1.dest, ast);
int posn = 0;
if (((HiveParserASTNode) ast.getChild(0)).getToken().getType()
== HiveASTParser.QUERY_HINT) {
HiveASTParseDriver pd = new HiveASTParseDriver();
String queryHintStr = ast.getChild(0).getText();
if (LOG.isDebugEnabled()) {
LOG.debug("QUERY HINT: " + queryHintStr);
}
try {
HiveParserASTNode hintNode = pd.parseHint(queryHintStr);
qbp.setHints(hintNode);
posn++;
} catch (HiveASTParseException e) {
throw new SemanticException(
"failed to parse query hint: " + e.getMessage(), e);
}
}
if ((ast.getChild(posn).getChild(0).getType() == HiveASTParser.TOK_TRANSFORM)) {
queryProperties.setUsesScript(true);
}
LinkedHashMap<String, HiveParserASTNode> aggregations =
doPhase1GetAggregationsFromSelect(ast, qb, ctx1.dest);
doPhase1GetColumnAliasesFromSelect(ast, qbp);
qbp.setAggregationExprsForClause(ctx1.dest, aggregations);
qbp.setDistinctFuncExprsForClause(
ctx1.dest, doPhase1GetDistinctFuncExprs(aggregations));
break;
case HiveASTParser.TOK_WHERE:
qbp.setWhrExprForClause(ctx1.dest, ast);
if (!HiveParserSubQueryUtils.findSubQueries((HiveParserASTNode) ast.getChild(0))
.isEmpty()) {
queryProperties.setFilterWithSubQuery(true);
}
break;
case HiveASTParser.TOK_INSERT_INTO:
String tabName =
getUnescapedName(
(HiveParserASTNode) ast.getChild(0).getChild(0),
catalogRegistry.getCurrentCatalog(),
catalogRegistry.getCurrentDatabase());
qbp.addInsertIntoTable(tabName, ast);
// TODO: hive doesn't break here, so we copy what's below here
handleTokDestination(ctx1, ast, qbp, plannerCtx);
break;
case HiveASTParser.TOK_DESTINATION:
handleTokDestination(ctx1, ast, qbp, plannerCtx);
break;
case HiveASTParser.TOK_FROM:
int childCount = ast.getChildCount();
if (childCount != 1) {
throw new SemanticException(
HiveParserUtils.generateErrorMessage(
ast, "Multiple Children " + childCount));
}
if (!qbp.getIsSubQ()) {
qbp.setQueryFromExpr(ast);
}
// Check if this is a subquery / lateral view
HiveParserASTNode frm = (HiveParserASTNode) ast.getChild(0);
if (frm.getToken().getType() == HiveASTParser.TOK_TABREF) {
processTable(qb, frm);
} else if (frm.getToken().getType() == HiveASTParser.TOK_VIRTUAL_TABLE) {
// Create a temp table with the passed values in it then rewrite this
// portion of the tree to be from that table.
HiveParserASTNode newFrom = genValuesTempTable(frm, qb);
ast.setChild(0, newFrom);
processTable(qb, newFrom);
} else if (frm.getToken().getType() == HiveASTParser.TOK_SUBQUERY) {
processSubQuery(qb, frm);
} else if (frm.getToken().getType() == HiveASTParser.TOK_LATERAL_VIEW
|| frm.getToken().getType() == HiveASTParser.TOK_LATERAL_VIEW_OUTER) {
queryProperties.setHasLateralViews(true);
processLateralView(qb, frm);
} else if (HiveParserUtils.isJoinToken(frm)) {
processJoin(qb, frm);
qbp.setJoinExpr(frm);
} else if (frm.getToken().getType() == HiveASTParser.TOK_PTBLFUNCTION) {
queryProperties.setHasPTF(true);
processPTF(qb, frm);
}
break;
case HiveASTParser.TOK_CLUSTERBY:
// Get the clusterby aliases - these are aliased to the entries in the select
// list
queryProperties.setHasClusterBy(true);
qbp.setClusterByExprForClause(ctx1.dest, ast);
break;
case HiveASTParser.TOK_DISTRIBUTEBY:
// Get the distribute by aliases - these are aliased to the entries in the
// select list
queryProperties.setHasDistributeBy(true);
qbp.setDistributeByExprForClause(ctx1.dest, ast);
if (qbp.getClusterByForClause(ctx1.dest) != null) {
throw new SemanticException(
HiveParserUtils.generateErrorMessage(
ast, ErrorMsg.CLUSTERBY_DISTRIBUTEBY_CONFLICT.getMsg()));
} else if (qbp.getOrderByForClause(ctx1.dest) != null) {
throw new SemanticException(
HiveParserUtils.generateErrorMessage(
ast, ErrorMsg.ORDERBY_DISTRIBUTEBY_CONFLICT.getMsg()));
}
break;
case HiveASTParser.TOK_SORTBY:
// Get the sort by aliases - these are aliased to the entries in the select list
queryProperties.setHasSortBy(true);
qbp.setSortByExprForClause(ctx1.dest, ast);
if (qbp.getClusterByForClause(ctx1.dest) != null) {
throw new SemanticException(
HiveParserUtils.generateErrorMessage(
ast, ErrorMsg.CLUSTERBY_SORTBY_CONFLICT.getMsg()));
} else if (qbp.getOrderByForClause(ctx1.dest) != null) {
throw new SemanticException(
HiveParserUtils.generateErrorMessage(
ast, ErrorMsg.ORDERBY_SORTBY_CONFLICT.getMsg()));
}
break;
case HiveASTParser.TOK_ORDERBY:
// Get the order by aliases - these are aliased to the entries in the select
// list
queryProperties.setHasOrderBy(true);
qbp.setOrderByExprForClause(ctx1.dest, ast);
if (qbp.getClusterByForClause(ctx1.dest) != null) {
throw new SemanticException(
HiveParserUtils.generateErrorMessage(
ast, ErrorMsg.CLUSTERBY_ORDERBY_CONFLICT.getMsg()));
}
break;
case HiveASTParser.TOK_GROUPBY:
case HiveASTParser.TOK_ROLLUP_GROUPBY:
case HiveASTParser.TOK_CUBE_GROUPBY:
case HiveASTParser.TOK_GROUPING_SETS:
// Get the groupby aliases - these are aliased to the entries in the select list
queryProperties.setHasGroupBy(true);
if (qbp.getJoinExpr() != null) {
queryProperties.setHasJoinFollowedByGroupBy(true);
}
if (qbp.getSelForClause(ctx1.dest).getToken().getType()
== HiveASTParser.TOK_SELECTDI) {
throw new SemanticException(
HiveParserUtils.generateErrorMessage(
ast, ErrorMsg.SELECT_DISTINCT_WITH_GROUPBY.getMsg()));
}
qbp.setGroupByExprForClause(ctx1.dest, ast);
skipRecursion = true;
// Rollup and Cubes are syntactic sugar on top of grouping sets
if (ast.getToken().getType() == HiveASTParser.TOK_ROLLUP_GROUPBY) {
qbp.getDestRollups().add(ctx1.dest);
} else if (ast.getToken().getType() == HiveASTParser.TOK_CUBE_GROUPBY) {
qbp.getDestCubes().add(ctx1.dest);
} else if (ast.getToken().getType() == HiveASTParser.TOK_GROUPING_SETS) {
qbp.getDestGroupingSets().add(ctx1.dest);
}
break;
case HiveASTParser.TOK_HAVING:
qbp.setHavingExprForClause(ctx1.dest, ast);
qbp.addAggregationExprsForClause(
ctx1.dest, doPhase1GetAggregationsFromSelect(ast, qb, ctx1.dest));
break;
case HiveASTParser.KW_WINDOW:
if (!qb.hasWindowingSpec(ctx1.dest)) {
throw new SemanticException(
HiveParserUtils.generateErrorMessage(
ast,
"Query has no Cluster/Distribute By; but has a Window definition"));
}
handleQueryWindowClauses(qb, ctx1, ast);
break;
case HiveASTParser.TOK_LIMIT:
if (ast.getChildCount() == 2) {
qbp.setDestLimit(
ctx1.dest,
new Integer(ast.getChild(0).getText()),
new Integer(ast.getChild(1).getText()));
} else {
qbp.setDestLimit(ctx1.dest, 0, new Integer(ast.getChild(0).getText()));
}
break;
case HiveASTParser.TOK_ANALYZE:
// Case of analyze command
String tableName =
getUnescapedName((HiveParserASTNode) ast.getChild(0).getChild(0))
.toLowerCase();
String originTableName =
getUnescapedOriginTableName(
(HiveParserASTNode) ast.getChild(0).getChild(0));
qb.setTabAlias(tableName, originTableName, tableName);
qb.addAlias(tableName);
qb.getParseInfo().setIsAnalyzeCommand(true);
qb.getParseInfo().setNoScanAnalyzeCommand(this.noscan);
qb.getParseInfo().setPartialScanAnalyzeCommand(this.partialscan);
// Allow analyze the whole table and dynamic partitions
HiveConf.setVar(conf, HiveConf.ConfVars.DYNAMICPARTITIONINGMODE, "nonstrict");
HiveConf.setVar(conf, HiveConf.ConfVars.HIVEMAPREDMODE, "nonstrict");
break;
case HiveASTParser.TOK_UNIONALL:
if (!qbp.getIsSubQ()) {
// this shouldn't happen. The parser should have converted the union to be
// contained in a subquery. Just in case, we keep the error as a fallback.
throw new SemanticException(
HiveParserUtils.generateErrorMessage(
ast, ErrorMsg.UNION_NOTIN_SUBQ.getMsg()));
}
skipRecursion = false;
break;
case HiveASTParser.TOK_INSERT:
HiveParserASTNode destination = (HiveParserASTNode) ast.getChild(0);
Tree tab = destination.getChild(0);
// Proceed if AST contains partition & If Not Exists
if (destination.getChildCount() == 2
&& tab.getChildCount() == 2
&& destination.getChild(1).getType() == HiveASTParser.TOK_IFNOTEXISTS) {
ObjectIdentifier tableIdentifier =
getObjectIdentifier(
catalogRegistry, (HiveParserASTNode) tab.getChild(0));
Tree partitions = tab.getChild(1);
int numChildren = partitions.getChildCount();
HashMap<String, String> partition = new HashMap<>();
for (int i = 0; i < numChildren; i++) {
String partitionName = partitions.getChild(i).getChild(0).getText();
Tree pvalue = partitions.getChild(i).getChild(1);
if (pvalue == null) {
break;
}
String partitionVal = stripQuotes(pvalue.getText());
partition.put(partitionName, partitionVal);
}
// if it is a dynamic partition throw the exception
if (numChildren != partition.size()) {
throw new SemanticException(
ErrorMsg.INSERT_INTO_DYNAMICPARTITION_IFNOTEXISTS.getMsg(
partition.toString()));
}
Optional<CatalogPartition> catalogPartition =
catalogRegistry.getPartition(
tableIdentifier, new CatalogPartitionSpec(partition));
// Check partition exists if it exists skip the overwrite
if (catalogPartition.isPresent()) {
phase1Result = false;
skipRecursion = true;
LOG.info(
"Partition already exists so insert into overwrite "
+ "skipped for partition : "
+ partition);
break;
}
ResolvedCatalogTable catalogTable =
(ResolvedCatalogTable)
(getCatalogTable(tableIdentifier.asSummaryString(), qb));
validatePartColumnType(
catalogTable,
partition,
(HiveParserASTNode) tab,
conf,
frameworkConfig,
cluster);
}
skipRecursion = false;
break;
case HiveASTParser.TOK_LATERAL_VIEW:
case HiveASTParser.TOK_LATERAL_VIEW_OUTER:
// todo: nested LV
assert ast.getChildCount() == 1;
qb.getParseInfo().getDestToLateralView().put(ctx1.dest, ast);
break;
case HiveASTParser.TOK_CTE:
processCTE(qb, ast);
break;
default:
skipRecursion = false;
break;
}
}
if (!skipRecursion) {
// Iterate over the rest of the children
int childCount = ast.getChildCount();
for (int childPos = 0; childPos < childCount && phase1Result; ++childPos) {
phase1Result =
doPhase1((HiveParserASTNode) ast.getChild(childPos), qb, ctx1, plannerCtx);
}
}
return phase1Result;
}