Steps to replicate the issue (include links if applicable):
- Install MediaWiki with a Wikibase repository on PHP 8.1 with a SQLite database backend
- Attempt to create a property through Special:NewProperty
What happens?:
Creating Properties (and probably everything else) throws the following exception and fails:
[error] [796a23f655bcb0773f725fe4] /wiki/Special:NewProperty PHP Warning: [data-update-failed]: A data update callback triggered an exception (Fail-safe exception. Avoiding infinite loop due to possibly undetectable existing records in master. It may be due to encoding incompatibility between database values and values passed in $neededRecords parameter.) [Called from Wikibase\Repo\Content\DataUpdateAdapter::doUpdate in /srv/mediawiki/extensions/Wikibase/repo/includes/Content/DataUpdateAdapter.php at line 63] #0 [internal function]: MWExceptionHandler::handleError() #1 /srv/mediawiki/includes/debug/MWDebug.php(500): trigger_error() #2 /srv/mediawiki/includes/debug/MWDebug.php(196): MWDebug::sendMessage() #3 /srv/mediawiki/includes/GlobalFunctions.php(1065): MWDebug::warning() #4 /srv/mediawiki/extensions/Wikibase/lib/includes/Reporting/LogWarningExceptionHandler.php(28): wfLogWarning() #5 /srv/mediawiki/extensions/Wikibase/repo/includes/Content/DataUpdateAdapter.php(63): Wikibase\Lib\Reporting\LogWarningExceptionHandler->handleException() #6 /srv/mediawiki/includes/deferred/DeferredUpdates.php(536): Wikibase\Repo\Content\DataUpdateAdapter->doUpdate() #7 /srv/mediawiki/includes/deferred/RefreshSecondaryDataUpdate.php(103): DeferredUpdates::attemptUpdate() #8 /srv/mediawiki/includes/deferred/DeferredUpdates.php(536): RefreshSecondaryDataUpdate->doUpdate() #9 /srv/mediawiki/includes/deferred/DeferredUpdates.php(419): DeferredUpdates::attemptUpdate() #10 /srv/mediawiki/includes/deferred/DeferredUpdates.php(229): DeferredUpdates::run() #11 /srv/mediawiki/includes/deferred/DeferredUpdatesScope.php(264): DeferredUpdates::{closure}() #12 /srv/mediawiki/includes/deferred/DeferredUpdatesScope.php(196): DeferredUpdatesScope->processStageQueue() #13 /srv/mediawiki/includes/deferred/DeferredUpdates.php(250): DeferredUpdatesScope->processUpdates() #14 /srv/mediawiki/includes/MediaWiki.php(1123): DeferredUpdates::doUpdates() #15 /srv/mediawiki/includes/MediaWiki.php(845): MediaWiki->restInPeace() #16 /srv/mediawiki/includes/MediaWiki.php(588): MediaWiki->doPostOutputShutdown() #17 /srv/mediawiki/index.php(53): MediaWiki->run() #18 /srv/mediawiki/index.php(46): wfIndexMain() #19 {main} [warning] [data-update-failed]: A data update callback triggered an exception (Fail-safe exception. Avoiding infinite loop due to possibly undetectable existing records in master. It may be due to encoding incompatibility between database values and values passed in $neededRecords parameter.) [Called from Wikibase\Repo\Content\DataUpdateAdapter::doUpdate in /srv/mediawiki/extensions/Wikibase/repo/includes/Content/DataUpdateAdapter.php at line 63]
What should have happened instead?:
Creating Properties (and probably everything else) works.
Software version (skip for WMF-hosted wikis like Wikipedia):
Mediawiki 1.38.2
PHP 8.1.9
Other information (browser name/version, screenshots, etc.):
The exception is 100% correct about the cause. Starting with PHP 8.1, integer columns return integers now. This breaks the comparison for the insertion into the wbt_text_in_lang table because the type id is specified as a string in DatabaseTermInLangIdsAcquirer::acquireTermInLangIdsInner. The difference in type causes the calculated hashes for the inserted row and needed row to differ, causing the infinite loop.
I'm not sure what the best way to fix this is as it only affects SQLite when running on PHP >= 8.1. MySQL, PostgreSQL, and PHP < 8.1 still require the type to be a string.