public Operator validateAndVectorizeOperator()

in ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/Vectorizer.java [5229:5512]


  public Operator<? extends OperatorDesc> validateAndVectorizeOperator(Operator<? extends OperatorDesc> op,
      VectorizationContext vContext, boolean isReduce, boolean isTez,
      VectorTaskColumnInfo vectorTaskColumnInfo)
          throws HiveException, VectorizerCannotVectorizeException {
    Operator<? extends OperatorDesc> vectorOp = null;

    // This "global" allows various validation methods to set the "not vectorized" reason.
    currentOperator = op;

    boolean isNative = false;
    try {
      switch (op.getType()) {
        case MAPJOIN:
          {
            if (op instanceof MapJoinOperator) {
              if (!validateMapJoinOperator((MapJoinOperator) op)) {
                throw new VectorizerCannotVectorizeException();
              }
            } else if (op instanceof SMBMapJoinOperator) {
              if (!validateSMBMapJoinOperator((SMBMapJoinOperator) op)) {
                throw new VectorizerCannotVectorizeException();
              }
            } else {
              setOperatorNotSupported(op);
              throw new VectorizerCannotVectorizeException();
            }

            if (op instanceof MapJoinOperator) {

              MapJoinDesc desc = (MapJoinDesc) op.getConf();
              int joinType = desc.getConds()[0].getType();

              VectorMapJoinDesc vectorMapJoinDesc = new VectorMapJoinDesc();
              boolean specialize =
                  canSpecializeMapJoin(op, desc, isTez, vContext, vectorMapJoinDesc);

              if (!specialize) {

                Class<? extends Operator<?>> opClass = null;

                // *NON-NATIVE* vector map differences for LEFT OUTER JOIN and Filtered...

                List<ExprNodeDesc> bigTableFilters = desc.getFilters().get((byte) desc.getPosBigTable());
                boolean isOuterAndFiltered = (!desc.isNoOuterJoin() && bigTableFilters.size() > 0);
                if (!isOuterAndFiltered) {
                  opClass = VectorMapJoinOperator.class;
                } else {
                  if (joinType == JoinDesc.FULL_OUTER_JOIN) {
                    setOperatorIssue("Vectorized & filtered full-outer joins not supported");
                    throw new VectorizerCannotVectorizeException();
                  }
                  opClass = VectorMapJoinOuterFilteredOperator.class;
                }

                vectorOp = OperatorFactory.getVectorOperator(
                    opClass, op.getCompilationOpContext(), desc,
                    vContext, vectorMapJoinDesc);
              } else {

                // TEMPORARY Until Native Vector Map Join with Hybrid passes tests...
                // HiveConf.setBoolVar(physicalContext.getConf(),
                //    HiveConf.ConfVars.HIVE_USE_HYBRIDGRACE_HASHJOIN, false);

                vectorOp = specializeMapJoinOperator(op, vContext, desc, vectorMapJoinDesc);
                isNative = true;

                if (vectorTaskColumnInfo != null) {
                  if (usesVectorUDFAdaptor(vectorMapJoinDesc.getAllBigTableKeyExpressions())) {
                    vectorTaskColumnInfo.setUsesVectorUDFAdaptor(true);
                  }
                  if (usesVectorUDFAdaptor(vectorMapJoinDesc.getAllBigTableValueExpressions())) {
                    vectorTaskColumnInfo.setUsesVectorUDFAdaptor(true);
                  }
                }
              }
            } else {
              Preconditions.checkState(op instanceof SMBMapJoinOperator);

              SMBJoinDesc smbJoinSinkDesc = (SMBJoinDesc) op.getConf();

              // Check additional constraint.
              if (smbJoinSinkDesc.getFilterMap() != null) {
                setOperatorIssue("FilterMaps not supported for Vector Pass-Thru SMB MapJoin");
                throw new VectorizerCannotVectorizeException();
              }

              VectorSMBJoinDesc vectorSMBJoinDesc = new VectorSMBJoinDesc();
              vectorOp = OperatorFactory.getVectorOperator(
                  op.getCompilationOpContext(), smbJoinSinkDesc, vContext, vectorSMBJoinDesc);
              isNative = false;
            }
          }
          break;

        case REDUCESINK:
          {
            if (!validateReduceSinkOperator((ReduceSinkOperator) op)) {
              throw new VectorizerCannotVectorizeException();
            }

            ReduceSinkDesc reduceDesc = (ReduceSinkDesc) op.getConf();

            VectorReduceSinkDesc vectorReduceSinkDesc = new VectorReduceSinkDesc();
            boolean specialize =
                canSpecializeReduceSink(reduceDesc, isTez, vContext, vectorReduceSinkDesc);

            if (!specialize) {

              vectorOp = OperatorFactory.getVectorOperator(
                  op.getCompilationOpContext(), reduceDesc, vContext, vectorReduceSinkDesc);
              isNative = false;
            } else {

              vectorOp = specializeReduceSinkOperator(op, vContext, reduceDesc, vectorReduceSinkDesc);
              isNative = true;

              if (vectorTaskColumnInfo != null) {
                VectorReduceSinkInfo vectorReduceSinkInfo = vectorReduceSinkDesc.getVectorReduceSinkInfo();
                if (usesVectorUDFAdaptor(vectorReduceSinkInfo.getReduceSinkKeyExpressions())) {
                  vectorTaskColumnInfo.setUsesVectorUDFAdaptor(true);
                }
                if (usesVectorUDFAdaptor(vectorReduceSinkInfo.getReduceSinkValueExpressions())) {
                  vectorTaskColumnInfo.setUsesVectorUDFAdaptor(true);
                }
              }
            }
          }
          break;
        case FILTER:
          {
            if (!validateFilterOperator((FilterOperator) op)) {
              throw new VectorizerCannotVectorizeException();
            }

            VectorFilterDesc vectorFilterDesc = new VectorFilterDesc();
            vectorOp = vectorizeFilterOperator(op, vContext, vectorFilterDesc);
            isNative = true;
            if (vectorTaskColumnInfo != null) {
              VectorExpression vectorPredicateExpr = vectorFilterDesc.getPredicateExpression();
              if (usesVectorUDFAdaptor(vectorPredicateExpr)) {
                vectorTaskColumnInfo.setUsesVectorUDFAdaptor(true);
              }
            }
          }
          break;
        case TOPNKEY:
          {
            if (!validateTopNKeyOperator((TopNKeyOperator) op)) {
              throw new VectorizerCannotVectorizeException();
            }

            VectorTopNKeyDesc vectorTopNKeyDesc = new VectorTopNKeyDesc();
            vectorOp = vectorizeTopNKeyOperator(op, vContext, vectorTopNKeyDesc);
            isNative = true;
            if (vectorTaskColumnInfo != null) {
              VectorExpression[] keyExpressions = vectorTopNKeyDesc.getKeyExpressions();
              if (usesVectorUDFAdaptor(keyExpressions)) {
                vectorTaskColumnInfo.setUsesVectorUDFAdaptor(true);
              }
            }
          }
          break;
        case SELECT:
          {
            if (!validateSelectOperator((SelectOperator) op)) {
              throw new VectorizerCannotVectorizeException();
            }

            VectorSelectDesc vectorSelectDesc = new VectorSelectDesc();
            vectorOp = vectorizeSelectOperator(op, vContext, vectorSelectDesc);
            isNative = true;
            if (vectorTaskColumnInfo != null) {
              VectorExpression[] vectorSelectExprs = vectorSelectDesc.getSelectExpressions();
              if (usesVectorUDFAdaptor(vectorSelectExprs)) {
                vectorTaskColumnInfo.setUsesVectorUDFAdaptor(true);
              }
            }
          }
          break;
        case GROUPBY:
          {
            // The validateGroupByOperator method will update vectorGroupByDesc.
            VectorGroupByDesc vectorGroupByDesc = new VectorGroupByDesc();
            if (!validateGroupByOperator((GroupByOperator) op, isReduce, isTez,
                vectorGroupByDesc)) {
              throw new VectorizerCannotVectorizeException();
            }

            ImmutablePair<Operator<? extends OperatorDesc>,String> pair =
                doVectorizeGroupByOperator(op, vContext, vectorGroupByDesc);
            if (pair.left == null) {
              setOperatorIssue(pair.right);
              throw new VectorizerCannotVectorizeException();
            }
            vectorOp = pair.left;
            isNative = false;
            if (vectorTaskColumnInfo != null) {
              VectorExpression[] vecKeyExpressions = vectorGroupByDesc.getKeyExpressions();
              if (usesVectorUDFAdaptor(vecKeyExpressions)) {
                vectorTaskColumnInfo.setUsesVectorUDFAdaptor(true);
              }
              VectorAggregationDesc[] vecAggrDescs = vectorGroupByDesc.getVecAggrDescs();
              for (VectorAggregationDesc vecAggrDesc : vecAggrDescs) {
                if (usesVectorUDFAdaptor(vecAggrDesc.getInputExpression())) {
                  vectorTaskColumnInfo.setUsesVectorUDFAdaptor(true);
                }
              }
            }

          }
          break;
        case FILESINK:
          {
            if (!validateFileSinkOperator((FileSinkOperator) op)) {
              throw new VectorizerCannotVectorizeException();
            }

            FileSinkDesc fileSinkDesc = (FileSinkDesc) op.getConf();

            VectorFileSinkDesc vectorFileSinkDesc = new VectorFileSinkDesc();

            vectorOp =
                OperatorFactory.getVectorOperator(
                    op.getCompilationOpContext(), fileSinkDesc, vContext, vectorFileSinkDesc);
            isNative = false;
          }
          break;
        case LIMIT:
          {
            // No validation.

            LimitDesc limitDesc = (LimitDesc) op.getConf();

            VectorLimitDesc vectorLimitDesc = new VectorLimitDesc();
            vectorOp = OperatorFactory.getVectorOperator(
                op.getCompilationOpContext(), limitDesc, vContext, vectorLimitDesc);
            isNative = true;
          }
          break;
        case EVENT:
          {
            // No validation.

            AppMasterEventDesc eventDesc = (AppMasterEventDesc) op.getConf();

            VectorAppMasterEventDesc vectorEventDesc = new VectorAppMasterEventDesc();
            vectorOp = OperatorFactory.getVectorOperator(
                op.getCompilationOpContext(), eventDesc, vContext, vectorEventDesc);
            isNative = true;
          }
          break;
        case PTF:
          {
            // The validatePTFOperator method will update vectorPTFDesc.
            VectorPTFDesc vectorPTFDesc = new VectorPTFDesc();
            if (!validatePTFOperator((PTFOperator) op, vContext, vectorPTFDesc)) {
              throw new VectorizerCannotVectorizeException();
            }

            vectorOp = vectorizePTFOperator(op, vContext, vectorPTFDesc);
            isNative = true;
          }
          break;
        default:
          setOperatorNotSupported(op);
          throw new VectorizerCannotVectorizeException();
      }
    } catch (HiveException e) {
      setOperatorIssue(e.getMessage());
      throw new VectorizerCannotVectorizeException();
    }

    Preconditions.checkState(vectorOp != null);
    if (vectorTaskColumnInfo != null && !isNative) {
      vectorTaskColumnInfo.setAllNative(false);
    }

    LOG.debug("vectorizeOperator " + vectorOp.getClass().getName());
    LOG.debug("vectorizeOperator " + vectorOp.getConf().getClass().getName());
    // These operators need to be linked to enable runtime statistics to be gathered/used correctly
    planMapper.link(op, vectorOp);

    return vectorOp;
  }