Search in sources :

Example 1 with HiveParserNamedJoinInfo

use of org.apache.flink.table.planner.delegation.hive.copy.HiveParserNamedJoinInfo in project flink by apache.

the class HiveParserCalcitePlanner method genJoinRelNode.

private RelNode genJoinRelNode(RelNode leftRel, String leftTableAlias, RelNode rightRel, String rightTableAlias, JoinType hiveJoinType, HiveParserASTNode joinCondAst) throws SemanticException {
    HiveParserRowResolver leftRR = relToRowResolver.get(leftRel);
    HiveParserRowResolver rightRR = relToRowResolver.get(rightRel);
    // 1. Construct ExpressionNodeDesc representing Join Condition
    RexNode joinCondRex;
    List<String> namedColumns = null;
    if (joinCondAst != null) {
        HiveParserJoinTypeCheckCtx jCtx = new HiveParserJoinTypeCheckCtx(leftRR, rightRR, hiveJoinType, frameworkConfig, cluster);
        HiveParserRowResolver combinedRR = HiveParserRowResolver.getCombinedRR(leftRR, rightRR);
        if (joinCondAst.getType() == HiveASTParser.TOK_TABCOLNAME && !hiveJoinType.equals(JoinType.LEFTSEMI)) {
            namedColumns = new ArrayList<>();
            // We will transform using clause and make it look like an on-clause.
            // So, lets generate a valid on-clause AST from using.
            HiveParserASTNode and = (HiveParserASTNode) HiveASTParseDriver.ADAPTOR.create(HiveASTParser.KW_AND, "and");
            HiveParserASTNode equal = null;
            int count = 0;
            for (Node child : joinCondAst.getChildren()) {
                String columnName = ((HiveParserASTNode) child).getText();
                // dealing with views
                if (semanticAnalyzer.unparseTranslator != null && semanticAnalyzer.unparseTranslator.isEnabled()) {
                    semanticAnalyzer.unparseTranslator.addIdentifierTranslation((HiveParserASTNode) child);
                }
                namedColumns.add(columnName);
                HiveParserASTNode left = HiveParserASTBuilder.qualifiedName(leftTableAlias, columnName);
                HiveParserASTNode right = HiveParserASTBuilder.qualifiedName(rightTableAlias, columnName);
                equal = (HiveParserASTNode) HiveASTParseDriver.ADAPTOR.create(HiveASTParser.EQUAL, "=");
                HiveASTParseDriver.ADAPTOR.addChild(equal, left);
                HiveASTParseDriver.ADAPTOR.addChild(equal, right);
                HiveASTParseDriver.ADAPTOR.addChild(and, equal);
                count++;
            }
            joinCondAst = count > 1 ? and : equal;
        } else if (semanticAnalyzer.unparseTranslator != null && semanticAnalyzer.unparseTranslator.isEnabled()) {
            semanticAnalyzer.genAllExprNodeDesc(joinCondAst, combinedRR, jCtx);
        }
        Map<HiveParserASTNode, ExprNodeDesc> exprNodes = HiveParserUtils.genExprNode(joinCondAst, jCtx);
        if (jCtx.getError() != null) {
            throw new SemanticException(generateErrorMessage(jCtx.getErrorSrcNode(), jCtx.getError()));
        }
        ExprNodeDesc joinCondExprNode = exprNodes.get(joinCondAst);
        List<RelNode> inputRels = new ArrayList<>();
        inputRels.add(leftRel);
        inputRels.add(rightRel);
        joinCondRex = HiveParserRexNodeConverter.convert(cluster, joinCondExprNode, inputRels, relToRowResolver, relToHiveColNameCalcitePosMap, false, funcConverter).accept(funcConverter);
    } else {
        joinCondRex = cluster.getRexBuilder().makeLiteral(true);
    }
    // 3. Construct Join Rel Node and HiveParserRowResolver for the new Join Node
    boolean leftSemiJoin = false;
    JoinRelType calciteJoinType;
    switch(hiveJoinType) {
        case LEFTOUTER:
            calciteJoinType = JoinRelType.LEFT;
            break;
        case RIGHTOUTER:
            calciteJoinType = JoinRelType.RIGHT;
            break;
        case FULLOUTER:
            calciteJoinType = JoinRelType.FULL;
            break;
        case LEFTSEMI:
            calciteJoinType = JoinRelType.SEMI;
            leftSemiJoin = true;
            break;
        case INNER:
        default:
            calciteJoinType = JoinRelType.INNER;
            break;
    }
    RelNode topRel;
    HiveParserRowResolver topRR;
    if (leftSemiJoin) {
        List<RelDataTypeField> sysFieldList = new ArrayList<>();
        List<RexNode> leftJoinKeys = new ArrayList<>();
        List<RexNode> rightJoinKeys = new ArrayList<>();
        RexNode nonEquiConds = RelOptUtil.splitJoinCondition(sysFieldList, leftRel, rightRel, joinCondRex, leftJoinKeys, rightJoinKeys, null, null);
        if (!nonEquiConds.isAlwaysTrue()) {
            throw new SemanticException("Non equality condition not supported in Semi-Join" + nonEquiConds);
        }
        RelNode[] inputRels = new RelNode[] { leftRel, rightRel };
        final List<Integer> leftKeys = new ArrayList<>();
        final List<Integer> rightKeys = new ArrayList<>();
        joinCondRex = HiveParserUtils.projectNonColumnEquiConditions(RelFactories.DEFAULT_PROJECT_FACTORY, inputRels, leftJoinKeys, rightJoinKeys, 0, leftKeys, rightKeys);
        topRel = LogicalJoin.create(inputRels[0], inputRels[1], Collections.emptyList(), joinCondRex, Collections.emptySet(), calciteJoinType);
        // previous call to projectNonColumnEquiConditions updated it
        if (inputRels[0] != leftRel) {
            HiveParserRowResolver newLeftRR = new HiveParserRowResolver();
            if (!HiveParserRowResolver.add(newLeftRR, leftRR)) {
                LOG.warn("Duplicates detected when adding columns to RR: see previous message");
            }
            for (int i = leftRel.getRowType().getFieldCount(); i < inputRels[0].getRowType().getFieldCount(); i++) {
                ColumnInfo oColInfo = new ColumnInfo(getColumnInternalName(i), HiveParserTypeConverter.convert(inputRels[0].getRowType().getFieldList().get(i).getType()), null, false);
                newLeftRR.put(oColInfo.getTabAlias(), oColInfo.getInternalName(), oColInfo);
            }
            HiveParserRowResolver joinRR = new HiveParserRowResolver();
            if (!HiveParserRowResolver.add(joinRR, newLeftRR)) {
                LOG.warn("Duplicates detected when adding columns to RR: see previous message");
            }
            relToHiveColNameCalcitePosMap.put(topRel, buildHiveToCalciteColumnMap(joinRR));
            relToRowResolver.put(topRel, joinRR);
            // Introduce top project operator to remove additional column(s) that have been
            // introduced
            List<RexNode> topFields = new ArrayList<>();
            List<String> topFieldNames = new ArrayList<>();
            for (int i = 0; i < leftRel.getRowType().getFieldCount(); i++) {
                final RelDataTypeField field = leftRel.getRowType().getFieldList().get(i);
                topFields.add(leftRel.getCluster().getRexBuilder().makeInputRef(field.getType(), i));
                topFieldNames.add(field.getName());
            }
            topRel = LogicalProject.create(topRel, Collections.emptyList(), topFields, topFieldNames);
        }
        topRR = new HiveParserRowResolver();
        if (!HiveParserRowResolver.add(topRR, leftRR)) {
            LOG.warn("Duplicates detected when adding columns to RR: see previous message");
        }
    } else {
        topRel = LogicalJoin.create(leftRel, rightRel, Collections.emptyList(), joinCondRex, Collections.emptySet(), calciteJoinType);
        topRR = HiveParserRowResolver.getCombinedRR(leftRR, rightRR);
        if (namedColumns != null) {
            List<String> tableAliases = new ArrayList<>();
            tableAliases.add(leftTableAlias);
            tableAliases.add(rightTableAlias);
            topRR.setNamedJoinInfo(new HiveParserNamedJoinInfo(tableAliases, namedColumns, hiveJoinType));
        }
    }
    relToHiveColNameCalcitePosMap.put(topRel, buildHiveToCalciteColumnMap(topRR));
    relToRowResolver.put(topRel, topRR);
    return topRel;
}
Also used : HiveParserJoinTypeCheckCtx(org.apache.flink.table.planner.delegation.hive.copy.HiveParserJoinTypeCheckCtx) HiveParserNamedJoinInfo(org.apache.flink.table.planner.delegation.hive.copy.HiveParserNamedJoinInfo) HiveParserASTNode(org.apache.flink.table.planner.delegation.hive.copy.HiveParserASTNode) Node(org.apache.hadoop.hive.ql.lib.Node) RexNode(org.apache.calcite.rex.RexNode) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) ColumnInfo(org.apache.hadoop.hive.ql.exec.ColumnInfo) HiveParserRowResolver(org.apache.flink.table.planner.delegation.hive.copy.HiveParserRowResolver) ExprNodeDesc(org.apache.hadoop.hive.ql.plan.ExprNodeDesc) SemanticException(org.apache.hadoop.hive.ql.parse.SemanticException) HiveParserASTNode(org.apache.flink.table.planner.delegation.hive.copy.HiveParserASTNode) JoinRelType(org.apache.calcite.rel.core.JoinRelType) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

ArrayList (java.util.ArrayList)1 RelNode (org.apache.calcite.rel.RelNode)1 JoinRelType (org.apache.calcite.rel.core.JoinRelType)1 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)1 RexNode (org.apache.calcite.rex.RexNode)1 HiveParserASTNode (org.apache.flink.table.planner.delegation.hive.copy.HiveParserASTNode)1 HiveParserJoinTypeCheckCtx (org.apache.flink.table.planner.delegation.hive.copy.HiveParserJoinTypeCheckCtx)1 HiveParserNamedJoinInfo (org.apache.flink.table.planner.delegation.hive.copy.HiveParserNamedJoinInfo)1 HiveParserRowResolver (org.apache.flink.table.planner.delegation.hive.copy.HiveParserRowResolver)1 ColumnInfo (org.apache.hadoop.hive.ql.exec.ColumnInfo)1 Node (org.apache.hadoop.hive.ql.lib.Node)1 SemanticException (org.apache.hadoop.hive.ql.parse.SemanticException)1 ExprNodeDesc (org.apache.hadoop.hive.ql.plan.ExprNodeDesc)1