Add support for TIMESTAMP type in exasol connector#26963
Conversation
Reviewer's GuideThe PR introduces full support for Exasol TIMESTAMP type in the Trino connector by extending JDBC type handling in ExasolClient with precision-aware read/write functions, adding extensive round-trip and error-handling tests in TestExasolTypeMapping, and updating documentation accordingly. ER diagram for TIMESTAMP type mapping between Exasol and TrinoerDiagram
EXASOL_TIMESTAMP {
precision int
}
TRINO_TIMESTAMP {
precision int
}
EXASOL_TIMESTAMP ||--|| TRINO_TIMESTAMP : "maps to"
Class diagram for updated ExasolClient TIMESTAMP supportclassDiagram
class ExasolClient {
+toColumnMapping(session, typeHandle)
+timestampColumnMapping(typeHandle)
+longTimestampReadFunction(timestampType)
+longTimestampWriteFunction(timestampType)
+objectTimestampReadFunction(timestampType)
+objectTimestampWriteFunction(timestampType)
+verifyObjectTimestampPrecision(timestampType)
+getTimestampBindExpression(precision)
MAX_EXASOL_TIMESTAMP_PRECISION : int
}
class TimestampType {
+getPrecision()
+isShort()
}
class LongTimestamp {}
ExasolClient --> TimestampType
ExasolClient --> LongTimestamp
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey there - I've reviewed your changes - here's some feedback:
- In both LongWriteFunction and ObjectWriteFunction setNull methods you’re calling statement.setNull(index, Types.VARCHAR), but since this is a TIMESTAMP column you should use Types.TIMESTAMP to avoid unintended type conversions.
- Instead of hardcoding MAX_EXASOL_TIMESTAMP_PRECISION = 9 in ExasolClient, consider reusing the max precision constant from TimestampType (e.g. TimestampType.MAX_PRECISION) or centralizing it to avoid duplication.
- In testUnsupportedInsertValue you hardcode the table name to test_unsupported_hashtype; switch to a per-test randomNameSuffix (like in testUnsupportedDefinition) to prevent conflicts when running tests in parallel.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In both LongWriteFunction and ObjectWriteFunction setNull methods you’re calling statement.setNull(index, Types.VARCHAR), but since this is a TIMESTAMP column you should use Types.TIMESTAMP to avoid unintended type conversions.
- Instead of hardcoding MAX_EXASOL_TIMESTAMP_PRECISION = 9 in ExasolClient, consider reusing the max precision constant from TimestampType (e.g. TimestampType.MAX_PRECISION) or centralizing it to avoid duplication.
- In testUnsupportedInsertValue you hardcode the table name to test_unsupported_hashtype; switch to a per-test randomNameSuffix (like in testUnsupportedDefinition) to prevent conflicts when running tests in parallel.
## Individual Comments
### Comment 1
<location> `plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java:345` </location>
<code_context>
+ public void setNull(PreparedStatement statement, int index)
+ throws SQLException
+ {
+ statement.setNull(index, Types.VARCHAR);
+ }
+ };
</code_context>
<issue_to_address>
**issue (bug_risk):** Using Types.VARCHAR for setting null on TIMESTAMP columns may be incorrect.
In both longTimestampWriteFunction and objectTimestampWriteFunction, setNull should use Types.TIMESTAMP for TIMESTAMP columns to avoid potential JDBC or Exasol issues. Change to Types.TIMESTAMP unless VARCHAR is required for a specific reason.
</issue_to_address>
### Comment 2
<location> `plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java:317-318` </location>
<code_context>
+ private static LongReadFunction longTimestampReadFunction(TimestampType timestampType)
+ {
+ return (resultSet, columnIndex) -> {
+ Timestamp timestamp = resultSet.getTimestamp(columnIndex);
+ return toTrinoTimestamp(timestampType, timestamp.toLocalDateTime());
+ };
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** Null handling for ResultSet.getTimestamp is missing.
A null check should be added before calling toLocalDateTime() to prevent a NullPointerException when the database value is NULL.
</issue_to_address>
### Comment 3
<location> `plugin/trino-exasol/src/test/java/io/trino/plugin/exasol/TestExasolTypeMapping.java:566-572` </location>
<code_context>
+ expectedException);
+ }
+
+ private void testUnsupportedInsertValue(
+ String exasolType,
+ String inputLiteral,
+ String expectedException)
+ {
+ try (TestTable table = new TestTable(onRemoteDatabase(), TEST_SCHEMA + ".test_unsupported_hashtype", "(col %s)".formatted(exasolType))) {
+ assertExasolSqlQueryFails("INSERT INTO %s VALUES (%s)".formatted(table.getName(), inputLiteral), expectedException);
+ }
+ }
</code_context>
<issue_to_address>
**question (testing):** Question about test table naming for unsupported insert value tests.
Consider parameterizing the test table name or generating a unique name for each test to prevent conflicts during parallel test execution.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
8dc68e8 to
70b19d8
Compare
MAX_EXASOL_TIMESTAMP_PRECISION is 9, butTimestampType.MAX_PRECISION is 12, so we have to create a separate constant. |
70b19d8 to
a417a34
Compare
a417a34 to
a22f7ac
Compare
Thank you very much for your review findings! 👍 |
Thank you very much for your review, @chenjian2664 ! 👍 |
9db1bd7 to
ddbdfb9
Compare
|
This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack. |
|
@ebyhr @Praveen2112 any updates on the PR? |
|
This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack. |
ddbdfb9 to
f995fa5
Compare
f995fa5 to
b39f8d4
Compare
skyglass
left a comment
There was a problem hiding this comment.
@chenjian2664 , Thank you very much for your feedback! 👍
I have created separate TestExasolTypeMapping#testTimestampCoercion and moved the cases with coercion to this new test method.
I also added some additional test cases with coercion.
|
This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack. |
ec5c5b1 to
cdc4f73
Compare
|
This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack. |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
📝 WalkthroughWalkthroughThis pull request adds timestamp support to the Exasol connector for Trino. The changes include documentation updates for the 📝 Coding Plan
Comment Tip CodeRabbit can suggest fixes for GitHub Check annotations.Configure the |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
plugin/trino-exasol/src/test/java/io/trino/plugin/exasol/TestExasolTypeMapping.java (2)
354-361: Javadoc placement is unconventional.The
@Testannotation should come after the Javadoc comment, not before it. The conventional ordering is: Javadoc → annotations → method signature.📝 Suggested fix
- `@Test` /** * Additional test supplementing {`@link` `#testTimestamp`} * with timestamp precisions higher than the input value decimal digits * * `@see` `#testTimestamp` */ + `@Test` void testTimestampCoercion()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@plugin/trino-exasol/src/test/java/io/trino/plugin/exasol/TestExasolTypeMapping.java` around lines 354 - 361, The `@Test` annotation is placed before the Javadoc for the testTimestampCoercion method; move the Javadoc block so it appears immediately above the `@Test` annotation (i.e., reorder to: Javadoc, then `@Test`, then the method signature for testTimestampCoercion) to follow conventional Java annotation/Javadoc ordering.
608-618: Misleading table name prefix.The table name prefix
test_unsupported_hashtype_is misleading since this method is now also used for TIMESTAMP type tests. Consider using a more generic name.📝 Suggested fix
private void testUnsupportedInsertValue( String exasolType, String inputLiteral, String expectedException) { try (TestTable table = new TestTable(onRemoteDatabase(), - TEST_SCHEMA + ".test_unsupported_hashtype_" + randomNameSuffix(), + TEST_SCHEMA + ".test_unsupported_value_" + randomNameSuffix(), "(col %s)".formatted(exasolType))) { assertExasolSqlQueryFails("INSERT INTO %s VALUES (%s)".formatted(table.getName(), inputLiteral), expectedException); } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@plugin/trino-exasol/src/test/java/io/trino/plugin/exasol/TestExasolTypeMapping.java` around lines 608 - 618, The table name prefix "test_unsupported_hashtype_" in testUnsupportedInsertValue is misleading; update the TestTable name construction to use a generic prefix such as "test_unsupported_insert_" (or "test_unsupported_value_") instead of "test_unsupported_hashtype_" so the table name is correct for TIMESTAMP and other non-hash-type tests—modify the string in the TestTable constructor call inside testUnsupportedInsertValue (where TEST_SCHEMA + ".test_unsupported_hashtype_" + randomNameSuffix() is used) to the new prefix.plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java (1)
455-462: Consider adding upper bound validation for precision.The method only validates that precision is non-negative but doesn't check the upper bound. While callers currently validate precision before calling this method, adding defensive validation would make the method self-contained and protect against future misuse.
📝 Suggested fix
private static String getTimestampBindExpression(int precision) { - checkArgument(precision >= 0, "Precision is negative: %s", precision); + checkArgument(precision >= 0 && precision <= MAX_EXASOL_TIMESTAMP_PRECISION, + "Precision is out of range: %s", precision); if (precision == 0) { return "TO_TIMESTAMP(?, 'YYYY-MM-DD HH24:MI:SS')"; } return format("TO_TIMESTAMP(?, 'YYYY-MM-DD HH24:MI:SS.FF%d')", precision); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java` around lines 455 - 462, getTimestampBindExpression currently only checks precision >= 0; add an upper-bound check to make it defensive (e.g., define a constant MAX_TIMESTAMP_PRECISION and ensure precision <= MAX_TIMESTAMP_PRECISION) and throw via checkArgument when out of range; update getTimestampBindExpression to use checkArgument(precision <= MAX_TIMESTAMP_PRECISION, "Precision is too large: %s", precision) (leave existing non-negative check) so the method is self-contained and protects callers from invalid precision values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@plugin/trino-exasol/src/test/java/io/trino/plugin/exasol/TestExasolTypeMapping.java`:
- Around line 345-346: The test file TestExasolTypeMapping contains two
identical .addRoundTrip(...) assertions (both using
resolveInvalidDstGapValue("2018-04-01 02:13:55.123") with createTimestampType(3)
and the same expected TIMESTAMP) which is a duplicate; remove one of the
duplicate .addRoundTrip(...) lines or replace it with a different scenario
(e.g., a different DST gap timestamp, precision via createTimestampType(n), or
expected value) so each .addRoundTrip call in the test covers a unique case.
---
Nitpick comments:
In `@plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java`:
- Around line 455-462: getTimestampBindExpression currently only checks
precision >= 0; add an upper-bound check to make it defensive (e.g., define a
constant MAX_TIMESTAMP_PRECISION and ensure precision <=
MAX_TIMESTAMP_PRECISION) and throw via checkArgument when out of range; update
getTimestampBindExpression to use checkArgument(precision <=
MAX_TIMESTAMP_PRECISION, "Precision is too large: %s", precision) (leave
existing non-negative check) so the method is self-contained and protects
callers from invalid precision values.
In
`@plugin/trino-exasol/src/test/java/io/trino/plugin/exasol/TestExasolTypeMapping.java`:
- Around line 354-361: The `@Test` annotation is placed before the Javadoc for the
testTimestampCoercion method; move the Javadoc block so it appears immediately
above the `@Test` annotation (i.e., reorder to: Javadoc, then `@Test`, then the
method signature for testTimestampCoercion) to follow conventional Java
annotation/Javadoc ordering.
- Around line 608-618: The table name prefix "test_unsupported_hashtype_" in
testUnsupportedInsertValue is misleading; update the TestTable name construction
to use a generic prefix such as "test_unsupported_insert_" (or
"test_unsupported_value_") instead of "test_unsupported_hashtype_" so the table
name is correct for TIMESTAMP and other non-hash-type tests—modify the string in
the TestTable constructor call inside testUnsupportedInsertValue (where
TEST_SCHEMA + ".test_unsupported_hashtype_" + randomNameSuffix() is used) to the
new prefix.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 50a2626a-9941-48c5-a30f-f3a07b3aa1f9
📒 Files selected for processing (3)
docs/src/main/sphinx/connector/exasol.mdplugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.javaplugin/trino-exasol/src/test/java/io/trino/plugin/exasol/TestExasolTypeMapping.java
FYI |
|
This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack. |
fb7cd42 to
9bd9bcc
Compare
9bd9bcc to
ba04b8e
Compare
skyglass
left a comment
There was a problem hiding this comment.
Thank you very much for your review, @chenjian2664 , @Praveen2112 , @ebyhr !
The PR has been updated and your review findings have been applied.
|
This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack. |
Description
Added Exasol Trino connector support for Timestamp JDBC data type
Additional context and related issues
Release notes
Summary by Sourcery
Add support for the Exasol TIMESTAMP type by mapping it to Trino’s TIMESTAMP(n) and handling precision, read/write functions, and binding; include comprehensive tests for round-trip behavior across time zones (including DST edge cases) and unsupported values, and update connector documentation.
New Features:
Enhancements:
Documentation:
Tests: