Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 33 additions & 56 deletions pinot-spi/src/main/java/org/apache/pinot/spi/data/FieldSpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import javax.annotation.Nullable;
import org.apache.pinot.spi.utils.BooleanUtils;
import org.apache.pinot.spi.utils.ByteArray;
Expand Down Expand Up @@ -419,8 +418,9 @@ public Object getDefaultNullValue() {
return _defaultNullValue;
}

@JsonIgnore
public String getDefaultNullValueString() {
return _dataType != null ? _dataType.toString(_defaultNullValue) : getStringValue(_defaultNullValue);
return _dataType.toString(_defaultNullValue);
}

/// Returns the [String] representation of the given object.
Expand Down Expand Up @@ -462,22 +462,13 @@ private void setDefaultNullValue(@Nullable JsonNode defaultNullValue) {
@JsonIgnore
public void setDefaultNullValue(@Nullable Object defaultNullValue) {
if (defaultNullValue != null) {
_stringDefaultNullValue = getStringDefaultNullValue(defaultNullValue);
_stringDefaultNullValue = getStringValue(defaultNullValue);
}
if (_dataType != null) {
_defaultNullValue = getDefaultNullValue(getFieldType(), _dataType, _stringDefaultNullValue);
}
}

// UUID default values must stringify to their canonical 8-4-4-4-12 form (not raw hex) so they round-trip back
// through getDefaultNullValue(...); all other types keep the generic getStringValue() form.
private String getStringDefaultNullValue(Object defaultNullValue) {
if (_dataType == DataType.UUID && !(defaultNullValue instanceof String)) {
return _dataType.toString(defaultNullValue);
}
return getStringValue(defaultNullValue);
}

public static Object getDefaultNullValue(FieldType fieldType, DataType dataType,
@Nullable String stringDefaultNullValue) {
if (stringDefaultNullValue != null) {
Expand Down Expand Up @@ -748,9 +739,25 @@ public enum FieldType {
DIMENSION, METRIC, TIME, DATE_TIME, COMPLEX
}

/**
* The <code>DataType</code> enum is used to demonstrate the data type of a field.
*/
/// The `DataType` enum represents the data type of a field.
///
/// A value of a given type is held in memory as a fixed Java class, and every value-handling method on this enum
/// (`convert`, `equals`, `hashCode`, `compare`, `toString`) expects and produces that representation:
/// - `INT` → [Integer]
/// - `LONG` → [Long]
/// - `FLOAT` → [Float]
/// - `DOUBLE` → [Double]
/// - `BIG_DECIMAL` → [BigDecimal]
/// - `BOOLEAN` → [Integer] (`0` or `1`)
/// - `TIMESTAMP` → [Long] (epoch millis)
/// - `STRING` / `JSON` → [String]
/// - `BYTES` → `byte[]`
/// - `UUID` → `byte[]` (fixed 16-byte big-endian form)
/// - `MAP` / `OPEN_STRUCT` → [Map]
/// - `LIST` → [List]
///
/// `convertInternal` is the exception: it returns the internal storage form, which for `BYTES` and `UUID` is
/// [ByteArray] rather than `byte[]`.
@SuppressWarnings("rawtypes")
public enum DataType {
// LIST is for complex lists which is different from multi-value column of primitives
Expand Down Expand Up @@ -881,23 +888,16 @@ public Object convert(String value) {
throw new IllegalStateException();
}
} catch (Exception e) {
throw new IllegalArgumentException(
"Cannot convert value: '" + value + "' to type: " + this + " (" + e.getMessage() + ")", e);
throw new IllegalArgumentException("Cannot convert value: '" + value + "' to type: " + this);
}
}

public boolean equals(Object value1, Object value2) {
if (this == UUID) {
return UuidUtils.equals(toBytesValue(value1), toBytesValue(value2));
}
return this == BYTES ? Arrays.equals(toBytesValue(value1), toBytesValue(value2)) : value1.equals(value2);
return this == BYTES || this == UUID ? Arrays.equals((byte[]) value1, (byte[]) value2) : value1.equals(value2);
}

public int hashCode(Object value) {
if (this == UUID) {
return UuidUtils.hashCode(toBytesValue(value));
}
return this == BYTES ? Arrays.hashCode(toBytesValue(value)) : value.hashCode();
return this == BYTES || this == UUID ? Arrays.hashCode((byte[]) value) : value.hashCode();
}
Comment thread
Jackie-Jiang marked this conversation as resolved.

/**
Expand All @@ -910,26 +910,23 @@ public int hashCode(Object value) {
public int compare(Object value1, Object value2) {
switch (this) {
case INT:
case BOOLEAN:
return Integer.compare((int) value1, (int) value2);
case LONG:
case TIMESTAMP:
return Long.compare((long) value1, (long) value2);
case FLOAT:
return Float.compare((float) value1, (float) value2);
case DOUBLE:
return Double.compare((double) value1, (double) value2);
case BIG_DECIMAL:
return ((BigDecimal) value1).compareTo((BigDecimal) value2);
case BOOLEAN:
return Boolean.compare((boolean) value1, (boolean) value2);
case TIMESTAMP:
return Long.compare((long) value1, (long) value2);
case STRING:
case JSON:
return ((String) value1).compareTo((String) value2);
case BYTES:
return ByteArray.compare(toBytesValue(value1), toBytesValue(value2));
case UUID:
return UuidUtils.compare(toBytesValue(value1), toBytesValue(value2));
return ByteArray.compare((byte[]) value1, (byte[]) value2);
case MAP:
Comment thread
Jackie-Jiang marked this conversation as resolved.
case OPEN_STRUCT:
case LIST:
Expand All @@ -946,14 +943,11 @@ public String toString(Object value) {
if (this == BIG_DECIMAL) {
return ((BigDecimal) value).toPlainString();
}
if (this == UUID) {
if (value instanceof UUID) {
return UuidUtils.toString((UUID) value);
}
return UuidUtils.toString(toBytesValue(value));
}
if (this == BYTES) {
return BytesUtils.toHexString(toBytesValue(value));
return BytesUtils.toHexString((byte[]) value);
}
if (this == UUID) {
return UuidUtils.toString((byte[]) value);
}
if (this == MAP || this == OPEN_STRUCT || this == LIST) {
try {
Expand Down Expand Up @@ -1000,25 +994,8 @@ public Comparable convertInternal(String value) {
throw new IllegalStateException();
}
} catch (Exception e) {
throw new IllegalArgumentException(
"Cannot convert value: '" + value + "' to type: " + this + " (" + e.getMessage() + ")", e);
}
}

private byte[] toBytesValue(Object value) {
if (value instanceof byte[]) {
return (byte[]) value;
}
if (value instanceof ByteArray) {
return ((ByteArray) value).getBytes();
}
if (value instanceof UUID) {
return UuidUtils.toBytes((UUID) value);
}
if (value instanceof String && this == UUID) {
return UuidUtils.toBytes((String) value);
throw new IllegalArgumentException("Cannot convert value: '" + value + "' to type: " + this);
}
throw new IllegalArgumentException("Unsupported value for " + this + ": " + value);
}
}

Expand Down
Loading
Loading