Skip to content

Conversation

skyglass
Copy link
Member

@skyglass skyglass commented Oct 15, 2025

Description

Added Exasol Trino connector support for Timestamp JDBC data type

Additional context and related issues

  • Exasol TIMESTAMP type is mapped to Trino TIMESTAMP type
  • added correspondent tests for timestamp with precision data type
  • added tests for DST gap and DST overlap times in "America/Bahia_Bandera" JVM time zone

Release notes

## Exasol Connect
* Add support for `timestamp` type. 

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:

  • Support Exasol TIMESTAMP(n) type mapping to Trino TIMESTAMP(n).

Enhancements:

  • Implement timestampColumnMapping with appropriate read/write functions for short and long timestamps and bind expression generation based on precision.
  • Validate precision range against Exasol’s maximum supported precision.

Documentation:

  • Update Exasol connector documentation to include TIMESTAMP(n) type mapping.

Tests:

  • Add round-trip tests for TIMESTAMP types with various precisions, time zones, and DST gap/overlap scenarios.
  • Add tests for unsupported timestamp values and invalid type definitions.

@cla-bot cla-bot bot added the cla-signed label Oct 15, 2025
Copy link

sourcery-ai bot commented Oct 15, 2025

Reviewer's Guide

The 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 Trino

erDiagram
    EXASOL_TIMESTAMP {
        precision int
    }
    TRINO_TIMESTAMP {
        precision int
    }
    EXASOL_TIMESTAMP ||--|| TRINO_TIMESTAMP : "maps to"
Loading

Class diagram for updated ExasolClient TIMESTAMP support

classDiagram
    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
Loading

File-Level Changes

Change Details Files
Implement ExasolClient timestamp type mapping and binding logic
  • Define MAX_EXASOL_TIMESTAMP_PRECISION constant
  • Extend toColumnMapping to handle Types.TIMESTAMP
  • Implement timestampColumnMapping with precision-based long/object pathways
  • Provide read/write functions for both short and long timestamps
  • Add getTimestampBindExpression and precision verification logic
plugin/trino-exasol/src/main/java/io/trino/plugin/exasol/ExasolClient.java
Add comprehensive timestamp tests in TestExasolTypeMapping
  • Introduce testTimestamp covering multiple precisions and time zones
  • Add DST gap and overlap scenarios for America/Bahia_Banderas
  • Implement testUnsupportedTimestampValues for boundary and invalid cases
  • Add helper methods for unsupported definitions, insert values, and DST-gap resolution
plugin/trino-exasol/src/test/java/io/trino/plugin/exasol/TestExasolTypeMapping.java
Update documentation to include TIMESTAMP(n) mapping
  • Add TIMESTAMP(n) entry to type mapping table in exasol.md
docs/src/main/sphinx/connector/exasol.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions bot added docs exasol Exasol connector labels Oct 15, 2025
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@skyglass
Copy link
Member Author

  • 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.

MAX_EXASOL_TIMESTAMP_PRECISION is 9, butTimestampType.MAX_PRECISION is 12, so we have to create a separate constant.
We still need to check for precision <= MAX_EXASOL_TIMESTAMP_PRECISION, because there shouldn't be any precision more than 9. It would mean some programmatic error, because all data comes from Exasol and Exasol doesn't support TIMESTAMP columns with precision > 9

@skyglass skyglass force-pushed the feature/724_only_timestamp_data_type branch from 70b19d8 to a417a34 Compare October 15, 2025 15:56
Copy link
Contributor

@chenjian2664 chenjian2664 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

FULL_PUSHDOWN);
}

private static LongReadFunction longTimestampReadFunction(TimestampType timestampType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please verify the timestamp precision is in the expected range


private static LongWriteFunction longTimestampWriteFunction(TimestampType timestampType)
{
return new LongWriteFunction()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

@chenjian2664
Copy link
Contributor

@ebyhr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants