private ImmutablePair<Boolean, Boolean> validateInputFormatAndSchemaEvolution(MapWork mapWork, String alias,
        TableScanOperator tableScanOperator, VectorTaskColumnInfo vectorTaskColumnInfo)
            throws SemanticException {

      boolean isFullAcidTable = tableScanOperator.getConf().isFullAcidTable();

      // These names/types are the data columns plus partition columns.
      final List<String> allColumnNameList = new ArrayList<String>();
      final List<TypeInfo> allTypeInfoList = new ArrayList<TypeInfo>();

      final List<VirtualColumn> availableVirtualColumnList = new ArrayList<VirtualColumn>();

      getTableScanOperatorSchemaInfo(
          tableScanOperator,
          allColumnNameList, allTypeInfoList,
          availableVirtualColumnList);
      final int virtualColumnCount = availableVirtualColumnList.size();

      final List<Integer> dataColumnNums = new ArrayList<Integer>();

      final int dataAndPartColumnCount = allColumnNameList.size() - virtualColumnCount;

      /*
       * Validate input formats of all the partitions can be vectorized.
       */
      boolean isFirst = true;
      int dataColumnCount = 0;
      int partitionColumnCount = 0;

      List<String> tableDataColumnList = null;
      List<TypeInfo> tableDataTypeInfoList = null;

      Map<Path, List<String>> pathToAliases = mapWork.getPathToAliases();
      Map<Path, PartitionDesc> pathToPartitionInfo = mapWork.getPathToPartitionInfo();

      // Remember the input file formats we validated and why.
      Set<String> inputFileFormatClassNameSet = new HashSet<String>();
      Map<VectorPartitionDesc, VectorPartitionDesc> vectorPartitionDescMap =
          new LinkedHashMap<VectorPartitionDesc, VectorPartitionDesc>();
      Set<String> enabledConditionsMetSet = new HashSet<String>();
      List<String> enabledConditionsNotMetList = new ArrayList<String>();
      Set<Support> inputFormatSupportSet = new TreeSet<Support>();
      boolean outsideLoopIsFirstPartition = true;

      for (Entry<Path, List<String>> entry: pathToAliases.entrySet()) {
        final boolean isFirstPartition = outsideLoopIsFirstPartition;
        outsideLoopIsFirstPartition = false;

        Path path = entry.getKey();
        List<String> aliases = entry.getValue();
        boolean isPresent = (aliases != null && aliases.indexOf(alias) != -1);
        if (!isPresent) {
          setOperatorIssue("Alias " + alias + " not present in aliases " + aliases);
          return new ImmutablePair<Boolean,Boolean>(false, false);
        }
        // TODO: should this use getPartitionDescFromPathRecursively? That's what other code uses.
        PartitionDesc partDesc = pathToPartitionInfo.get(path);
        if (partDesc.getVectorPartitionDesc() != null) {
          // We've seen this already.
          continue;
        }
        Set<Support> newSupportSet = new TreeSet<Support>();

        final List<TypeInfo> nextDataTypeInfoList;
        final Deserializer deserializer;
        final StructObjectInspector partObjectInspector;
        try {
          deserializer = partDesc.getDeserializer(hiveConf);
          partObjectInspector = (StructObjectInspector) deserializer.getObjectInspector();
        } catch (Exception e) {
          throw new SemanticException(e);
        }

        if (isFirst) {

          /*
           * Determine the data and partition columns using the first partition descriptor's
           * partition count.  In other words, how to split the schema columns -- the
           * allColumnNameList and allTypeInfoList variables -- into the data and partition columns.
           */

          LinkedHashMap<String, String> partSpec = partDesc.getPartSpec();
          if (partSpec != null && partSpec.size() > 0) {
            partitionColumnCount = partSpec.size();
            dataColumnCount = dataAndPartColumnCount - partitionColumnCount;
          } else {
            partitionColumnCount = 0;
            dataColumnCount = dataAndPartColumnCount;
          }

          determineDataColumnNums(tableScanOperator, allColumnNameList, dataColumnCount,
              dataColumnNums);

          tableDataColumnList = allColumnNameList.subList(0, dataColumnCount);
          tableDataTypeInfoList = allTypeInfoList.subList(0, dataColumnCount);

          isFirst = false;
        }

        if (Utilities.isInputFileFormatSelfDescribing(partDesc)) {

          /*
           * Self-Describing Input Format will convert its data to the table schema. So, there
           * will be no VectorMapOperator conversion needed.
           */
          nextDataTypeInfoList = tableDataTypeInfoList;
        } else {
          String nextDataTypesString = ObjectInspectorUtils.getFieldTypes(partObjectInspector);

          /*
           * We convert to an array of TypeInfo using a library routine since it parses the
           * information and can handle use of different separators, etc.  We cannot use the
           * raw type string for comparison in the map because of the different separators used.
           */
          nextDataTypeInfoList =
              TypeInfoUtils.getTypeInfosFromTypeString(nextDataTypesString);
        }

        // HIVE-20419: Vectorization: Prevent mutation of VectorPartitionDesc after being used in a
        // hashmap key
        final boolean isVerifiedVectorPartDesc =
            verifyAndSetVectorPartDesc(
              partDesc, isFullAcidTable,
              allTypeInfoList,
              inputFileFormatClassNameSet,
              vectorPartitionDescMap,
              enabledConditionsMetSet, enabledConditionsNotMetList,
              newSupportSet,
              nextDataTypeInfoList);

        final VectorPartitionDesc vectorPartDesc = partDesc.getVectorPartitionDesc();

        if (!isVerifiedVectorPartDesc) {

          // Always set these so EXPLAIN can see.
          setValidateInputFormatAndSchemaEvolutionExplain(
              mapWork, inputFileFormatClassNameSet, vectorPartitionDescMap,
              enabledConditionsMetSet, enabledConditionsNotMetList);

          // We consider this an enable issue, not a not vectorized issue.
          return new ImmutablePair<Boolean,Boolean>(false, true);
        }

        handleSupport(isFirstPartition, inputFormatSupportSet, newSupportSet);

        // We need to get the partition's column names from the partition serde.
        // (e.g. Avro provides the table schema and ignores the partition schema..).
        //
        String nextDataColumnsString = ObjectInspectorUtils.getFieldNames(partObjectInspector);
        String[] nextDataColumns = StringUtils.isBlank(nextDataColumnsString) ?
            new String[0] : nextDataColumnsString.split(",");
        List<String> nextDataColumnList = Arrays.asList(nextDataColumns);

        /*
         * Validate the column names that are present are the same.  Missing columns will be
         * implicitly defaulted to null.
         */
        if (nextDataColumnList.size() > tableDataColumnList.size()) {
          enabledConditionsNotMetList.add(
              String.format(
                  "Could not enable vectorization due to " +
                  "partition column names size %d is greater than the number of table column names size %d",
                  nextDataColumnList.size(), tableDataColumnList.size()));

          // Always set these so EXPLAIN can see.
          setValidateInputFormatAndSchemaEvolutionExplain(
              mapWork, inputFileFormatClassNameSet, vectorPartitionDescMap,
              enabledConditionsMetSet, enabledConditionsNotMetList);
          return new ImmutablePair<Boolean,Boolean>(false, true);
        }
        if (!(deserializer instanceof NullStructSerDe)) {

          // (Don't insist NullStructSerDe produce correct column names).
          for (int i = 0; i < nextDataColumnList.size(); i++) {
            String nextColumnName = nextDataColumnList.get(i);
            String tableColumnName = tableDataColumnList.get(i);
            if (!nextColumnName.equals(tableColumnName)) {
              enabledConditionsNotMetList.add(
                  String.format(
                      "Could not enable vectorization due to " +
                      "partition column name %s does not match table column name %s",
                      nextColumnName, tableColumnName));

              // Always set these so EXPLAIN can see.
              setValidateInputFormatAndSchemaEvolutionExplain(
                  mapWork, inputFileFormatClassNameSet, vectorPartitionDescMap,
                  enabledConditionsMetSet, enabledConditionsNotMetList);
              return new ImmutablePair<Boolean,Boolean>(false, true);
            }
          }
        }

        boolean isPartitionRowConversion = false;

        if (!vectorPartDesc.getIsInputFileFormatSelfDescribing()) {
          final int nextDataTypeInfoSize = nextDataTypeInfoList.size();
          if (nextDataTypeInfoSize > tableDataTypeInfoList.size()) {
            enabledConditionsNotMetList.add(
                String.format(
                    "Could not enable vectorization due to " +
                    "partition column types size %d is greater than the number of table column types size %d",
                    nextDataTypeInfoSize, tableDataTypeInfoList.size()));

            // Always set these so EXPLAIN can see.
            setValidateInputFormatAndSchemaEvolutionExplain(
                mapWork, inputFileFormatClassNameSet, vectorPartitionDescMap,
                enabledConditionsMetSet, enabledConditionsNotMetList);
            return new ImmutablePair<Boolean,Boolean>(false, true);
          }
          for (int i = 0; i < nextDataTypeInfoSize; i++) {
            TypeInfo tableDataTypeInfo = tableDataTypeInfoList.get(i);
            TypeInfo nextDataTypeInfo = nextDataTypeInfoList.get(i);

            // FUTURE: We be more sophisticated in our conversion check.
            if (!tableDataTypeInfo.equals(nextDataTypeInfo)) {
              isPartitionRowConversion = true;
              break;
            }
          }
        }
        if (isPartitionRowConversion && isLlapIoEnabled) {
          enabledConditionsNotMetList.add(
              "Could not enable vectorization. " +
              "LLAP I/O is enabled which automatically deserializes into " +
              "VECTORIZED_INPUT_FILE_FORMAT. " +
              "A partition requires data type conversion and that is not supported");

          // Always set these so EXPLAIN can see.
          setValidateInputFormatAndSchemaEvolutionExplain(
              mapWork, inputFileFormatClassNameSet, vectorPartitionDescMap,
              enabledConditionsMetSet, enabledConditionsNotMetList);
          return new ImmutablePair<Boolean,Boolean>(false, true);
        }
      }

      // For now, we don't know which virtual columns are going to be included.  We'll add them
      // later...
      vectorTaskColumnInfo.setAllColumnNames(allColumnNameList);
      vectorTaskColumnInfo.setAllTypeInfos(allTypeInfoList);

      vectorTaskColumnInfo.setDataColumnNums(dataColumnNums);
      vectorTaskColumnInfo.setPartitionColumnCount(partitionColumnCount);
      vectorTaskColumnInfo.setAvailableVirtualColumnList(availableVirtualColumnList);
      vectorTaskColumnInfo.setUseVectorizedInputFileFormat(
          shouldUseVectorizedInputFormat(inputFileFormatClassNameSet));

      vectorTaskColumnInfo.setInputFormatSupportSet(inputFormatSupportSet);

      // Always set these so EXPLAIN can see.
      mapWork.setVectorizationInputFileFormatClassNameSet(inputFileFormatClassNameSet);
      ArrayList<VectorPartitionDesc> vectorPartitionDescList = new ArrayList<VectorPartitionDesc>();
      vectorPartitionDescList.addAll(vectorPartitionDescMap.keySet());
      mapWork.setVectorPartitionDescList(vectorPartitionDescList);
      mapWork.setVectorizationEnabledConditionsMet(enabledConditionsMetSet);
      mapWork.setVectorizationEnabledConditionsNotMet(enabledConditionsNotMetList);

      return new ImmutablePair<Boolean,Boolean>(true, false);
    }
Decimal types can be specified with different precision and scales e.g. decimal(10,5),
as opposed to other data types which can be represented by constant strings.
The regex matches only the {@link serdeConstants#DECIMAL_TYPE_NAME} prefix of the type.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/Vectorizer.java