private static ASTNode createASTLateralView(TableFunctionScan tfs, Schema s,
      QueryBlockInfo tableFunctionSource, String sqAlias) {
    // The structure of the AST LATERAL VIEW will be:
    //
    //   TOK_LATERAL_VIEW
    //     TOK_SELECT
    //       TOK_SELEXPR
    //         TOK_FUNCTION
    //           <udtf func>
    //           ...
    //         <col alias for function>
    //         TOK_TABALIAS
    //           <table alias for lateral view>

    // set up the select for the parameters of the UDTF
    List<ASTNode> children = new ArrayList<>();
    // The UDTF function call within the table function scan will be of the form:
    // lateral(my_udtf_func(...), $0, $1, ...).  For recreating the AST, we need
    // the inner "my_udtf_func".
    RexCall lateralCall = (RexCall) tfs.getCall();
    RexCall call = (RexCall) lateralCall.getOperands().get(0);
    for (RexNode rn : call.getOperands()) {
      ASTNode expr = rn.accept(new RexVisitor(s, rn instanceof RexLiteral,
          tfs.getCluster().getRexBuilder()));
      children.add(expr);
    }
    ASTNode function = buildUDTFAST(call.getOperator().getName(), children);

    // Add the function to the SELEXPR
    ASTBuilder selexpr = ASTBuilder.construct(HiveParser.TOK_SELEXPR, "TOK_SELEXPR");
    selexpr.add(function);

    // Add only the table generated size columns to the select expr for the function,
    // skipping over the base table columns from the input side of the join.
    int i = 0;
    for (ColumnInfo c : s) {
      if (i++ < tableFunctionSource.schema.size()) {
        continue;
      }
      selexpr.add(HiveParser.Identifier, c.column);
    }
    // add the table alias for the lateral view.
    ASTBuilder tabAlias = ASTBuilder.construct(HiveParser.TOK_TABALIAS, "TOK_TABALIAS");
    tabAlias.add(HiveParser.Identifier, sqAlias);

    // add the table alias to the SEL_EXPR
    selexpr.add(tabAlias.node());

    // create the SELECT clause
    ASTBuilder sel = ASTBuilder.construct(HiveParser.TOK_SELEXPR, "TOK_SELECT");
    sel.add(selexpr.node());

    // place the SELECT clause under the LATERAL VIEW clause
    ASTBuilder lateralview = ASTBuilder.construct(HiveParser.TOK_LATERAL_VIEW, "TOK_LATERAL_VIEW");
    lateralview.add(sel.node());

    // finally, add the LATERAL VIEW clause under the left side source which is the base table.
    lateralview.add(tableFunctionSource.ast);

    return lateralview.node();
  }
Add PK-FK join information to the AST as a query hint
@param ast
@param join
@param swapSides whether the left and right input of the join is swapped
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/ASTConverter.java