public boolean doPhase1()

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;
    }