MDL-88218: Emulate common MySQL functions in the SQLite driver - #6
Closed
erseco wants to merge 1 commit into
Conversation
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().
Member
Author
|
Closing without merging: applied this same commit directly onto |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Running a
block_configurable_reportsSQL report on the SQLite driver fails with: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_WSNotes:
CONCAT()returnsNULLwhen any argument isNULL(intentionally overriding the SQLite ≥ 3.44 built-in, which skips NULLs),FROM_UNIXTIME(NULL)returnsNULL, unknownDATE_FORMATspecifiers 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.Pdo\Sqlite::createFunction()when available (PHP 8.4+PDO::connect()) and falls back toPDO::sqliteCreateFunction().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
PDOSQLite 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.