Loading the parity record
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Parity / SQLite
Every number on this page was produced by running both implementations over the same cases: the real sqlite3 package pinned at 3.45.3 answers first, and its answer is the expectation the Go port is held to. Nothing is a hand-written expectation, so a new upstream release re-scores the port on its own. See SQLite for the port's own documentation. Source: github.com/malcolmston/sqlite.
Not a generic diagram: every node below names an artefact of this harness — the pinned package it installed, the runner files it started, the case files it streamed, and the counts it wrote out.
| Case group | Cases | Match | Mismatch | Group parity |
|---|---|---|---|---|
| functions | 85 | 60 | 25 | 70.6% |
| unsupported | 52 | 6 | 46 | 11.5% |
| types | 47 | 47 | 0 | 100.0% |
| ddl | 37 | 13 | 24 | 35.1% |
| select-basic | 37 | 37 | 0 | 100.0% |
| operators | 30 | 22 | 8 | 73.3% |
| aggregates | 26 | 22 | 4 | 84.6% |
| dml | 22 | 15 | 7 | 68.2% |
| null-logic | 21 | 21 | 0 | 100.0% |
| errors | 20 | 20 | 0 | 100.0% |
| params | 17 | 17 | 0 | 100.0% |
| joins | 15 | 6 | 9 | 40.0% |
| txn | 12 | 10 | 2 | 83.3% |
| bugs | 7 | 0 | 7 | 0.0% |
Every exported symbol of the upstream package, and what the port offers for it. The upstream list is derived mechanically, never from a README: sqlite3 -batch -init /dev/null :memory: \
"SELECT DISTINCT upper(name) FROM pragma_function_list ORDER BY 1;" # 193 names. A symbol with no case is untested, never a match.
| Upstream symbol | Go symbol | Status | Cases | Note |
|---|---|---|---|---|
| != operator | — | match | u-ne-bang | |
| -- line comment | — | match | u-comment-line | |
| /* block comment */ | — | match | u-comment-block | |
| 1.0/0 -> NULL | — | match | div-zero-real | |
| 1/0 -> NULL | — | match | div-zero-int | |
| ? as a LIKE pattern | — | match | param-like | |
| ? as LIMIT | — | match | param-limit | |
| ? bound to a BLOB | — | match | param-blob | |
| ? bound to NULL | — | match | param-null | |
| ? bound to NULL in a comparison | — | match | param-null-compare | |
| ? in a multi-row INSERT | — | match | param-insert-multi | |
| ? in DELETE | — | match | param-delete | |
| ? in HAVING | — | match | param-having | |
| ? in INSERT | — | match | param-insert | |
| ? in the SELECT list | — | match | param-select-list | |
| ? in UPDATE | — | match | param-update | |
| ? in WHERE (INTEGER) | — | match | param-where-int | |
| ? in WHERE (REAL) | — | match | param-where-real | |
| ? in WHERE (TEXT) | — | match | param-where-text | |
| ? inside an expression | — | match | param-expr | |
| ? inside IN (...) | — | match | param-in-list | |
| abs() | — | match | fn-abs-int | |
| abs() near INTEGER min | — | match | fn-abs-overflow | |
| abs() on TEXT | — | match | fn-abs-text | |
| abs() REAL | — | match | fn-abs-real | |
| abs(NULL) | — | match | fn-abs-null | |
| addition | — | match | add-int | |
| aggregate FILTER clause | — | missing | u-filter-clause | |
| aggregate in WHERE | — | match | err-agg-in-where | |
| aggregate over an expression | — | match | agg-expr | |
| aggregate used as a window function | — | missing | u-agg-over-window | |
| ALTER TABLE ... ADD COLUMN | — | missing | ddl-alter-add-column | |
| ALTER TABLE ... DROP COLUMN | — | missing | ddl-alter-drop-column | |
| ALTER TABLE ... RENAME COLUMN | — | missing | ddl-alter-rename-column | |
| ALTER TABLE ... RENAME TO | — | missing | ddl-alter-rename-table | |
| ANALYZE | — | missing | u-analyze | |
| ATTACH DATABASE | — | missing | u-attach | |
| AUTOINCREMENT | — | missing | ddl-autoincrement | |
| avg() | — | match | agg-avg | |
| avg() of integers is REAL | — | match | agg-avg-int-exact | |
| avg() over only NULLs | — | match | agg-avg-null-only | |
| backtick-quoted identifiers | — | missing | ddl-backtick-ident | |
| bare VALUES statement | — | missing | u-values-stmt | |
| BEGIN ... COMMIT persists | — | match | txn-commit-visible | |
| BEGIN ... ROLLBACK discards | — | match | txn-rollback-discards | |
| BEGIN TRANSACTION / COMMIT TRANSACTION as plain SQL | — | match | txn-raw-begin-transaction | |
| BEGIN/COMMIT as plain SQL statements | — | match | txn-raw-begin-sql | |
| BETWEEN ... AND | — | missing | u-between | |
| bitwise & | — | missing | u-bitand | |
| bitwise << | — | missing | u-shift-left | |
| bitwise >> | — | missing | u-shift-right | |
| bitwise | | — | missing | u-bitor | |
| bitwise ~ | — | missing | u-bitnot | |
| BLOB column round-trip | — | match | column-affinity-blob | |
| BLOB literal x'...' | — | match | type-blob-literal | |
| bracket-quoted identifiers | — | missing | ddl-bracket-ident | |
| CASE <expr> WHEN | — | missing | u-case-operand | |
| CASE WHEN ... THEN ... ELSE ... END | — | missing | u-case-when | |
| CASE with no ELSE | — | missing | u-case-no-else | |
| CAST in a SELECT list | — | missing | u-cast-expr | |
| CAST(... AS BLOB) | — | missing | fn-cast-blob | |
| CAST(... AS INTEGER) | — | missing | fn-cast-int | |
| CAST(... AS NUMERIC) | — | missing | fn-cast-numeric | |
| CAST(... AS REAL) | — | missing | fn-cast-real | |
| CAST(... AS TEXT) | — | missing | fn-cast-text | |
| changes() | — | missing | fn-changes | |
| char() | — | match | fn-char-one | |
| char() variadic | — | match | fn-char-many | |
| char() with no arguments | — | match | fn-char-none | |
| CHECK column constraint | — | missing | ddl-check-ok | |
| CHECK violated (must fail) | — | match | ddl-check-violation | |
| coalesce() | — | match | coalesce-first, fn-coalesce-fn | |
| coalesce() all NULL | — | match | coalesce-all-null | |
| COLLATE column constraint | — | missing | ddl-collate | |
| COLLATE in an expression | — | missing | u-collate-expr | |
| composite PRIMARY KEY | — | missing | ddl-pk-composite | |
| correlated scalar subquery | — | missing | u-subquery-correlated | |
| count(*) | — | match | agg-count-star | |
| count(*) over no rows -> 0 | — | match | agg-count-empty | |
| count(column) skips NULL | — | match | agg-count-col | |
| count(DISTINCT text) | — | match | agg-count-distinct-text | |
| count(DISTINCT x) | — | match | agg-count-distinct | |
| CREATE INDEX | — | missing | ddl-create-index | |
| CREATE TABLE ... AS SELECT | — | missing | ddl-create-table-as | |
| CREATE TABLE duplicate (must fail) | — | match | ddl-duplicate | |
| CREATE TABLE IF NOT EXISTS | — | match | ddl-if-not-exists | |
| CREATE TABLE with typed and untyped columns | — | match | ddl-types | |
| CREATE TEMP TABLE | — | missing | ddl-temp-table | |
| CREATE TRIGGER | — | missing | ddl-create-trigger | |
| CREATE UNIQUE INDEX | — | missing | ddl-create-unique-index | |
| CREATE VIEW | — | missing | ddl-create-view | |
| CROSS JOIN | — | missing | join-cross-keyword | |
| date() | — | missing | fn-date | |
| date() with a modifier | — | missing | fn-date-modifier | |
| datetime() | — | missing | fn-datetime | |
| datetime(..., 'unixepoch') | — | missing | fn-datetime-unixepoch | |
| DEFAULT column constraint | — | missing | ddl-default | |
| DELETE ... LIMIT (needs SQLITE_ENABLE_UPDATE_DELETE_LIMIT) | — | match | delete-limit | |
| DELETE ... WHERE | — | match | delete-where | |
| DELETE from an unknown table | — | match | err-delete-no-table |
Every case the harness streamed to both runners, with the exact upstream symbol and Go symbol it exercised. A deliberate, documented difference is a deviation and is counted apart from a mismatch.
| Case | Group | Upstream symbol | Go symbol | Status | Note |
|---|---|---|---|---|---|
| agg-count-star | aggregates | count(*) | sqlite: count(*) | match | |
| agg-count-col | aggregates | count(column) skips NULL | sqlite: count(column) skips NULL | match | |
| agg-count-distinct | aggregates | count(DISTINCT x) | sqlite: count(DISTINCT x) | match | |
| agg-sum | aggregates | sum() | sqlite: sum() | match | |
| agg-sum-real | aggregates | sum() over REAL | sqlite: sum() over REAL | match | |
| agg-sum-empty | aggregates | sum() over no rows -> NULL | sqlite: sum() over no rows -> NULL | match | |
| agg-count-empty | aggregates | count(*) over no rows -> 0 | sqlite: count(*) over no rows -> 0 | match | |
| agg-avg | aggregates | avg() | sqlite: avg() | match | |
| agg-avg-int-exact | aggregates | avg() of integers is REAL | sqlite: avg() of integers is REAL | match | |
| agg-min | aggregates | min() aggregate | sqlite: min() aggregate | match | |
| agg-max | aggregates | max() aggregate | sqlite: max() aggregate | match | |
| agg-min-text | aggregates | min() over TEXT | sqlite: min() over TEXT | match | |
| agg-max-text | aggregates | max() over TEXT | sqlite: max() over TEXT | match | |
| agg-multi | aggregates | several aggregates in one SELECT | sqlite: several aggregates in one SELECT | match | |
| agg-expr | aggregates | aggregate over an expression | sqlite: aggregate over an expression | match | |
| group-by | aggregates | GROUP BY | sqlite: GROUP BY | match | |
| group-by-having | aggregates | GROUP BY ... HAVING | sqlite: GROUP BY ... HAVING | match | |
| group-by-having-sum | aggregates | HAVING over sum() | sqlite: HAVING over sum() | match | |
| group-by-two | aggregates | GROUP BY a, b | sqlite: GROUP BY a, b | match | |
| group-by-null | aggregates | GROUP BY groups NULLs together | sqlite: GROUP BY groups NULLs together | mismatch | |
| agg-distinct-sum | aggregates | sum(DISTINCT x) | sqlite: sum(DISTINCT x) | match | |
| agg-group-concat | aggregates | group_concat() | sqlite: group_concat() | mismatch | |
| agg-group-concat-sep | aggregates | group_concat(x, sep) | sqlite: group_concat(x, sep) | mismatch | |
| agg-total | aggregates | total() | sqlite: total() | mismatch | |
| agg-count-distinct-text | aggregates | count(DISTINCT text) | sqlite: count(DISTINCT text) | match | |
| agg-avg-null-only | aggregates | avg() over only NULLs | sqlite: avg() over only NULLs | match | |
| bug-left-join-unaliased | bugs | LEFT JOIN on an un-aliased table | sqlite: LEFT JOIN on an un-aliased table | mismatch | port bug: LEFT is consumed as the alias of t, so the join silently degrades to INNER and the unmatched rows vanish with no error |
| bug-left-join-unaliased-count | bugs | LEFT JOIN row count on an un-aliased table | sqlite: LEFT JOIN row count on an un-aliased table | mismatch | the same bug seen as a wrong count |
| bug-left-join-unaliased-nulls | bugs | LEFT JOIN unmatched rows | sqlite: LEFT JOIN unmatched rows | mismatch | upstream sees the unmatched left rows; the port sees none |
| bug-rowid-omitted-pk | bugs | INSERT omitting INTEGER PRIMARY KEY auto-assigns a rowid | sqlite: INSERT omitting INTEGER PRIMARY KEY auto-assigns a rowid | mismatch | port bug: no rowid is assigned; the INSERT fails with a NOT NULL constraint error instead of auto-numbering |
| bug-rowid-omitted-pk-multi | bugs | INTEGER PRIMARY KEY auto-numbering sequence | sqlite: INTEGER PRIMARY KEY auto-numbering sequence | mismatch | |
| bug-rowid-explicit-null | bugs | explicit NULL into INTEGER PRIMARY KEY auto-assigns a rowid | sqlite: explicit NULL into INTEGER PRIMARY KEY auto-assigns a rowid | mismatch | |
| bug-rowid-pseudo-column | bugs | implicit rowid pseudo-column | sqlite: implicit rowid pseudo-column | mismatch | |
| ddl-types | ddl | CREATE TABLE with typed and untyped columns | sqlite: CREATE TABLE with typed and untyped columns | match | |
| ddl-if-not-exists | ddl | CREATE TABLE IF NOT EXISTS | sqlite: CREATE TABLE IF NOT EXISTS | match | |
| ddl-duplicate | ddl | CREATE TABLE duplicate (must fail) | sqlite: CREATE TABLE duplicate (must fail) | match | |
| ddl-drop | ddl | DROP TABLE | sqlite: DROP TABLE | match | |
| ddl-drop-if-exists | ddl | DROP TABLE IF EXISTS | sqlite: DROP TABLE IF EXISTS | match | |
| ddl-drop-missing | ddl | DROP TABLE missing (must fail) | sqlite: DROP TABLE missing (must fail) | match | |
| ddl-not-null-ok | ddl | NOT NULL constraint satisfied | sqlite: NOT NULL constraint satisfied | match | |
| ddl-not-null-violation | ddl | NOT NULL constraint violated (must fail) | sqlite: NOT NULL constraint violated (must fail) | match | |
| ddl-pk-dup | ddl | PRIMARY KEY uniqueness (must fail) | sqlite: PRIMARY KEY uniqueness (must fail) | match | |
| ddl-pk-text | ddl | TEXT PRIMARY KEY | sqlite: TEXT PRIMARY KEY | match | |
| ddl-pk-table-constraint | ddl | table-level PRIMARY KEY (a) | sqlite: table-level PRIMARY KEY (a) | mismatch | |
| ddl-pk-composite | ddl | composite PRIMARY KEY | sqlite: composite PRIMARY KEY | mismatch | |
| ddl-unique | ddl | UNIQUE column constraint | sqlite: UNIQUE column constraint | mismatch | |
| ddl-unique-violation | ddl | UNIQUE violated (must fail) | sqlite: UNIQUE violated (must fail) | match | |
| ddl-default | ddl | DEFAULT column constraint | sqlite: DEFAULT column constraint | mismatch | |
| ddl-autoincrement | ddl | AUTOINCREMENT | sqlite: AUTOINCREMENT | mismatch | |
| ddl-check-ok | ddl | CHECK column constraint | sqlite: CHECK column constraint | mismatch | |
| ddl-check-violation | ddl | CHECK violated (must fail) | sqlite: CHECK violated (must fail) | match | |
| ddl-collate | ddl | COLLATE column constraint | sqlite: COLLATE column constraint | mismatch | |
| ddl-references | ddl | REFERENCES column constraint | sqlite: REFERENCES column constraint | mismatch | |
| ddl-foreign-key-table | ddl | table-level FOREIGN KEY | sqlite: table-level FOREIGN KEY | mismatch | |
| ddl-create-index | ddl | CREATE INDEX | sqlite: CREATE INDEX | mismatch | |
| ddl-create-unique-index | ddl | CREATE UNIQUE INDEX | sqlite: CREATE UNIQUE INDEX | mismatch | |
| ddl-drop-index | ddl | DROP INDEX | sqlite: DROP INDEX | mismatch | |
| ddl-alter-add-column | ddl | ALTER TABLE ... ADD COLUMN | sqlite: ALTER TABLE ... ADD COLUMN | mismatch | |
| ddl-alter-rename-table | ddl | ALTER TABLE ... RENAME TO | sqlite: ALTER TABLE ... RENAME TO | mismatch | |
| ddl-alter-rename-column | ddl | ALTER TABLE ... RENAME COLUMN | sqlite: ALTER TABLE ... RENAME COLUMN | mismatch | |
| ddl-alter-drop-column | ddl | ALTER TABLE ... DROP COLUMN | sqlite: ALTER TABLE ... DROP COLUMN | mismatch | |
| ddl-create-table-as | ddl | CREATE TABLE ... AS SELECT | sqlite: CREATE TABLE ... AS SELECT | mismatch | |
| ddl-create-view | ddl | CREATE VIEW | sqlite: CREATE VIEW | mismatch | |
| ddl-temp-table | ddl | CREATE TEMP TABLE | sqlite: CREATE TEMP TABLE | mismatch | |
| ddl-without-rowid | ddl | WITHOUT ROWID | sqlite: WITHOUT ROWID | mismatch | |
| ddl-generated-column | ddl | GENERATED ALWAYS AS column | sqlite: GENERATED ALWAYS AS column | mismatch | |
| ddl-create-trigger | ddl | CREATE TRIGGER | sqlite: CREATE TRIGGER | mismatch | |
| ddl-quoted-ident | ddl | double-quoted identifiers | sqlite: double-quoted identifiers | match | |
| ddl-backtick-ident | ddl | backtick-quoted identifiers | sqlite: backtick-quoted identifiers | mismatch | |
| ddl-bracket-ident | ddl | bracket-quoted identifiers | sqlite: bracket-quoted identifiers | mismatch | |
| insert-cols | dml | INSERT INTO t (cols) VALUES (...) | sqlite: INSERT INTO t (cols) VALUES (...) | match | |
| insert-multi-row | dml | multi-row INSERT | sqlite: multi-row INSERT | match | |
| insert-no-collist | dml | INSERT without a column list | sqlite: INSERT without a column list | match | |
| insert-partial-cols | dml | INSERT omitting a nullable column | sqlite: INSERT omitting a nullable column | match | |
| insert-expr | dml | INSERT with an expression | sqlite: INSERT with an expression | match | |
| insert-select | dml | INSERT ... SELECT | sqlite: INSERT ... SELECT | mismatch | |
| insert-select-where | dml | INSERT ... SELECT ... WHERE | sqlite: INSERT ... SELECT ... WHERE | mismatch | |
| insert-or-ignore | dml | INSERT OR IGNORE | sqlite: INSERT OR IGNORE | mismatch | |
| insert-or-replace | dml | INSERT OR REPLACE | sqlite: INSERT OR REPLACE | mismatch | |
| replace-into | dml | REPLACE INTO | sqlite: REPLACE INTO | mismatch | |
| insert-upsert | dml | INSERT ... ON CONFLICT DO UPDATE (upsert) | sqlite: INSERT ... ON CONFLICT DO UPDATE (upsert) | mismatch | |
| insert-default-values | dml | INSERT ... DEFAULT VALUES | sqlite: INSERT ... DEFAULT VALUES | mismatch | |
| update-where | dml | UPDATE ... WHERE | sqlite: UPDATE ... WHERE | match | |
| update-all | dml | UPDATE without WHERE | sqlite: UPDATE without WHERE | match | |
| update-multi-col | dml | UPDATE multiple columns | sqlite: UPDATE multiple columns | match | |
| update-expr | dml | UPDATE with an expression | sqlite: UPDATE with an expression | match | |
| update-to-null | dml | UPDATE ... SET c = NULL | sqlite: UPDATE ... SET c = NULL | match | |
| update-no-match | dml | UPDATE matching no rows | sqlite: UPDATE matching no rows | match | |
| delete-where | dml | DELETE ... WHERE | sqlite: DELETE ... WHERE | match | |
| delete-all | dml | DELETE without WHERE | sqlite: DELETE without WHERE | match | |
| delete-null-pred | dml | DELETE on IS NULL | sqlite: DELETE on IS NULL | match | |
| delete-limit | dml | DELETE ... LIMIT (needs SQLITE_ENABLE_UPDATE_DELETE_LIMIT) | sqlite: DELETE ... LIMIT (needs SQLITE_ENABLE_UPDATE_DELETE_LIMIT) | match | |
| err-syntax-garbage | errors | malformed statement | sqlite: malformed statement | match | |
| err-syntax-trailing | errors | FROM with no table | sqlite: FROM with no table | match | |
| err-no-such-table | errors | unknown table | sqlite: unknown table | match | |
| err-no-such-column | errors | unknown column | sqlite: unknown column | match | |
| err-no-such-column-where | errors | unknown column in WHERE | sqlite: unknown column in WHERE | match | |
| err-no-such-column-order | errors | unknown column in ORDER BY | sqlite: unknown column in ORDER BY | match | |
| err-insert-count-mismatch | errors | INSERT value/column count mismatch | sqlite: INSERT value/column count mismatch | match | |
| err-insert-unknown-column | errors | INSERT into an unknown column | sqlite: INSERT into an unknown column | match |