-
Notifications
You must be signed in to change notification settings - Fork 2.1k
[Feature][Connector-V2] Fix Unsupported data type exception when ck inserting JSON via JDBC #9906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
…nserting JSON via JDBC
…nserting JSON via JDBC
|
|
||
| public static final BasicType<String> STRING_TYPE = | ||
| new BasicType<>(String.class, SqlType.STRING); | ||
| public static final BasicType<String> JSON_TYPE = new BasicType<>(String.class, SqlType.JSON); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already has https://github.com/apache/seatunnel/blob/dev/seatunnel-api/src/main/java/org/apache/seatunnel/api/table/type/CommonOptions.java#L33. So I think we can reuse this option. Not create new type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already has https://github.com/apache/seatunnel/blob/dev/seatunnel-api/src/main/java/org/apache/seatunnel/api/table/type/CommonOptions.java#L33. So I think we can reuse this option. Not create new type.
Hi @Hisoka-X, thank you for the review.
I see now that BasicType#JSON_TYPE is redundant. ck sink can infer the type from the catalog. I'll remove it in the next commit to allow writing to JSON columns without any config changes.
…nserting JSON via JDBC
|
Please also verify in e2e code |
Thank you for the review, I'll add the e2e test in the next commit. |
…nserting JSON via JDBC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @JeremyXin
| tableSchema.get( | ||
| fieldNames[i])) | ||
| ? ClickHouseDataType.JSON.name() | ||
| : fieldTypes[i].getSqlType().name()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sqltype is come from SeaTunnel. Why it can used in clickhouse sql directly? We should use ClickhouseTypeConverter to convert.
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sqltype is come from SeaTunnel. Why it can used in clickhouse sql directly? We should use
ClickhouseTypeConverterto convert.
Hi @Hisoka-X , Thank you for your guidance. I'm facing a roadblock and would appreciate your input.
To force SqlBasedPreparedStatement for writing JSON types, I'm adding a CAST in the VALUES() clause. And that all other types are converted to a generic ?.
Since only the JSON type requires special handling, I'd like to skip implementing ClickhouseTypeConverter#convert and instead directly use the data types from tableSchema for the CAST.
e.g.,String typeName = tableSchema.getOrDefault(fieldName, ""), Do you think this is feasible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what do you want to do. Could you share some demo? Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what do you want to do. Could you share some demo? Thanks.
Hi @Hisoka-X , Thank you for your reply.
Use the native ClickHouse tableSchema for type mapping in the INSERT sql, instead of using SeaTunnel types. JSON columns are now explicitly cast with CAST(? AS String), all other column types remain as a ? placeholder.
here is the code change:
// Uses ClickHouse table schema to get type names
String[] typeNames =
Arrays.stream(fieldNames)
.map(name -> tableSchema.getOrDefault(name, ""))
.toArray(String[]::new);The CAST for JSON is a workaround for older clickhouse-jdbc limitations when JSON support was experimental, then this implementation is somewhat informal, and this might require further discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Cyanty , I found the same issue in ClickHouse/clickhouse-java#2491. I think the better way is upgrade the clickhouse-jdbc version. Could you try this way? Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Cyanty , I found the same issue in ClickHouse/clickhouse-java#2491. I think the better way is upgrade the clickhouse-jdbc version. Could you try this way? Thanks.
Hi @Hisoka-X , Of course, upgrading the driver version would be more reasonable. I will attempt to upgrade the version and check if there are any incompatible codes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Cyanty !
close #9857
Issue:
When using
clickhouse-client:0.3.2-patch11, inserting data into aJSONcolumn throws anUnsupported data typeexception. The error originates fromClickHouseRowBinaryProcessor#MappedFunctions.serialize(484).Root Cause:
The
ClickHouseRowBinaryProcessorin this driver version lacks a serializer mapping for theJSONdata type. ForINSERT ... VALUES (?,?,...)statements, the driver defaults to usingInputBasedPreparedStatement, which invokes theserializemethod duringaddBatch(). This inevitably triggers the exception when aJSONtype is encountered.Solution:
It was observed that if the
VALUES()clause contains characters other than?,,, orWhitespace, the driver defaults toSqlBasedPreparedStatement. This implementation builds theINSERTstatement by concatenating values as a single string and does not call theserializemethod. By slightly modifying the statement, we can force the use ofSqlBasedPreparedStatement, thus bypassing the bug and enablingJSONinsertion without a driver update.Check list
New License Guide