Skip to content

MDL-88218: Emulate common MySQL functions in the SQLite driver - #6

Closed
erseco wants to merge 1 commit into
MDL-88218-Add-experimental-SQLite-support-for-Moodle-WASM-environmentsfrom
MDL-88218-sqlite-mysql-compat-functions
Closed

MDL-88218: Emulate common MySQL functions in the SQLite driver#6
erseco wants to merge 1 commit into
MDL-88218-Add-experimental-SQLite-support-for-Moodle-WASM-environmentsfrom
MDL-88218-sqlite-mysql-compat-functions

Conversation

@erseco

@erseco erseco commented Jul 30, 2026

Copy link
Copy Markdown
Member

Problem

Running a block_configurable_reports SQL report on the SQLite driver fails with:

Error reading from database
Debug info: SQLSTATE[HY000]: General error: 1 no such function: FROM_UNIXTIME
SELECT id, username, firstname, lastname, FROM_UNIXTIME(timecreated) AS created FROM mdl_user WHERE deleted = 0 ORDER BY id DESC LIMIT 5000

Plugins that accept raw SQL (configurable reports being the canonical example) almost always receive queries written in MySQL dialect, and SQLite has no FROM_UNIXTIME(), DATE_FORMAT(), IF(), etc.

Fix

SQLite supports user defined functions, so configure_dbconnection() now registers emulations of the most common MySQL date/time and string helpers on every connection:

FROM_UNIXTIME, UNIX_TIMESTAMP, DATE_FORMAT, NOW, CURDATE, CURTIME, IF, MD5, CONCAT, CONCAT_WS

Notes:

  • Emulations follow MySQL semantics: CONCAT() returns NULL when any argument is NULL (intentionally overriding the SQLite ≥ 3.44 built-in, which skips NULLs), FROM_UNIXTIME(NULL) returns NULL, unknown DATE_FORMAT specifiers yield the literal character.
  • DATE_FORMAT/FROM_UNIXTIME(ts, fmt) cover the commonly used format specifiers; week-based specifiers (%u, %v, %V, %x, %X) are approximated with their ISO-8601 equivalents.
  • Registration prefers Pdo\Sqlite::createFunction() when available (PHP 8.4+ PDO::connect()) and falls back to PDO::sqliteCreateFunction().
  • Moodle core is unaffected: cross-DB SQL goes through sql_concat() & friends; this only rescues raw MySQL-flavoured SQL from plugins.

Testing

Verified against the real driver file with a standalone harness (parent class stubbed, real PDO SQLite connection): the exact failing report query plus 20 function checks, including NULL handling and format-specifier edge cases — all pass. The failing scenario is reproducible in Moodle Playground by loading the configurable_reports blueprint and opening /blocks/configurable_reports/viewreport.php?id=1.

Plugins that accept raw SQL written for MySQL (e.g.
block_configurable_reports) fail on SQLite with errors such as
"no such function: FROM_UNIXTIME". SQLite supports user defined
functions, so register emulations of the most common MySQL date/time
and string helpers on every connection: FROM_UNIXTIME, UNIX_TIMESTAMP,
DATE_FORMAT, NOW, CURDATE, CURTIME, IF, MD5, CONCAT and CONCAT_WS.

The emulations follow MySQL semantics (CONCAT returns NULL when any
argument is NULL; unknown DATE_FORMAT specifiers yield the literal
character; week-based specifiers are approximated with ISO-8601
equivalents). Registration prefers Pdo\Sqlite::createFunction() when
available (PHP 8.4+) and falls back to PDO::sqliteCreateFunction().
@erseco

erseco commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

Closing without merging: applied this same commit directly onto MDL-88218-Add-experimental-SQLite-support-for-Moodle-WASM-environments (the branch behind #1) to stay consistent with how the fix was pushed onto the other version branches (#2, #3, #4, #5), instead of leaving it as a separate stacked PR.

@erseco erseco closed this Jul 30, 2026
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