presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/TypeUtils.java/TypeUtils/prestoNativeToJdbcObject
class TypeUtils:    private static Object prestoNativeToJdbcObject(ConnectorSession session, Type prestoType, Object prestoNative)
            throws SQLException
    {
        if (prestoNative == null) {
            return null;
        }

        if (DOUBLE.equals(prestoType) || BOOLEAN.equals(prestoType) || BIGINT.equals(prestoType)) {
            return prestoNative;
        }

        if (prestoType instanceof DecimalType) {
            DecimalType decimalType = (DecimalType) prestoType;
            if (decimalType.isShort()) {
                BigInteger unscaledValue = BigInteger.valueOf((long) prestoNative);
                return new BigDecimal(unscaledValue, decimalType.getScale(), new MathContext(decimalType.getPrecision()));
            }
            BigInteger unscaledValue = decodeUnscaledValue((Slice) prestoNative);
            return new BigDecimal(unscaledValue, decimalType.getScale(), new MathContext(decimalType.getPrecision()));
        }

        if (REAL.equals(prestoType)) {
            return intBitsToFloat(toIntExact((long) prestoNative));
        }

        if (TINYINT.equals(prestoType)) {
            return SignedBytes.checkedCast((long) prestoNative);
        }

        if (SMALLINT.equals(prestoType)) {
            return Shorts.checkedCast((long) prestoNative);
        }

        if (INTEGER.equals(prestoType)) {
            return toIntExact((long) prestoNative);
        }

        if (DATE.equals(prestoType)) {
            // convert to midnight in default time zone
            long millis = DAYS.toMillis((long) prestoNative);
            return new Date(UTC.getMillisKeepLocal(DateTimeZone.getDefault(), millis));
        }

        if (TIMESTAMP.equals(prestoType)) {
            if (session.isLegacyTimestamp()) {
                ZoneId sessionZone = ZoneId.of(session.getTimeZoneKey().getId());
                return toPgTimestamp(fromPrestoLegacyTimestamp((long) prestoNative, sessionZone));
            }
            return toPgTimestamp(fromPrestoTimestamp((long) prestoNative));
        }

        if (TIMESTAMP_WITH_TIME_ZONE.equals(prestoType)) {
            long millisUtc = unpackMillisUtc((long) prestoNative);
            // PostgreSQL does not store zone, only the point in time
            return new Timestamp(millisUtc);
        }

        if (prestoType instanceof VarcharType || prestoType instanceof CharType) {
            return ((Slice) prestoNative).toStringUtf8();
        }

        if (prestoType instanceof ArrayType) {
            // process subarray of multi-dimensional array
            return getJdbcObjectArray(session, ((ArrayType) prestoType).getElementType(), (Block) prestoNative);
        }

        throw new PrestoException(NOT_SUPPORTED, "Unsupported type: " + prestoType);
    }