public Object process()

in flink-connector-hive/src/main/java/org/apache/flink/table/planner/delegation/hive/HiveParserTypeCheckProcFactory.java [1480:1684]


        public Object process(
                Node nd, Stack<Node> stack, NodeProcessorCtx procCtx, Object... nodeOutputs)
                throws SemanticException {

            HiveParserTypeCheckCtx ctx = (HiveParserTypeCheckCtx) procCtx;

            ExprNodeDesc desc = HiveParserTypeCheckProcFactory.processGByExpr(nd, procCtx);
            if (desc != null) {
                // Here we know nd represents a group by expression.

                // During the DFS traversal of the AST, a descendant of nd likely set an
                // error because a sub-tree of nd is unlikely to also be a group by
                // expression. For example, in a query such as
                // SELECT *concat(key)* FROM src GROUP BY concat(key), 'key' will be
                // processed before 'concat(key)' and since 'key' is not a group by
                // expression, an error will be set in ctx by ColumnExprProcessor.

                // We can clear the global error when we see that it was set in a
                // descendant node of a group by expression because
                // processGByExpr() returns a ExprNodeDesc that effectively ignores
                // its children. Although the error can be set multiple times by
                // descendant nodes, DFS traversal ensures that the error only needs to
                // be cleared once. Also, for a case like
                // SELECT concat(value, concat(value))... the logic still works as the
                // error is only set with the first 'value'; all node processors quit
                // early if the global error is set.

                if (isDescendant(nd, ctx.getErrorSrcNode())) {
                    ctx.setError(null, null);
                }
                return desc;
            }

            if (ctx.getError() != null) {
                return null;
            }

            HiveParserASTNode expr = (HiveParserASTNode) nd;

            /*
             * A Windowing specification get added as a child to a UDAF invocation to distinguish it
             * from similar UDAFs but on different windows.
             * The UDAF is translated to a WindowFunction invocation in the PTFTranslator.
             * So here we just return null for tokens that appear in a Window Specification.
             * When the traversal reaches up to the UDAF invocation its ExprNodeDesc is build using the
             * ColumnInfo in the InputRR. This is similar to how UDAFs are handled in Select lists.
             * The difference is that there is translation for Window related tokens, so we just
             * return null;
             */
            if (windowingTokens.contains(expr.getType())) {
                if (!ctx.getallowWindowing()) {
                    throw new SemanticException(
                            HiveParserUtils.generateErrorMessage(
                                    expr,
                                    ErrorMsg.INVALID_FUNCTION.getMsg(
                                            "Windowing is not supported in the context")));
                }

                return null;
            }

            if (expr.getType() == HiveASTParser.TOK_SUBQUERY_OP
                    || expr.getType() == HiveASTParser.TOK_QUERY) {
                return null;
            }

            if (expr.getType() == HiveASTParser.TOK_TABNAME) {
                return null;
            }

            if (expr.getType() == HiveASTParser.TOK_ALLCOLREF) {
                if (!ctx.getallowAllColRef()) {
                    throw new SemanticException(
                            HiveParserUtils.generateErrorMessage(
                                    expr,
                                    ErrorMsg.INVALID_COLUMN.getMsg(
                                            "All column reference is not supported in the context")));
                }

                HiveParserRowResolver input = ctx.getInputRR();
                HiveParserExprNodeColumnListDesc columnList =
                        new HiveParserExprNodeColumnListDesc();
                assert expr.getChildCount() <= 1;
                if (expr.getChildCount() == 1) {
                    // table aliased (select a.*, for example)
                    HiveParserASTNode child = (HiveParserASTNode) expr.getChild(0);
                    assert child.getType() == HiveASTParser.TOK_TABNAME;
                    assert child.getChildCount() == 1;
                    String tableAlias = unescapeIdentifier(child.getChild(0).getText());
                    HashMap<String, ColumnInfo> columns = input.getFieldMap(tableAlias);
                    if (columns == null) {
                        throw new SemanticException(
                                HiveParserErrorMsg.getMsg(ErrorMsg.INVALID_TABLE_ALIAS, child));
                    }
                    for (Map.Entry<String, ColumnInfo> colMap : columns.entrySet()) {
                        ColumnInfo colInfo = colMap.getValue();
                        if (!colInfo.getIsVirtualCol()) {
                            columnList.addColumn(toExprNodeDesc(colInfo));
                        }
                    }
                } else {
                    // all columns (select *, for example)
                    for (ColumnInfo colInfo : input.getColumnInfos()) {
                        if (!colInfo.getIsVirtualCol()) {
                            columnList.addColumn(toExprNodeDesc(colInfo));
                        }
                    }
                }
                return columnList;
            }

            // If the first child is a TOK_TABLE_OR_COL, and nodeOutput[0] is NULL,
            // and the operator is a DOT, then it's a table column reference.
            if (expr.getType() == HiveASTParser.DOT
                    && expr.getChild(0).getType() == HiveASTParser.TOK_TABLE_OR_COL
                    && nodeOutputs[0] == null) {
                return processQualifiedColRef(ctx, expr, nodeOutputs);
            }

            // Return nulls for conversion operators
            if (conversionFunctionTextHashMap.keySet().contains(expr.getType())
                    || specialFunctionTextHashMap.keySet().contains(expr.getType())
                    || expr.getToken().getType() == HiveASTParser.CharSetName
                    || expr.getToken().getType() == HiveASTParser.CharSetLiteral) {
                return null;
            }

            boolean isFunction =
                    (expr.getType() == HiveASTParser.TOK_FUNCTION
                            || expr.getType() == HiveASTParser.TOK_FUNCTIONSTAR
                            || expr.getType() == HiveASTParser.TOK_FUNCTIONDI);

            if (!ctx.getAllowDistinctFunctions()
                    && expr.getType() == HiveASTParser.TOK_FUNCTIONDI) {
                throw new SemanticException(
                        HiveParserUtils.generateErrorMessage(
                                expr, ErrorMsg.DISTINCT_NOT_SUPPORTED.getMsg()));
            }

            // Create all children
            int childrenBegin = (isFunction ? 1 : 0);
            ArrayList<ExprNodeDesc> children =
                    new ArrayList<>(expr.getChildCount() - childrenBegin);
            for (int ci = childrenBegin; ci < expr.getChildCount(); ci++) {
                if (nodeOutputs[ci] instanceof HiveParserExprNodeColumnListDesc) {
                    children.addAll(
                            ((HiveParserExprNodeColumnListDesc) nodeOutputs[ci]).getChildren());
                } else {
                    children.add((ExprNodeDesc) nodeOutputs[ci]);
                }
            }

            if (expr.getType() == HiveASTParser.TOK_FUNCTIONSTAR) {
                if (!ctx.getallowFunctionStar()) {
                    throw new SemanticException(
                            HiveParserUtils.generateErrorMessage(
                                    expr,
                                    ErrorMsg.INVALID_COLUMN.getMsg(
                                            ".* reference is not supported in the context")));
                }

                HiveParserRowResolver input = ctx.getInputRR();
                for (ColumnInfo colInfo : input.getColumnInfos()) {
                    if (!colInfo.getIsVirtualCol()) {
                        children.add(toExprNodeDesc(colInfo));
                    }
                }
            }

            // If any of the children contains null, then return a null
            // this is a hack for now to handle the group by case
            if (children.contains(null)) {
                List<String> possibleColumnNames = getReferenceableColumnAliases(ctx);
                String reason =
                        String.format(
                                "(possible column names are: %s)",
                                StringUtils.join(possibleColumnNames, ", "));
                ctx.setError(
                        HiveParserErrorMsg.getMsg(
                                ErrorMsg.INVALID_COLUMN, expr.getChild(0), reason),
                        expr);
                return null;
            }

            // Create function desc
            try {
                return getXpathOrFuncExprNodeDesc(expr, isFunction, children, ctx);
            } catch (UDFArgumentTypeException e) {
                throw new SemanticException(
                        HiveParserErrorMsg.getMsg(
                                ErrorMsg.INVALID_ARGUMENT_TYPE,
                                expr.getChild(childrenBegin + e.getArgumentId()),
                                e.getMessage()),
                        e);
            } catch (UDFArgumentLengthException e) {
                throw new SemanticException(
                        HiveParserErrorMsg.getMsg(
                                ErrorMsg.INVALID_ARGUMENT_LENGTH, expr, e.getMessage()),
                        e);
            } catch (UDFArgumentException e) {
                throw new SemanticException(
                        HiveParserErrorMsg.getMsg(ErrorMsg.INVALID_ARGUMENT, expr, e.getMessage()),
                        e);
            }
        }