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;
}
}