A pure-Go database/sql driver for
HSQLDB / HyperSQL, speaking the native HSQLDB binary network protocol over
TCP (hsql:// and hsqls://). No JDBC, no CGo, no external dependencies — it
talks the wire protocol directly.
Status: alpha (v0). The common path — connect, query, prepared statements, transactions, the standard SQL types, result paging, generated keys (
LastInsertId), and reading/writing CLOB/BLOB values — is implemented and tested end-to-end against HSQLDB 2.7.4. APIs and behavior may change. Try it, report issues; don't bet production on it yet.
import (
"database/sql"
_ "github.com/rennerdo30/go-hsql"
)
db, err := sql.Open("hsql", "hsql://SA@localhost:9001/mydb")hsql://[user[:password]@]host[:port]/dbAlias[?param=value&...]
hsqls://... # same, over TLS
hostdefaults tolocalhost,portto9001.userdefaults toSA(HSQLDB's default administrative user).dbAliasis the server-side database alias (the--dbname.Nthe server was started with), not a file path.
Query parameters:
| Param | Meaning | Default |
|---|---|---|
zone |
session time-zone id sent at connect | UTC |
tzoffset |
session time-zone offset from UTC, in seconds | 0 |
fetchsize |
rows per result-set block (0 = all at once) | 0 |
tlsconfig |
registered TLS config name for hsqls:// |
unset |
- Connect / authenticate / ping over the native protocol (compat version 2.x).
- Direct statements (
db.Exec,db.Query) and prepared statements with?parameters (db.Prepare, parameterizedQuery/Exec). - Transactions:
db.BeginTxwith commit/rollback (binarySETSESSIONATTR/ENDTRAN, matching the Java client), isolation levels, read-only. Driver-specific savepoint helpers are available throughdb.Conn(ctx).Raw. - Two-phase commit:
PrepareCommit(ctx)viadb.Conn(ctx).Raw. - Result-set block paging via
REQUESTDATAfor large results. - Type mapping: INTEGER, BIGINT, SMALLINT, TINYINT, REAL/FLOAT/DOUBLE, BOOLEAN,
CHAR/VARCHAR (Java modified-UTF-8, full Unicode), DECIMAL/NUMERIC (as string,
arbitrary precision), DATE/TIME/TIMESTAMP (± time zone), BINARY/VARBINARY,
BIT, UUID, INTERVAL, and ARRAY result values. NULLs via
sql.Null*. - Reading CLOB/BLOB values (resolved via the
LARGE_OBJECT_OPsub-protocol, fetched in chunks). - Writing CLOB/BLOB values via prepared-statement parameters.
Use
hsql.NewBlob(reader, length)/hsql.NewClob(reader, length)for streaming binds; pass a negative length when the stream length is unknown. - Structured ARRAY parameters via
hsql.NewArray(...); typed ARRAY result scanning viahsql.ScanArray(&slice). - Native batch execution via
db.Conn(ctx).Raw: direct-SQL (ExecBatch) and prepared-statement (ExecPreparedBatch) usingBATCHEXECDIRECT/BATCHEXECUTE. - Statement cancellation: context cancel sends a protocol
SQLCANCELon a side connection (like the Java client) so the server aborts the running statement. LastInsertIdvia generated keys (works forIDENTITYcolumns on both direct and prepared inserts).- Column introspection via
sql.Rows.ColumnTypes()(type name, scan type, nullability, length, decimal precision/scale). - Context cancellation / deadlines, and
ErrBadConnhandling for pool health. - Errors surface as
*hsql.ErrorcarryingMessage,SQLState,ErrorCode.
Interoperability with a real HSQLDB Java server is proven: the entire test suite
runs against the actual org.hsqldb server. The wire protocol, transaction
control, LOBs, batches, generated keys, cancellation, and 2PC use the same
messages the reference Java client sends.
Remaining differences (all either niche or with no database/sql equivalent):
- Scrollable / updatable result sets (
UPDATE_RESULT) —database/sqlis forward-only, so these have no equivalent and are not implemented. - Stored-procedure OUT parameters —
CALLstatements that return result sets or update counts work via the normal paths; bound OUT parameters are not exposed (also adatabase/sqllimitation). - ARRAY results are delivered as text (
[a,b,c]); usehsql.ScanArrayfor typed slices. The text form is ambiguous for string elements containing commas — use typed numeric/boolean arrays for lossless results. - XA / distributed transactions — single-connection 2PC (
PrepareCommit) is supported; thejavax.transactionXA resource model has no Go equivalent.
The protocol was reverse-engineered from the HSQLDB 2.7.4 Java source. The test
suite runs against a real server: the source is cloned and compiled to a jar
under .hsqldb/ (git-ignored), and integration tests boot it automatically
(skipping if Java or the jar are absent).
go test ./... # unit + integration (needs Java + .hsqldb/hsqldb.jar)
go test ./internal/... # protocol codec unit tests only (no server)
The driver code is original. .hsqldb/ contains a local copy of the HSQLDB
project (BSD-style HyperSQL license) used only as reference and as a test
server; it is git-ignored and not distributed with this driver.