in flink-connector-hive/src/main/java/org/apache/flink/table/planner/delegation/hive/copy/HiveParserBaseSemanticAnalyzer.java [1037:1159]
public static void processPositionAlias(HiveParserASTNode ast, HiveConf conf)
throws SemanticException {
boolean isBothByPos =
HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_GROUPBY_ORDERBY_POSITION_ALIAS);
boolean isGbyByPos =
isBothByPos
|| Boolean.parseBoolean(conf.get("hive.groupby.position.alias", "false"));
boolean isObyByPos =
isBothByPos
|| Boolean.parseBoolean(conf.get("hive.orderby.position.alias", "true"));
Deque<HiveParserASTNode> stack = new ArrayDeque<>();
stack.push(ast);
while (!stack.isEmpty()) {
HiveParserASTNode next = stack.pop();
if (next.getChildCount() == 0) {
continue;
}
boolean isAllCol;
HiveParserASTNode selectNode = null;
HiveParserASTNode groupbyNode = null;
HiveParserASTNode orderbyNode = null;
// get node type
int childCount = next.getChildCount();
for (int childPos = 0; childPos < childCount; ++childPos) {
HiveParserASTNode node = (HiveParserASTNode) next.getChild(childPos);
int type = node.getToken().getType();
if (type == HiveASTParser.TOK_SELECT) {
selectNode = node;
} else if (type == HiveASTParser.TOK_GROUPBY) {
groupbyNode = node;
} else if (type == HiveASTParser.TOK_ORDERBY) {
orderbyNode = node;
}
}
if (selectNode != null) {
int selectExpCnt = selectNode.getChildCount();
// replace each of the position alias in GROUPBY with the actual column name
if (groupbyNode != null) {
for (int childPos = 0; childPos < groupbyNode.getChildCount(); ++childPos) {
HiveParserASTNode node = (HiveParserASTNode) groupbyNode.getChild(childPos);
if (node.getToken().getType() == HiveASTParser.Number) {
if (isGbyByPos) {
int pos = Integer.parseInt(node.getText());
if (pos > 0 && pos <= selectExpCnt) {
groupbyNode.setChild(
childPos, selectNode.getChild(pos - 1).getChild(0));
} else {
throw new SemanticException(
ErrorMsg.INVALID_POSITION_ALIAS_IN_GROUPBY.getMsg(
"Position alias: "
+ pos
+ " does not exist\n"
+ "The Select List is indexed from 1 to "
+ selectExpCnt));
}
} else {
warn(
"Using constant number "
+ node.getText()
+ " in group by. If you try to use position alias when hive.groupby.position.alias is false, the position alias will be ignored.");
}
}
}
}
// replace each of the position alias in ORDERBY with the actual column name
if (orderbyNode != null) {
isAllCol = false;
for (int childPos = 0; childPos < selectNode.getChildCount(); ++childPos) {
HiveParserASTNode node =
(HiveParserASTNode) selectNode.getChild(childPos).getChild(0);
if (node != null
&& node.getToken().getType() == HiveASTParser.TOK_ALLCOLREF) {
isAllCol = true;
}
}
for (int childPos = 0; childPos < orderbyNode.getChildCount(); ++childPos) {
HiveParserASTNode colNode =
(HiveParserASTNode) orderbyNode.getChild(childPos).getChild(0);
HiveParserASTNode node = (HiveParserASTNode) colNode.getChild(0);
if (node != null && node.getToken().getType() == HiveASTParser.Number) {
if (isObyByPos) {
if (!isAllCol) {
int pos = Integer.parseInt(node.getText());
if (pos > 0 && pos <= selectExpCnt) {
colNode.setChild(
0, selectNode.getChild(pos - 1).getChild(0));
} else {
throw new SemanticException(
ErrorMsg.INVALID_POSITION_ALIAS_IN_ORDERBY.getMsg(
"Position alias: "
+ pos
+ " does not exist\n"
+ "The Select List is indexed from 1 to "
+ selectExpCnt));
}
} else {
throw new SemanticException(
ErrorMsg.NO_SUPPORTED_ORDERBY_ALLCOLREF_POS.getMsg());
}
} else { // if not using position alias and it is a number.
warn(
"Using constant number "
+ node.getText()
+ " in order by. If you try to use position alias when hive.orderby.position.alias is false, the position alias will be ignored.");
}
}
}
}
}
for (int i = next.getChildren().size() - 1; i >= 0; i--) {
stack.push((HiveParserASTNode) next.getChildren().get(i));
}
}
}