Skip to content

SAP HANA connector

Dosi compiles SAP HANA Database SQL with the hana dialect and executes it through SAP's official HDBODBC client. The Rust ODBC wrapper is community software; the database client and wire protocol implementation come from SAP. No Java runtime, JDBC bridge, or Python SDK is required by Dosi.

Generated metric and detail queries quote their public output aliases so result column names match semantic bindings exactly, including case. Internal CTE aliases and physical identifiers retain their normal HANA resolution. Standard NULLIF expressions can be used in Datus compose derivations.

Install the client

Install the ODBC package from SAP HANA Client downloads on the machine running Dosi. Match the client's operating system and CPU architecture to the Dosi executable or Python process: Linux x86-64 and macOS ARM64/x86-64 have SAP packages. An ARM64 Mac running an Intel Python process needs the Intel client. The database server can run on another machine.

Use the absolute library path in odbc_driver, or export DOSI_HANA_ODBC_DRIVER. Linux uses libodbcHDB.so; macOS uses libodbcHDB.dylib. A registered HDBODBC driver is also accepted. Dosi's Unix builds bundle the ODBC driver manager; the proprietary SAP library is installed separately and loaded only when a HANA connection opens. SQL compilation and other database connectors do not require an SAP installation.

Connection profile

datasources:
  hana:
    type: hana
    host: hana.internal
    port: 39041
    username: ANALYTICS_READER
    password: ${HANA_PASSWORD}
    database: HXE
    schema: ANALYTICS
    odbc_driver: /opt/sap/hdbclient/libodbcHDB.so
    encrypt: true
    ssl_validate_certificate: true
    ssl_trust_store: /etc/dosi/hana-ca.pem
    ssl_host_name_in_certificate: hana.internal

The same datasource mapping works in a Datus agent.yml and Python's runtime connections mapping. database selects the tenant; table references use schema.table, never tenant.schema.table. Unqualified tables use the configured schema, or the authenticated user's default schema when omitted. Quoted identifiers preserve their case.

Setting Default Meaning
port 39041 Set your tenant SQL port explicitly, usually 443 for HANA Cloud.
database unset Optional tenant connection target, independent of the SQL namespace.
schema user default Session schema; required for user-store authentication.
userkey unset SAP hdbuserstore key; excludes username and password.
odbc_driver environment / HDBODBC SAP ODBC library path or registered driver name.
encrypt true Require an encrypted connection.
ssl_validate_certificate true Validate the server certificate.
ssl_trust_store client default CA trust-store path passed to SAP's client.
ssl_host_name_in_certificate endpoint host Expected certificate hostname, useful with a tunnel.
communication_timeout_seconds 60 Login and communication timeouts.
timeout_seconds 30 ODBC statement timeout.
max_result_rows 10000 Materialized result row budget.
max_result_bytes 16777216 UTF-8 cell and column-name budget; NULL costs one byte.

Positive timeout/budget settings are required. Exceeding either result budget returns an error and discards the result; Dosi never returns a truncated answer. LOBs are fetched in bounded chunks. Binary columns become lowercase hex text; exact decimals too wide for f64 remain text, while approximate numbers remain numeric. Timestamp fractional precision is retained.

TLS verification is enabled unless explicitly disabled in the profile. A self-signed test instance needs its CA in ssl_trust_store. There is no automatic retry with encryption or certificate validation disabled.

SAP secure user store

Create a key with SAP's hdbuserstore on the runtime machine under the same OS identity as Dosi. Then replace the password fields with:

datasources:
  hana:
    type: hana
    userkey: ANALYTICS_READONLY
    schema: ANALYTICS
    odbc_driver: /opt/sap/hdbclient/libodbcHDB.so
    encrypt: true
    ssl_validate_certificate: true

The ODBC connection uses SAP's serverNode=@KEY convention. The store owns the endpoint and credentials. Dosi does not create, copy, or rotate a production store. Install the full SAP HANA Client if you need its hdbuserstore tool. See SAP's user-store documentation.

SQL and feature boundaries

Supported paths include native model expressions, metrics, ordinary grouping, filters, ordering, limits, detail queries, and the shared row-to-Arrow result conversion. For date operations, author verified HANA functions such as ADD_DAYS, ADD_MONTHS, DAYS_BETWEEN, SECONDS_BETWEEN, TO_DATE, and TO_VARCHAR in expressions tagged HANA.

Portable models support day/week/month/quarter/year buckets, D-FORMAT date parsing, calendar offsets, and the time comparisons built from them. Weeks start on Monday. Unit-first DATEDIFF supports day/hour/minute/second boundary counts; native DAYS_BETWEEN retains its elapsed-whole-days semantics. Portable averages and statistical inputs use HANA decimal floating point (TO_DECIMAL, up to 34 significant digits), avoiding an unconditional binary DOUBLE conversion. An explicit floating cast keeps its requested type. This does not guarantee lossless aggregation of every DECIMAL(38,s) input.

Statistical windows, CUME_DIST, and NTH_VALUE use native HANA functions. Covariance windows use correlation and pairwise standard deviations with the same frame and NULL-pair exclusion. Cumulative RANGE uses HANA's implicit ordered frame, preserving peers; other explicit RANGE bounds are rejected.

Unsupported SQL generation returns dialect_unsupported_feature (or the existing dialect_unsupported_window_function) before a database query is sent. Dosi lowers portable expressions before execution and does not retry rejected queries through another dialect. Native functions in HANA-tagged expressions retain their native semantics.

Each execute operation owns a fresh connection. Batch execution runs ordinary semicolon-separated DDL/DML on one connection with autocommit; it is not an atomic migration or a SQLScript block parser. Send a complete SQLScript block as one statement when using a low-level execution API.

Errors and builds

Execution failures distinguish configuration, authentication, connectivity, timeouts, driver failures, and SQL rejection. Public diagnostics retain the SQLSTATE and SAP native error code, without echoing the driver's raw SQL or connection text. A missing client is a configuration error with an installation hint. Compiling SQL or running a dry run does not validate connectivity.

Build from source with exec-hana, exec-all-lean, or exec-all. Python wheels built from this source include the executor through exec-all. Existing published wheels acquire HANA support only after a new release; installing the SAP client alone does not add a dialect to an older wheel.