Skip to content

test(contrib/drivers/sqlitecgo): expand test coverage to the MySQL baseline + 3 driver fixes - #4897

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

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

Conversation

@lingcoder

Copy link
Copy Markdown
Contributor

ref #4689

Summary

Mirrors to the cgo SQLite driver the suites the pure-Go driver receives in #4892, so both drivers are held to the same assertions over the same API surface: 160 → 561 test functions, every added function keeping the name of its MySQL counterpart, plus a sqlitecgo-specific suite of 35. Nothing under database/ is touched; no pre-existing sqlitecgo test file is modified.

The suites left out are the same as in #4892, for the same reasons (master_slave, lock, partition — #4826, issue). No expectation differs from the sqlite driver's: mattn/go-sqlite3 and modernc agree on every case these suites cover.

Driver defects fixed

Running the mirrored suites showed three things that never worked on this driver. All three are omissions relative to the sqlite driver, which has each of them.

1. Union / UnionAll / WhereExists / WhereNotExists fail — the core builds (SELECT ..) UNION (SELECT ..) and EXISTS ((SELECT ..)), which SQLite rejects. Same DoFilter rewrite as #4892: each compound operand becomes SELECT * FROM (...), doubled EXISTS parentheses are reduced to one pair. Parentheses are matched, not pattern-guessed; unit-tested in sqlitecgo_z_unit_do_filter_test.go.

2. OrderRandom() emits RAND() — the driver had no OrderRandomFunction() override, so the MySQL default went through and SQLite answered no such function: RAND. Now RANDOM(), as in sqlite_order.go.

3. ConfigNode.Extra pragmas were silently ignored — sqlitecgo_open.go rendered them as _pragma=key(value), which is modernc's DSN syntax, copied from the sqlite driver. mattn/go-sqlite3 takes _<pragma>=<value> (_busy_timeout, _journal_mode, _foreign_keys, _synchronous, _cache_size, …). So busy_timeout and journal_mode=WAL never applied, and every multi-connection scenario died with database is locked. Now _%s=%s; Test_Open_Extra and Test_SQLiteCgo_Extra_Pragmas read the pragmas back.

sqlitecgo-specific suite

sqlitecgo_z_unit_feature_sqlitecgo_test.go is the sqlite driver's feature suite (:memory: links, Extra pragmas taking effect, INSERT OR IGNORE / INSERT OR REPLACE / ON CONFLICT DO UPDATE SQL shapes and effects, RETURNING, CTE, EXCEPT / INTERSECT, window functions, JSON1 including json_each, storage classes and typeof(), WITHOUT ROWID, STRICT, date functions, last_insert_rowid(), EXPLAIN QUERY PLAN, two WAL handles on one file) run against mattn. One difference from #4892 worth noting: the mixed-storage-class case that loses data on modernc (#4895) does not reproduce on mattn — Test_SQLiteCgo_Type_StorageClass_MixedRows passes here and pins the correct behaviour.

Verification

Windows 11, CGO_ENABLED=1, isolated temp dir, -count=1 -race as CI does:

561 functions: 561 pass, 0 fail   (112 s)

…seline

Mirrors the suites the sqlite driver received in gogf#4892, so that both SQLite
drivers are held to the same assertions over the same API surface. Test
functions in this package go from 160 to 523, every added function keeping
the name of its MySQL counterpart.

No expectation differs from the sqlite driver's. The files are the sqlite
driver's, with only the package name changed: mattn/go-sqlite3 and modernc's
driver agree on every case these suites cover, so nothing had to be re-judged
for cgo. The suites the sqlite driver leaves out are left out here for the
same reasons: master_slave (no replication), lock (no FOR UPDATE / FOR SHARE),
partition (Model.Partition is a no-op on every driver, gogf#4826), and issue
(reproduces MySQL-specific reports).

Nothing under database/ is touched, and none of the pre-existing sqlitecgo
test files are modified.
…es, order randomly with RANDOM(), and pass Extra pragmas in the DSN form mattn accepts

Three defects, each of which makes a documented gdb API unusable on this
driver. None of them was covered by a test before, which is why all three
survived.

Union and UnionAll never worked. The core builds a compound query as
`(SELECT ...) UNION (SELECT ...)`, and SQLite forbids parentheses around the
operands of a compound SELECT. DoFilter now wraps each operand as
`SELECT * FROM (...)`, which is legal and also keeps a per-operand ORDER BY or
LIMIT legal. WhereExists and WhereNotExists failed for a related reason:
Wheref expands to `EXISTS ((SELECT ...))`, and SQLite rejects the doubled
pair, so DoFilter reduces it to one. Parentheses are matched rather than
pattern-guessed, and quoted strings and identifiers are skipped. This is the
rewrite the sqlite driver received in gogf#4892, applied here unchanged.

OrderRandom emitted MySQL's RAND(), which SQLite does not have, so every
OrderRandom query failed with `no such function: RAND`. The driver now
overrides OrderRandomFunction to return RANDOM(), as the sqlite driver does.

ConfigNode.Extra was rendered into the DSN as `_pragma=key(value)`, which is
modernc's syntax and was copied from the sqlite driver. mattn/go-sqlite3
ignores DSN keys it does not know and reads pragmas as `_<pragma>=<value>`,
so no Extra entry ever reached the database: journal_mode=WAL and
busy_timeout were silently dropped, which left every multi-connection
scenario failing with `database is locked`. The DSN is now built in the form
mattn parses.
35 functions over what SQLite does that MySQL does not, all driven through
gdb rather than database/sql: memory databases and Extra pragmas, INSERT OR
IGNORE / OR REPLACE and ON CONFLICT DO UPDATE, RETURNING, CTEs including
recursive ones, EXCEPT / INTERSECT, window functions, the JSON1 functions and
operators, storage classes and typeof(), WITHOUT ROWID and STRICT tables, the
SQLite date functions, group_concat, iif, last_insert_rowid, RANDOM()
ordering, LIMIT -1, and EXPLAIN QUERY PLAN.

The suite is the sqlite driver's, renamed for this package, so the two
drivers are measured on the same ground. Every case behaves identically under
mattn, including Test_SQLiteCgo_Type_StorageClass_MixedRows: the first-row
column typing of gogf#4895 does not reproduce here, and the guard that reports it
stays in place so a regression would be named rather than merely failing.

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