Skip to content

test(contrib/drivers/sqlite): expand test coverage to the MySQL baseline + 2 driver fixes - #4892

Open
lingcoder wants to merge 3 commits into
gogf:masterfrom
lingcoder:test/sqlite-driver-test-coverage
Open

lingcoder wants to merge 3 commits into
gogf:masterfrom
lingcoder:test/sqlite-driver-test-coverage

Conversation

@lingcoder

@lingcoder lingcoder commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

ref #4689

Summary

Brings the SQLite driver up to the MySQL baseline. Test functions go from 161 to 561:

  • the remaining feature suites ported from MySQL, every function keeping the name of its MySQL counterpart;
  • sqlite_z_unit_feature_sqlite_test.go, 35 functions for behaviour that is SQLite's own: storage classes and typeof, WITHOUT ROWID, JSON1, window functions, CTEs, RETURNING, ON CONFLICT, INSERT OR IGNORE/REPLACE, LIMIT -1, last_insert_rowid(), EXPLAIN QUERY PLAN, date/time functions, RANDOM() ordering, the extra DSN pragmas.

Nothing under database/ is touched.

Four suites are not ported, on purpose:

Suite Why
master_slave SQLite has no replication
lock no FOR UPDATE / FOR SHARE; LockUpdate() yields invalid SQL
partition Model.Partition() is a no-op on every driver (#4826); a suite of skips asserts nothing
issue reproduces MySQL-specific reports

Test_Model_Schema1/2 are omitted for the same reason as master_slave.

Where SQLite defines behaviour differently, the expectations follow SQLite, verified by running rather than reasoned about: one isolation level, database is locked in place of deadlocks, storage classes in place of declared types, JSON1 functions in place of a JSON column type, busy_timeout + WAL for the multi-connection scenarios.

Bugs found

Porting surfaced five. Two are fixed here because the tests cannot pass without them and the fix is confined to the SQLite drivers; the others are tracked separately.

1. Union / UnionAll never worked on SQLite. The core builds (SELECT ...) UNION (SELECT ...); SQLite forbids parentheses around compound operands. Not one existing test touched Union, so this was never noticed. Fixed in DoFilter of both sqlite and sqlitecgo: each operand becomes SELECT * FROM (...), which keeps a per-operand ORDER BY/LIMIT legal too. Parentheses are matched, not pattern-guessed; string literals are skipped.

2. WhereExists / WhereNotExists fail on SQLite. Wheref("EXISTS (?)", subQuery) expands to EXISTS ((SELECT ...)), which SQLite rejects. Fixed in the same DoFilter: the doubled pair is reduced to one.

3. CacheOption.Force never caches an empty result — #4891. All() returns a nil Result for no rows, which skips the Force branch in saveSelectResultToCache. Core logic, reproduced identically on MySQL. Every driver carries an empty Test_Model_Cache_Force for this reason, with a note that misstates why; this one is the same stub but says why. The scenario gets asserted, in every driver, with the fix for #4891.

4. A column holding mixed storage classes is typed from its first row — #4895. Once the first row is an INTEGER, later REAL / TEXT / BLOB rows of the same column are coerced to int64 and read back as 1 / 0. Core logic (the ScanType fast path in columnValueToLocalValue), and specific to the modernc driver, which reports the first row's Go type as the column's scan type; sqlitecgo is not affected. Test_SQLite_Type_StorageClass_MixedRows is kept as a stub pointing to #4895 and gets its assertions with that fix; the per-row single-value reads are asserted in Test_SQLite_Type_StorageClass_Typeof.

5. A POINT column reads back as 0 — #4842, fixed by #4882 which has since merged; Test_DataType_Geometry_Point passes on the rebased branch.

Verification

Full suite on Windows 11 with an isolated temp dir, -count=1, on d924ae001:

561 functions: 561 pass, 0 fail

The DoFilter rewrite has its own unit tests (sqlite_z_unit_do_filter_test.go) covering the shapes the core emits, nested sub-queries, and parentheses inside string literals. The existing sqlitecgo suite passes with the shared rewrite.

@lingcoder
lingcoder requested review from gqcn and hailaz and removed request for hailaz September 23, 2026 22:10
@lingcoder lingcoder changed the title test(contrib/drivers/sqlite): port the MySQL feature suites test(contrib/drivers/sqlite): expand test coverage to the MySQL baseline + 2 driver fixes Sep 23, 2026
@lingcoder
lingcoder force-pushed the test/sqlite-driver-test-coverage branch from 71228ad to 9b621a0 Compare September 23, 2026 22:27
Adds the 28 feature suites the MySQL baseline has and SQLite lacked, taking the
driver from 158 to 521 test functions with the same names as their MySQL
counterparts. Four suites are not added: master_slave and lock have no SQLite
counterpart, partition is a no-op on every driver (gogf#4826), and the MySQL issue
suite reproduces MySQL-only reports. Test_Model_Schema1/2 are omitted for the
same reason as master_slave.

Expectations that differ from MySQL are the ones SQLite defines differently:
a single isolation level, `database is locked` instead of deadlocks, storage
classes instead of declared types, JSON1 functions instead of a JSON column type.

Test_Model_Cache_Force stays the stub every other driver carries: CacheOption.Force
never caches an empty result (gogf#4891), and the note here says so.
…into forms SQLite accepts

Union and UnionAll never worked on SQLite: the core builds them as
`(SELECT ...) UNION (SELECT ...)`, and SQLite forbids parentheses around the
operands of a compound SELECT. WhereExists and WhereNotExists failed the same way:
`EXISTS (?)` with a sub-query argument expands to `EXISTS ((SELECT ...))`.

The driver now rewrites the statement in DoFilter, matching parentheses rather than
patterns: each compound operand becomes `SELECT * FROM (...)`, which also keeps a
per-operand ORDER BY or LIMIT legal, and the doubled parentheses of EXISTS are
reduced to one pair. The sqlitecgo driver has the same defect and gets the same
rewrite in its own change.
@lingcoder
lingcoder force-pushed the test/sqlite-driver-test-coverage branch from 84fcc57 to 45e8dab Compare September 24, 2026 03:40

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant