Add Exasol ODBC dialect#386
Open
mkcorneli wants to merge 1 commit intoposit-dev:mainfrom
Open
Conversation
Introduce ExasolDialect implementing SqlDialect, plus an `exasol` branch
in OdbcReader's detect_dialect(). Lets the existing generic OdbcReader
work correctly against Exasol with no new reader implementation —
parallel in scope to the existing Snowflake dialect.
Connection string:
odbc://Driver=Exasol;EXAHOST=host:8563;EXAUID=user;EXAPWD=pass
The 11 method overrides in src/reader/exasol.rs were each chosen to fix
a default that is rejected or wrong on Exasol. Override SQL was verified
against exasol/docker-db:2025.2.0-arm64dev.0 by a separate probe-test
campaign maintained on a sibling branch (run with EXASOL_TEST_URL set;
test module: src/reader/exasol_probes.rs, not included in this PR).
Behavior justifications:
- string_type_name -> VARCHAR(2000000)
Bare VARCHAR is rejected in DDL on Exasol; an explicit length is
required. 2_000_000 is Exasol's practical max — a smaller N risks
truncating Polars/Arrow string columns at register() time.
- time_type_name -> VARCHAR(32)
Exasol has no SQL TIME type. `TIME '01:02:03'` raises
`Feature not supported: SQL-Type TIME`. VARCHAR-for-TIME mirrors the
SqliteDialect precedent at src/reader/sqlite.rs:45-47; consumers do a
Polars/Arrow-side reparse for Vega-Lite temporal axes.
- sql_greatest / sql_least
Exasol has native GREATEST/LEAST; emit those instead of the ANSI CASE
fallback for shorter, more readable SQL.
- sql_date_literal -> ADD_DAYS(DATE '1970-01-01', N)
Default `INTERVAL N DAY` (unquoted) is rejected by Exasol's parser.
ADD_DAYS sidesteps interval syntax entirely and pairs naturally with
ADD_SECONDS below.
- sql_datetime_literal -> ADD_SECONDS(TIMESTAMP '...', secs)
Default `INTERVAL N MICROSECOND` fails — MICROSECOND is not a valid
Exasol interval subtype (Exasol supports YEAR/MONTH/DAY/HOUR/MINUTE/
SECOND only). Note: Exasol's TIMESTAMP itself truncates to millisecond
precision; sub-millisecond input is silently zeroed by the database.
This is documented in the file's top doc-block.
- sql_time_literal -> 'HH:MM:SS.uuuuuu' string
Default emits TIME literal + NANOSECOND interval, both unsupported.
Time travels as VARCHAR(32) per time_type_name, so emitting an
ISO-8601 string matches the storage contract.
- sql_list_catalogs / sql_list_schemas / sql_list_tables /
sql_list_columns
Exasol has no information_schema views; the ANSI defaults raise
`object not found`. Substituted with SYS.EXA_SCHEMAS, SYS.EXA_ALL_TABLES,
and SYS.EXA_ALL_COLUMNS. Catalog filters are ignored (Exasol has no
catalog tier above schemas). Single quotes in schema/table arguments
are escaped via doubling.
There is a separate, pre-existing OdbcReader Int32 buffer issue that
affects DECIMAL-returning function results (e.g. GREATEST/LEAST over
DECIMAL columns with precision < 10). The dialect's emitted SQL is
correct; the issue is in the result-binding layer and will be filed as
its own upstream issue.
Tests (all in src/reader/exasol.rs and src/reader/odbc.rs):
- 11 dialect tests, one per override, asserting exact SQL strings.
- Single-quote escaping verified for sql_list_tables / sql_list_columns.
- test_detect_dialect extended with `Driver=Exasol;...` recognition
(existing Snowflake / PostgreSQL / generic-fallback assertions
preserved).
- New test_detect_dialect_exasol_curly_form covers `Driver={Exasol};`
and uppercase `DRIVER={EXASOL};` mixed-case forms.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an
ExasolDialectand anexasolbranch inOdbcReader::detect_dialect(). Lets the existing genericOdbcReaderwork correctly against Exasol with no new reader implementation — same scope as the existing Snowflake dialect.Closes #330. Related context on a possible Arrow/ADBC path: #331 (this PR uses the ODBC path; ADBC remains open).
Connection string:
Why each override exists
The 11 method overrides in
src/reader/exasol.rseach fix a default that is rejected or wrong on Exasol. Override SQL was verified againstexasol/docker-db:2025.2.0-arm64dev.0by a probe-test campaign maintained on a sibling branch (test modulesrc/reader/exasol_probes.rs, runs only whenEXASOL_TEST_URLis set; not included in this PR to keep the diff focused).string_type_nameVARCHARrejected in DDLVARCHAR(2000000)(Exasol's practical max)time_type_nameTIME '01:02:03'raises Feature not supported: SQL-Type TIMEVARCHAR(32), mirroringSqliteDialectprecedentsql_greatest/sql_leastGREATEST/LEASTsql_date_literalINTERVAL N DAY(unquoted) rejected by Exasol's parserADD_DAYS(DATE '1970-01-01', N)sql_datetime_literalMICROSECONDis not a valid Exasol interval subtypeADD_SECONDS(TIMESTAMP '...', secs)— see TIMESTAMP-precision note belowsql_time_literalTIMEliteral andNANOSECONDinterval unsupported'HH:MM:SS.uuuuuu'ISO-8601 string (matchestime_type_namestorage contract)sql_list_catalogs/_schemas/_tables/_columnsinformation_schemaviewsSYS.EXA_SCHEMAS,SYS.EXA_ALL_TABLES,SYS.EXA_ALL_COLUMNSNote on TIMESTAMP precision: Exasol's
TIMESTAMPtruncates to millisecond precision; sub-millisecond fractional input is silently zeroed by the database. This cannot be worked around at the dialect layer — documented at the top ofsrc/reader/exasol.rs.Catalog tier: Exasol treats schemas as the top tier.
sql_list_catalogssurfaces every schema as a top-level catalog;sql_list_schemasignores its catalog argument.Out of scope
ExasolReader. GenericOdbcReaderworks fine; no need for a new reader implementation.exarrow-rspath. Tracked separately in Arrow support in future plans? #331.OdbcReaderInt32 buffer issue for DECIMAL with precision < 10. AffectsGREATEST/LEASTresult consumption when the operands are DECIMAL columns. The dialect's emitted SQL is correct; the issue is in the result-binding layer insrc/reader/odbc.rs. Will be filed as a separate issue.Test plan
cargo test --features odbc --lib— 11 new dialect tests + extended detection test pass; full lib suite regression-clean (1335 tests pass before + after).cargo fmt --all -- --check— clean.cargo clippy --features odbc --lib— no new warnings (one pre-existing warning insrc/execute/scale.rs:254is unrelated, introduced in No-polars in ggsql #350).exasol/docker-db:2025.2.0-arm64dev.0(via the sibling probe-test campaign, not part of this PR).