You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[client-v2] Compiled POJO setter emits invalid bytecode (VerifyError) when the column type does not match the primitive field type #2999
client-v2 compiles a POJO field setter into bytecode (SerializerUtils.compilePOJOSetter). When the column type
and the POJO field's primitive type do not match exactly, the generated class is invalid and reading fails with java.lang.VerifyError (thrown when the compiled setter class is first linked, i.e. on the first row read).
Two distinct groups of combinations are affected.
1. The value left on the stack is not converted to the setter's primitive type. binaryReaderMethodForType only computed a conversion opcode for a few reader/field combinations
(longToOpcode, floatToOpcode and doubleToOpcode return -1 for byte/short/char/boolean, and the Int8/UInt8/Int16/Enum8/Enum16/Bool branches computed no conversion at all). So, for example:
an Int64, UInt32, Float32, Float64 or BFloat16 column bound to a byte, short, char or boolean field
an Int8, UInt8, Int16, Enum8, Enum16 or Bool column bound to a long, float or double field
leave a value of the wrong type on the operand stack for the setter descriptor, and the generated class does not verify.
2. A primitive field bound to a column that is not read into a primitive.
The generic branch emits LDC of a class constant for the target type and CHECKCAST with its internal name.
For a primitive target that produces a class constant named "I"/"J" and a CHECKCAST int, and the value read
by readValue (an Object) is passed to a primitive setter descriptor. So Int128, UInt128, Int256, UInt256
and Decimal* columns cannot be read into a primitive field at all, even though the value is a Number.
Stringsql = "SELECT toInt64(300) AS v"; // also: toFloat64(-2.7), toInt8(-5) into a long field, ...TableSchemaschema = client.getTableSchemaFromQuery(sql);
client.register(Pojo.class, schema);
client.queryAll(sql, Pojo.class, schema); // -> java.lang.VerifyError
The same happens with SELECT toInt128(-2) AS v or SELECT toDecimal64(123.45, 2) AS v bound to a long/double
field (group 2).
Expected behaviour
The value is converted to the field's primitive type following Java's narrowing/widening rules (as already happens
for an Int32 column bound to a byte field), and a Number-valued column can be read into a primitive field.
Error log
java.lang.VerifyError
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
...
at com.clickhouse.client.api.data_formats.internal.SerializerUtils.compilePOJOSetter(SerializerUtils.java:...)
Activity