private boolean doReadField()

in serde/src/java/org/apache/hadoop/hive/serde2/lazy/fast/LazySimpleDeserializeRead.java [647:905]


  private boolean doReadField(Field field) {
    final int fieldStart = currentFieldStart;
    final int fieldLength = currentFieldLength;
    if (fieldLength < 0) {
      return false;
    }

    final byte[] bytes = this.bytes;

    // Is the field the configured string representing NULL?
    if (nullSequenceBytes != null) {
      if (checkNull(bytes, fieldStart, fieldLength)) {
        return false;
      }
    }

    try {
      /*
       * We have a field and are positioned to it.  Read it.
       */
      if (field.isPrimitive) {
        switch (field.primitiveCategory) {
        case BOOLEAN:
          {
            int i = fieldStart;
            if (fieldLength == 4) {
              if ((bytes[i] == 'T' || bytes[i] == 't') &&
                  (bytes[i + 1] == 'R' || bytes[i + 1] == 'r') &&
                  (bytes[i + 2] == 'U' || bytes[i + 2] == 'u') &&
                  (bytes[i + 3] == 'E' || bytes[i + 3] == 'e')) {
                currentBoolean = true;
              } else {
                // No boolean value match for 4 char field.
                return false;
              }
            } else if (fieldLength == 5) {
              if ((bytes[i] == 'F' || bytes[i] == 'f') &&
                  (bytes[i + 1] == 'A' || bytes[i + 1] == 'a') &&
                  (bytes[i + 2] == 'L' || bytes[i + 2] == 'l') &&
                  (bytes[i + 3] == 'S' || bytes[i + 3] == 's') &&
                  (bytes[i + 4] == 'E' || bytes[i + 4] == 'e')) {
                currentBoolean = false;
              } else {
                // No boolean value match for 5 char field.
                return false;
              }
            } else if (isExtendedBooleanLiteral && fieldLength == 1) {
              byte b = bytes[fieldStart];
              if (b == '1' || b == 't' || b == 'T') {
                currentBoolean = true;
              } else if (b == '0' || b == 'f' || b == 'F') {
                currentBoolean = false;
              } else {
                // No boolean value match for extended 1 char field.
                return false;
              }
            } else {
              // No boolean value match for other lengths.
              return false;
            }
          }
          return true;
        case BYTE:
          if (!LazyUtils.isNumberMaybe(bytes, fieldStart, fieldLength)) {
            return false;
          }
          currentByte = LazyByte.parseByte(bytes, fieldStart, fieldLength, 10);
          return true;
        case SHORT:
          if (!LazyUtils.isNumberMaybe(bytes, fieldStart, fieldLength)) {
            return false;
          }
          currentShort = LazyShort.parseShort(bytes, fieldStart, fieldLength, 10);
          return true;
        case INT:
          if (!LazyUtils.isNumberMaybe(bytes, fieldStart, fieldLength)) {
            return false;
          }
          currentInt = LazyInteger.parseInt(bytes, fieldStart, fieldLength, 10);
          return true;
        case LONG:
          if (!LazyUtils.isNumberMaybe(bytes, fieldStart, fieldLength)) {
            return false;
          }
          currentLong = LazyLong.parseLong(bytes, fieldStart, fieldLength, 10);
          return true;
        case FLOAT:
          if (!LazyUtils.isNumberMaybe(bytes, fieldStart, fieldLength)) {
            return false;
          }
          currentFloat =
              Float.parseFloat(
                  new String(bytes, fieldStart, fieldLength, StandardCharsets.UTF_8));
          return true;
        case DOUBLE:
          if (!LazyUtils.isNumberMaybe(bytes, fieldStart, fieldLength)) {
            return false;
          }
          currentDouble = StringToDouble.strtod(bytes, fieldStart, fieldLength);
          return true;
        case STRING:
        case CHAR:
        case VARCHAR:
          {
            if (isEscaped) {
              if (currentEscapeCount == 0) {
                // No escaping.
                currentExternalBufferNeeded = false;
                currentBytes = bytes;
                currentBytesStart = fieldStart;
                currentBytesLength = fieldLength;
              } else {
                final int unescapedLength = fieldLength - currentEscapeCount;
                if (useExternalBuffer) {
                  currentExternalBufferNeeded = true;
                  currentExternalBufferNeededLen = unescapedLength;
                } else {
                  // The copyToBuffer will reposition and re-read the input buffer.
                  currentExternalBufferNeeded = false;
                  if (internalBufferLen < unescapedLength) {
                    internalBufferLen = unescapedLength;
                    internalBuffer = new byte[internalBufferLen];
                  }
                  copyToBuffer(internalBuffer, 0, unescapedLength);
                  currentBytes = internalBuffer;
                  currentBytesStart = 0;
                  currentBytesLength = unescapedLength;
                }
              }
            } else {
              // If the data is not escaped, reference the data directly.
              currentExternalBufferNeeded = false;
              currentBytes = bytes;
              currentBytesStart = fieldStart;
              currentBytesLength = fieldLength;
            }
          }
          return true;
        case BINARY:
          {
            ByteBuffer bb = ByteBuffer.wrap(bytes, fieldStart, fieldLength);
            // Base64 or raw value: Throws IllegalArgumentException on invalid decode
            final ByteBuffer b64bb = isDecodeBinaryAsBase64 ? Base64.getDecoder().decode(bb) : bb;
            currentBytes = new byte[b64bb.remaining()];
            b64bb.get(currentBytes);
            currentBytesStart = 0;
            currentBytesLength = currentBytes.length;
          }
          return true;
        case DATE:
          if (!LazyUtils.isDateMaybe(bytes, fieldStart, fieldLength)) {
            return false;
          }
          currentDateWritable.set(
              Date.valueOf(
                  new String(bytes, fieldStart, fieldLength, StandardCharsets.UTF_8)));
          return true;
        case TIMESTAMP:
          {
            if (!LazyUtils.isDateMaybe(bytes, fieldStart, fieldLength)) {
              return false;
            }
            String s = new String(bytes, fieldStart, fieldLength, StandardCharsets.US_ASCII);
            Timestamp ts = timestampParser.parseTimestamp(s);
            if (ts == null) {
              logExceptionMessage(bytes, fieldStart, fieldLength, "TIMESTAMP");
              return false;
            }
            currentTimestampWritable.set(ts);
          }
          return true;
        case INTERVAL_YEAR_MONTH:
          if (fieldLength == 0) {
            return false;
          }
          try {
            String s = new String(bytes, fieldStart, fieldLength, StandardCharsets.UTF_8);
            currentHiveIntervalYearMonthWritable.set(HiveIntervalYearMonth.valueOf(s));
          } catch (Exception e) {
            logExceptionMessage(bytes, fieldStart, fieldLength, "INTERVAL_YEAR_MONTH");
            return false;
          }
          return true;
        case INTERVAL_DAY_TIME:
          if (fieldLength == 0) {
            return false;
          }
          try {
            String s = new String(bytes, fieldStart, fieldLength, StandardCharsets.UTF_8);
            currentHiveIntervalDayTimeWritable.set(HiveIntervalDayTime.valueOf(s));
          } catch (Exception e) {
            logExceptionMessage(bytes, fieldStart, fieldLength, "INTERVAL_DAY_TIME");
            return false;
          }
          return true;
        case DECIMAL:
          {
            if (!LazyUtils.isNumberMaybe(bytes, fieldStart, fieldLength)) {
              return false;
            }
            // Trim blanks because OldHiveDecimal did...
            currentHiveDecimalWritable.setFromBytes(bytes, fieldStart, fieldLength, /* trimBlanks */ true);
            boolean decimalIsNull = !currentHiveDecimalWritable.isSet();
            if (!decimalIsNull) {
              DecimalTypeInfo decimalTypeInfo = (DecimalTypeInfo) field.typeInfo;

              int precision = decimalTypeInfo.getPrecision();
              int scale = decimalTypeInfo.getScale();

              decimalIsNull = !currentHiveDecimalWritable.mutateEnforcePrecisionScale(precision, scale);
              if (!decimalIsNull) {
                return true;
              }
            }
            if (LOG.isDebugEnabled()) {
              LOG.debug("Data not in the HiveDecimal data type range so converted to null. Given data is :"
                  + new String(bytes, fieldStart, fieldLength, StandardCharsets.UTF_8));
            }
          }
          return false;

        default:
          throw new Error("Unexpected primitive category " + field.primitiveCategory);
        }
      } else {
        switch (field.complexCategory) {
        case LIST:
        case MAP:
        case STRUCT:
        case UNION:
          {
            // Check for Map which occupies 2 levels (key separator and key/value pair separator).
            if (currentLevel > 0
                && currentComplexTypeHelpers[currentLevel] == null
                && currentComplexTypeHelpers[currentLevel - 1] instanceof MapComplexTypeHelper) {
              currentLevel++;
            }
            ComplexTypeHelper complexTypeHelper = field.complexTypeHelper; 
            currentComplexTypeHelpers[currentLevel++] = complexTypeHelper;
            if (field.complexCategory == Category.MAP) {
              currentComplexTypeHelpers[currentLevel] = null;
            }
  
            // Set up context for readNextComplexField.
            complexTypeHelper.setCurrentFieldInfo(currentFieldStart, currentFieldLength);
          }
          return true;
        default:
          throw new Error("Unexpected complex category " + field.complexCategory);
        }
      }
    } catch (NumberFormatException nfe) {
       logExceptionMessage(bytes, fieldStart, fieldLength, field.complexCategory, field.primitiveCategory);
       return false;
    } catch (IllegalArgumentException iae) {
      logExceptionMessage(bytes, fieldStart, fieldLength, field.complexCategory, field.primitiveCategory);
      return false;
    }
  }