in holo-client/src/main/java/com/alibaba/hologres/client/impl/binlog/HoloBinlogDecoder.java [145:258]
private void convertBinaryRowToRecord(Column column, BinaryRow currentRow, Record currentRecord, int index)
throws HoloClientException {
int offsetIndex = index + 3;
if (currentRow.isNullAt(offsetIndex)) {
currentRecord.setObject(index, null);
return;
}
switch (column.getType()) {
case Types.CHAR:
currentRecord.setObject(index, String.format("%-" + column.getPrecision() + "s", currentRow.getString(offsetIndex)));
break;
case Types.VARCHAR:
currentRecord.setObject(index, currentRow.getString(offsetIndex));
break;
case Types.OTHER:
if ("roaringbitmap".equals(column.getTypeName())) {
currentRecord.setObject(index, currentRow.getByteArray(offsetIndex));
} else {
currentRecord.setObject(index, currentRow.getString(offsetIndex));
}
break;
case Types.DATE:
currentRecord.setObject(index, new Date(currentRow.getInt(offsetIndex) * ONE_DAY_IN_MILLIES));
break;
case Types.TIME:
case Types.TIME_WITH_TIMEZONE:
if ("timetz".equals(column.getTypeName())) {
long time = ByteBuffer.wrap(currentRow.getByteArray(offsetIndex)).order(ByteOrder.LITTLE_ENDIAN).asLongBuffer().get(0);
int zoneOffset = ByteBuffer.wrap(currentRow.getByteArray(offsetIndex)).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get(2);
currentRecord.setObject(index, new Time(time / 1000L + zoneOffset * 1000L));
} else {
currentRecord.setObject(index, new Time(currentRow.getLong(offsetIndex) / 1000L - TIMEZONE_OFFSET));
}
break;
case Types.TIMESTAMP:
case Types.TIMESTAMP_WITH_TIMEZONE:
if ("timestamptz".equals(column.getTypeName())) {
currentRecord.setObject(index, new Timestamp(currentRow.getLong(offsetIndex)));
} else {
long microseconds = currentRow.getLong(offsetIndex);
Timestamp timestamp = new Timestamp(microseconds / 1000L - TIMEZONE_OFFSET);
timestamp.setNanos((int) ((microseconds % 1_000_000L) * 1_000));
currentRecord.setObject(index, timestamp);
}
break;
case Types.SMALLINT:
currentRecord.setObject(index, currentRow.getShort(offsetIndex));
break;
case Types.INTEGER:
currentRecord.setObject(index, currentRow.getInt(offsetIndex));
break;
case Types.BIGINT:
currentRecord.setObject(index, currentRow.getLong(offsetIndex));
break;
case Types.NUMERIC:
case Types.DECIMAL:
int scale = column.getScale();
byte[] value = currentRow.getByteArray(offsetIndex);
ArrayUtil.reverse(value);
BigInteger bigInteger = new BigInteger(value);
BigDecimal bigDecimal = new BigDecimal(bigInteger);
bigDecimal = bigDecimal.movePointLeft(scale);
bigDecimal = bigDecimal.setScale(scale, BigDecimal.ROUND_DOWN);
currentRecord.setObject(index, bigDecimal);
break;
case Types.FLOAT:
case Types.REAL:
currentRecord.setObject(index, currentRow.getFloat(offsetIndex));
break;
case Types.DOUBLE:
currentRecord.setObject(index, currentRow.getDouble(offsetIndex));
break;
case Types.BINARY:
case Types.VARBINARY:
currentRecord.setObject(index, currentRow.getByteArray(offsetIndex));
break;
case Types.ARRAY:
switch (column.getTypeName()) {
case "_int4":
currentRecord.setObject(index, currentRow.getArray(offsetIndex).toIntArray());
break;
case "_int8":
currentRecord.setObject(index, currentRow.getArray(offsetIndex).toLongArray());
break;
case "_float4":
currentRecord.setObject(index, currentRow.getArray(offsetIndex).toFloatArray());
break;
case "_float8":
currentRecord.setObject(index, currentRow.getArray(offsetIndex).toDoubleArray());
break;
case "_bool":
currentRecord.setObject(index, currentRow.getArray(offsetIndex).toBooleanArray());
break;
case "_text":
case "_varchar":
BinaryArray binaryArray = currentRow.getArray(offsetIndex);
String[] stringArrays = new String[binaryArray.numElements()];
for (int i = 0; i < binaryArray.numElements(); i++) {
stringArrays[i] = binaryArray.getString(i);
}
currentRecord.setObject(index, stringArrays);
break;
default:
throw new HoloClientException(ExceptionCode.DATA_TYPE_ERROR, "unsupported array type " + column.getType() + " type name:" + column.getTypeName());
}
break;
case Types.BOOLEAN:
case Types.BIT:
currentRecord.setObject(index, currentRow.getBoolean(offsetIndex));
break;
default:
throw new HoloClientException(ExceptionCode.DATA_TYPE_ERROR, "unsupported type " + column.getType() + " type name:" + column.getTypeName());
}
}