feat(bigquery-jdbc): implement TypeRegistry and TypeDescriptor - #13947
feat(bigquery-jdbc): implement TypeRegistry and TypeDescriptor#13947Neenu1995 wants to merge 6 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces BigQueryTypeRegistry and TypeDescriptor to handle bidirectional type mapping and coercion between JDBC, Java, and BigQuery. The review feedback highlights several key issues and improvements: a potential runtime exception in the TIMESTAMP coercer for Java 8 date/time types, precision loss when converting Number to BigDecimal using doubleValue(), and unused code involving DESCRIPTORS_BY_ORDINAL. Additionally, suggestions were made to expand conversion support for java.util.Date and Gson's JsonElement to make the registry more robust.
| (val, zone) -> { | ||
| if (val instanceof Date) return (Date) val; | ||
| if (val instanceof LocalDate) return Date.valueOf((LocalDate) val); | ||
| throw new IllegalArgumentException("Cannot convert to DATE: " + val); |
There was a problem hiding this comment.
In JDBC, it is common to convert other date/time types (like java.sql.Timestamp or java.util.Date) to java.sql.Date. Adding support for java.util.Date (which is the superclass of java.sql.Timestamp) makes the driver much more robust and user-friendly.
if (val instanceof Date) return (Date) val;
if (val instanceof LocalDate) return Date.valueOf((LocalDate) val);
if (val instanceof java.util.Date) return new Date(((java.util.Date) val).getTime());
throw new IllegalArgumentException("Cannot convert to DATE: " + val);
}));| (val, zone) -> { | ||
| if (val instanceof Time) return (Time) val; | ||
| if (val instanceof LocalTime) return Time.valueOf((LocalTime) val); | ||
| throw new IllegalArgumentException("Cannot convert to TIME: " + val); |
There was a problem hiding this comment.
In JDBC, it is common to convert other date/time types (like java.sql.Timestamp or java.util.Date) to java.sql.Time. Adding support for java.util.Date makes the driver much more robust and user-friendly.
(val, zone) -> {
if (val instanceof Time) return (Time) val;
if (val instanceof LocalTime) return Time.valueOf((LocalTime) val);
if (val instanceof java.util.Date) return new Time(((java.util.Date) val).getTime());
throw new IllegalArgumentException("Cannot convert to TIME: " + val);| Types.OTHER, | ||
| String.class, | ||
| StandardSQLTypeName.JSON, | ||
| Arrays.asList(com.google.gson.JsonObject.class), |
There was a problem hiding this comment.
Registering com.google.gson.JsonElement.class instead of com.google.gson.JsonObject.class allows the type registry to automatically resolve any Gson JSON element (including JsonArray, JsonPrimitive, etc.) to the JSON descriptor, thanks to the fallback assignability check in getDescriptorForClass.
| Arrays.asList(com.google.gson.JsonObject.class), | |
| Arrays.asList(com.google.gson.JsonElement.class), |
| */ | ||
| final class BigQueryTypeRegistry { | ||
|
|
||
| private static final TypeDescriptor<?>[] DESCRIPTORS_BY_ORDINAL; |
| int maxOrdinal = 0; | ||
| for (StandardSQLTypeName type : StandardSQLTypeName.values()) { | ||
| if (type.ordinal() > maxOrdinal) { | ||
| maxOrdinal = type.ordinal(); | ||
| } | ||
| } | ||
| DESCRIPTORS_BY_ORDINAL = new TypeDescriptor<?>[maxOrdinal + 1]; |
| if (DESCRIPTORS_BY_ORDINAL[descriptor.getBqType().ordinal()] == null) { | ||
| DESCRIPTORS_BY_ORDINAL[descriptor.getBqType().ordinal()] = descriptor; | ||
| } |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a type mapping and coercion system between JDBC, Java, and BigQuery types, consisting of BigQueryTimezoneUtility, BigQueryTypeRegistry, and TypeDescriptor. The feedback highlights several key areas for improvement: resolving a potential parsing bug in boxTimestamp for strings with timezone offsets, using legacy Calendar manipulation for java.sql.Time to handle DST correctly, preserving millisecond precision when converting to LocalTime, and removing the unused DESCRIPTORS_BY_ORDINAL array.
No description provided.