in paimon-format/src/main/java/org/apache/paimon/format/parquet/writer/ParquetRowDataWriter.java [544:635]
private FieldWriter createDecimalWriter(int precision, int scale) {
checkArgument(
precision <= DecimalType.MAX_PRECISION,
"Decimal precision %s exceeds max precision %s",
precision,
DecimalType.MAX_PRECISION);
class Int32Writer implements FieldWriter {
@Override
public void write(InternalArray arrayData, int ordinal) {
long unscaledLong =
(arrayData.getDecimal(ordinal, precision, scale)).toUnscaledLong();
addRecord(unscaledLong);
}
@Override
public void write(InternalRow row, int ordinal) {
long unscaledLong = row.getDecimal(ordinal, precision, scale).toUnscaledLong();
addRecord(unscaledLong);
}
private void addRecord(long unscaledLong) {
recordConsumer.addInteger((int) unscaledLong);
}
}
class Int64Writer implements FieldWriter {
@Override
public void write(InternalArray arrayData, int ordinal) {
long unscaledLong =
(arrayData.getDecimal(ordinal, precision, scale)).toUnscaledLong();
addRecord(unscaledLong);
}
@Override
public void write(InternalRow row, int ordinal) {
long unscaledLong = row.getDecimal(ordinal, precision, scale).toUnscaledLong();
addRecord(unscaledLong);
}
private void addRecord(long unscaledLong) {
recordConsumer.addLong(unscaledLong);
}
}
class UnscaledBytesWriter implements FieldWriter {
private final int numBytes;
private final byte[] decimalBuffer;
private UnscaledBytesWriter() {
this.numBytes = computeMinBytesForDecimalPrecision(precision);
this.decimalBuffer = new byte[numBytes];
}
@Override
public void write(InternalArray arrayData, int ordinal) {
byte[] bytes = (arrayData.getDecimal(ordinal, precision, scale)).toUnscaledBytes();
addRecord(bytes);
}
@Override
public void write(InternalRow row, int ordinal) {
byte[] bytes = row.getDecimal(ordinal, precision, scale).toUnscaledBytes();
addRecord(bytes);
}
private void addRecord(byte[] bytes) {
byte[] writtenBytes;
if (bytes.length == numBytes) {
// Avoid copy.
writtenBytes = bytes;
} else {
byte signByte = bytes[0] < 0 ? (byte) -1 : (byte) 0;
Arrays.fill(decimalBuffer, 0, numBytes - bytes.length, signByte);
System.arraycopy(
bytes, 0, decimalBuffer, numBytes - bytes.length, bytes.length);
writtenBytes = decimalBuffer;
}
recordConsumer.addBinary(Binary.fromReusedByteArray(writtenBytes, 0, numBytes));
}
}
if (ParquetSchemaConverter.is32BitDecimal(precision)) {
return new Int32Writer();
} else if (ParquetSchemaConverter.is64BitDecimal(precision)) {
return new Int64Writer();
} else {
return new UnscaledBytesWriter();
}
}