class

SqlTest

abstract class SqlTest : Test

SqlTest is the base for the tests that run against a live database. It is abstract, so fant skips it; the concrete subclasses at the bottom of this file bind it to a Dialect.

Each test method gets a fresh instance, a fresh connection, and drops whatever tables it created. No test may depend on another's state.

fields arrayTable

Postgres array table

batchAutoTable

batchTable

Batch tables

db

Connection for the current test method

missingTable

A table that is never created

valsTable

The main test table

methods createRawTable

Create a table from raw ddl, and register it to be dropped during teardown

createVals

Create the main test table

insert

Insert a row built from a column-name:value map and return whatever Statement.execute returned

insertVals

Insert into the main test table and return the auto-generated key

ints

The single Int column selected by the given sql

rowCount

Number of rows in the main test table

sampleVals

A full row of values for the main test table

selectById

The row in the main test table with the given key

selectOne

The one row in the main test table whose v_str is the given key

setup

strs

The v_str values in the main test table, sorted

teardown

testArrays

Postgres array columns map to Fantom Lists

testBatchExecutor

testBatchKeys

Whether a batch insert yields keys depends on both the table and the driver, so this pins down all four corners of that

testBatchUpdate

testBuf

Binary round-trips through the setBinaryStream path in setParameters

testEmptyResult

testErrors

Everything the driver rejects should surface as SqlErr, not as a raw SQLException or a null

testEscapes

An "@" inside quoted text is literal, not a parameter

testExecute

Statement.execute returns one of three shapes depending on the sql

testGenerateKeysOff

testInsertAndSelect

testJsonbOperator

So must the postgres jsonb containment operator

testLimit

testMeta

testMissingParam

A parameter missing from the map currently binds as null rather than raising, so a typo in a param name is silent

testNulls

testPrepared

testQueryEach

testQueryTimeout

testQueryTimeoutFromPool

testSmoke

Exercise the fixture machinery end to end

testTransactions

testTypeRoundTrip

Round-trip a set of values through every column of the main test table, so that a failure names the exact type and value that broke

testUserVars

A mysql session variable must be escaped inside a prepared statement

typeCases

Values exercised by testTypeRoundTrip, keyed by logical type

valEq

Compare two cell values

verifyNullsExcept

Verify every cell in the row is null, apart from the named columns

verifyRow

Verify a row's cells against a column-name:value map

arrayTable const Str : arrayTable

Postgres array table; created with raw ddl since it never runs elsewhere

batchAutoTable const Str : batchAutoTable

batchTable const Str : batchTable

Batch tables; see Dialect.batchCols and Dialect.batchAutoCols

createRawTable Void createRawTable(Str name, Str ddl)

Create a table from raw ddl, and register it to be dropped during teardown. For feature-gated tests, where a portable ColDef schema would be pointless because the test only ever runs on one database.

createVals Void createVals()

Create the main test table

db SqlConn? : db

Connection for the current test method

insert Obj insert(Str table, Str:Obj? vals)

Insert a row built from a column-name:value map and return whatever Statement.execute returned. Columns are emitted in sorted order so the generated SQL is deterministic.

insertVals Int insertVals(Str:Obj? vals)

Insert into the main test table and return the auto-generated key

ints Int[] ints(Str sql)

The single Int column selected by the given sql

missingTable const Str : missingTable

A table that is never created

rowCount Int rowCount()

Number of rows in the main test table

sampleVals Str:Obj? sampleVals()

A full row of values for the main test table.

Note the float values are exactly representable in binary32, so that v_f32 round-trips through a 4 byte column without widening error, and the times carry no fractional seconds, which mysql datetime truncates. Probing the inexact cases belongs in a dedicated type test.

selectById Row selectById(Int id)

The row in the main test table with the given key

selectOne Row selectOne(Str key)

The one row in the main test table whose v_str is the given key

setup virtual Void setup()

strs Str[] strs()

The v_str values in the main test table, sorted

teardown virtual Void teardown()

testArrays Void testArrays()

Postgres array columns map to Fantom Lists; see SqlUtil.fanToSqlObj and SqlUtil.ToFanList.

testBatchExecutor Void testBatchExecutor()

testBatchKeys Void testBatchKeys()

Whether a batch insert yields keys depends on both the table and the driver, so this pins down all four corners of that.

testBatchUpdate Void testBatchUpdate()

testBuf Void testBuf()

Binary round-trips through the setBinaryStream path in setParameters

testEmptyResult Void testEmptyResult()

testErrors Void testErrors()

Everything the driver rejects should surface as SqlErr, not as a raw SQLException or a null

testEscapes Void testEscapes()

An "@" inside quoted text is literal, not a parameter. TokenizerTest covers this at the unit level; here we prove the sql actually runs.

testExecute Void testExecute()

Statement.execute returns one of three shapes depending on the sql

testGenerateKeysOff Void testGenerateKeysOff()

testInsertAndSelect Void testInsertAndSelect()

testJsonbOperator Void testJsonbOperator()

So must the postgres jsonb containment operator; see pod-doc "Escape Sequences". No table is needed, so the sql can be a raw dsl literal.

testLimit Void testLimit()

testMeta Void testMeta()

testMissingParam Void testMissingParam()

A parameter missing from the map currently binds as null rather than raising, so a typo in a param name is silent. This pins the current behavior; it is not necessarily the behavior we want.

testNulls Void testNulls()

testPrepared Void testPrepared()

testQueryEach Void testQueryEach()

testQueryTimeout Void testQueryTimeout()

testQueryTimeoutFromPool Void testQueryTimeoutFromPool()

testSmoke Void testSmoke()

Exercise the fixture machinery end to end: connect, create, describe, insert, select, and verify both metadata and values.

testTransactions Void testTransactions()

testTypeRoundTrip Void testTypeRoundTrip()

Round-trip a set of values through every column of the main test table, so that a failure names the exact type and value that broke. This is the conformance matrix: what each database can actually store and hand back unchanged.

testUserVars Void testUserVars()

A mysql session variable must be escaped inside a prepared statement

typeCases Str:Obj?[] typeCases()

Values exercised by testTypeRoundTrip, keyed by logical type. Null is covered separately by testNulls.

Constraints these values respect:

  • f32 values are exactly representable in binary32 and carry no more than 6 significant decimal digits. Exactness alone is not enough: mysql float round-trips through roughly 6 significant digits, so 2^24 comes back as 16777200 rather than 16777216
  • dec values carry the scale of decimal(9,2). Decimal equality is scale sensitive, since FanDecimal.equals delegates to BigDecimal.equals, so 0d and 0.00d are not equal
  • dt and time values are whole seconds, which mysql datetime and time truncate to by default
  • char values are exactly 4 chars, because postgres bpchar pads to the declared width while mysql char strips trailing spaces

valEq Bool valEq(Obj? a, Obj? b)

Compare two cell values. Buf does not define value equality, so binary cells are compared by content.

valsTable const Str : valsTable

The main test table; see Dialect.valsCols

verifyNullsExcept Void verifyNullsExcept(Row row, Str[] except)

Verify every cell in the row is null, apart from the named columns

verifyRow Void verifyRow(Row row, Str:Obj? expected)

Verify a row's cells against a column-name:value map. Only the named columns are checked.

Haxall 4.0.7 ∙ 27-Oct-2026 09:10 EDT