Examples of HiveUnionRel


Examples of org.apache.hadoop.hive.ql.optimizer.optiq.reloperators.HiveUnionRel

    }

    @SuppressWarnings("nls")
    private RelNode genUnionLogicalPlan(String unionalias, String leftalias, RelNode leftRel,
        String rightalias, RelNode rightRel) throws SemanticException {
      HiveUnionRel unionRel = null;

      // 1. Get Row Resolvers, Column map for original left and right input of
      // Union Rel
      RowResolver leftRR = this.relToHiveRR.get(leftRel);
      RowResolver rightRR = this.relToHiveRR.get(rightRel);
      HashMap<String, ColumnInfo> leftmap = leftRR.getFieldMap(leftalias);
      HashMap<String, ColumnInfo> rightmap = rightRR.getFieldMap(rightalias);

      // 2. Validate that Union is feasible according to Hive (by using type
      // info from RR)
      if (leftmap.size() != rightmap.size()) {
        throw new SemanticException("Schema of both sides of union should match.");
      }

      ASTNode tabref = qb.getAliases().isEmpty() ? null : qb.getParseInfo().getSrcForAlias(
          qb.getAliases().get(0));
      for (Map.Entry<String, ColumnInfo> lEntry : leftmap.entrySet()) {
        String field = lEntry.getKey();
        ColumnInfo lInfo = lEntry.getValue();
        ColumnInfo rInfo = rightmap.get(field);
        if (rInfo == null) {
          throw new SemanticException(generateErrorMessage(tabref,
              "Schema of both sides of union should match. " + rightalias
                  + " does not have the field " + field));
        }
        if (lInfo == null) {
          throw new SemanticException(generateErrorMessage(tabref,
              "Schema of both sides of union should match. " + leftalias
                  + " does not have the field " + field));
        }
        if (!lInfo.getInternalName().equals(rInfo.getInternalName())) {
          throw new OptiqSemanticException(generateErrorMessage(tabref,
              "Schema of both sides of union should match: field " + field + ":"
                  + " appears on the left side of the UNION at column position: "
                  + getPositionFromInternalName(lInfo.getInternalName())
                  + ", and on the right side of the UNION at column position: "
                  + getPositionFromInternalName(rInfo.getInternalName())
                  + ". Column positions should match for a UNION"));
        }
        // try widening coversion, otherwise fail union
        TypeInfo commonTypeInfo = FunctionRegistry.getCommonClassForUnionAll(lInfo.getType(),
            rInfo.getType());
        if (commonTypeInfo == null) {
          throw new OptiqSemanticException(generateErrorMessage(tabref,
              "Schema of both sides of union should match: Column " + field + " is of type "
                  + lInfo.getType().getTypeName() + " on first table and type "
                  + rInfo.getType().getTypeName() + " on second table"));
        }
      }

      // 3. construct Union Output RR using original left & right Input
      RowResolver unionoutRR = new RowResolver();
      for (Map.Entry<String, ColumnInfo> lEntry : leftmap.entrySet()) {
        String field = lEntry.getKey();
        ColumnInfo lInfo = lEntry.getValue();
        ColumnInfo rInfo = rightmap.get(field);
        ColumnInfo unionColInfo = new ColumnInfo(lInfo);
        unionColInfo.setTabAlias(unionalias);
        unionColInfo.setType(FunctionRegistry.getCommonClassForUnionAll(lInfo.getType(),
            rInfo.getType()));
        unionoutRR.put(unionalias, field, unionColInfo);
      }

      // 4. Determine which columns requires cast on left/right input (Optiq
      // requires exact types on both sides of union)
      boolean leftNeedsTypeCast = false;
      boolean rightNeedsTypeCast = false;
      List<RexNode> leftProjs = new ArrayList<RexNode>();
      List<RexNode> rightProjs = new ArrayList<RexNode>();
      List<RelDataTypeField> leftRowDT = leftRel.getRowType().getFieldList();
      List<RelDataTypeField> rightRowDT = rightRel.getRowType().getFieldList();

      RelDataType leftFieldDT;
      RelDataType rightFieldDT;
      RelDataType unionFieldDT;
      for (int i = 0; i < leftRowDT.size(); i++) {
        leftFieldDT = leftRowDT.get(i).getType();
        rightFieldDT = rightRowDT.get(i).getType();
        if (!leftFieldDT.equals(rightFieldDT)) {
          unionFieldDT = TypeConverter.convert(unionoutRR.getColumnInfos().get(i).getType(),
          cluster.getTypeFactory());
          if (!unionFieldDT.equals(leftFieldDT)) {
            leftNeedsTypeCast = true;
          }
          leftProjs.add(cluster.getRexBuilder().ensureType(unionFieldDT,
              cluster.getRexBuilder().makeInputRef(leftFieldDT, i), true));

          if (!unionFieldDT.equals(rightFieldDT)) {
            rightNeedsTypeCast = true;
          }
          rightProjs.add(cluster.getRexBuilder().ensureType(unionFieldDT,
              cluster.getRexBuilder().makeInputRef(rightFieldDT, i), true));
        } else {
          leftProjs.add(cluster.getRexBuilder().ensureType(leftFieldDT,
              cluster.getRexBuilder().makeInputRef(leftFieldDT, i), true));
          rightProjs.add(cluster.getRexBuilder().ensureType(rightFieldDT,
              cluster.getRexBuilder().makeInputRef(rightFieldDT, i), true));
        }
      }

      // 5. Introduce Project Rel above original left/right inputs if cast is
      // needed for type parity
      RelNode unionLeftInput = leftRel;
      RelNode unionRightInput = rightRel;
      if (leftNeedsTypeCast) {
        unionLeftInput = HiveProjectRel.create(leftRel, leftProjs, leftRel.getRowType()
            .getFieldNames());
      }
      if (rightNeedsTypeCast) {
        unionRightInput = HiveProjectRel.create(rightRel, rightProjs, rightRel.getRowType()
            .getFieldNames());
      }

      // 6. Construct Union Rel
      ImmutableList.Builder bldr = new ImmutableList.Builder<RelNode>();
      bldr.add(unionLeftInput);
      bldr.add(unionRightInput);
      unionRel = new HiveUnionRel(cluster, TraitsUtil.getDefaultTraitSet(cluster),
          bldr.build());

      relToHiveRR.put(unionRel, unionoutRR);
      relToHiveColNameOptiqPosMap.put(unionRel,
          this.buildHiveToOptiqColumnMap(unionoutRR, unionRel));
View Full Code Here
TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.