Error
- mwversion: 1.44.0-wmf.24
- reqId: b27a4bb6-bb07-4783-8102-37051513e3e1
- Find reqId in Logstash
[{reqId}] {exception_url} PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated[{reqId}] {exception_url} PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated| Subject | Repo | Branch | Lines +/- | |
|---|---|---|---|---|
| rdbms: Reduce backtrack on regex for generalizeSQL | mediawiki/core | master | +10 -1 |
| Status | Subtype | Assigned | Task | |
|---|---|---|---|---|
| · · · | ||||
| Resolved | None | T379874 ☂ PHP 8.1 issues found during WMF rollout/ramp up | ||
| Resolved | PRODUCTION ERROR | Umherirrender | T391874 PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated | |
| · · · |
This is probably not a GrowthExperiments issue. The error occurs in the last preg_replace call of \Wikimedia\Rdbms\QueryBuilderFromRawSql::generalizeSQL:
public static function generalizeSQL( $sql ) { # This does the same as the regexp below would do, but in such a way # as to avoid crashing php on some large strings. # $sql = preg_replace( "/'([^\\\\']|\\\\.)*'|\"([^\\\\\"]|\\\\.)*\"/", "'X'", $sql ); $sql = str_replace( "\\\\", '', $sql ); $sql = str_replace( "\\'", '', $sql ); $sql = str_replace( "\\\"", '', $sql ); $sql = preg_replace( "/'.*'/s", "'X'", $sql ); $sql = preg_replace( '/".*"/s', "'X'", $sql ); # All newlines, tabs, etc replaced by single space $sql = preg_replace( '/\s+/', ' ', $sql ); # All numbers => N, # except the ones surrounded by characters, e.g. l10n $sql = preg_replace( '/-?\d++(,-?\d++)+/', 'N,...,N', $sql ); $sql = preg_replace( '/(?<![a-zA-Z])-?\d+(?![a-zA-Z])/', 'N', $sql ); // <-- Error Stacktrace is referencing this line return $sql; }
The error says that the last argument, $sql is null. That means that the previous preg_replace call must have returned null. That line in particular was last changed in rdbms: avoid pcre.backtrack_limit in QueryBuilderFromRawSql::generalizeSQL() for T366640: QueryBuilderFromRawSql::generalizeSQL: PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated. So, I'm adding the respective tags and such.
I'll put this in our freezer because our involvement seems to be incidental. Please let us know if there is actually something wrong on our side here.
QueryBuilderFromRawSqlTest has a test failure to test the regex for a IN clause with 5000 items. That pass, but changing to 9000 makes it fail. That indicates another backtrace issue
Change #1172083 had a related patch set uploaded (by Umherirrender; author: Umherirrender):
[mediawiki/core@master] rdbms: Reduce backtrack on regex for generalizeSQL
Change #1172083 merged by jenkins-bot:
[mediawiki/core@master] rdbms: Reduce backtrack on regex for generalizeSQL
The root cause – if you want to call it like that – are mentors that have several 1000 mentees. The code actually generates SQL queries with thousands and thousands of distinct user ids in a single WHERE … IN clause.
I wonder if this is really necessary in all the situations where the code currently calls DatabaseMentorStore::getMenteesByMentor?
For example, I found quite a lot of places that drop the returned UserIdentity[] array and use only the user ids. It looks like at least some of these places can be rewritten to use a much cheaper query that returns growthexperiments_mentor_mentee.gemm_mentee_id directly, or possibly an even cheaper COUNT( growthexperiments_mentor_mentee.gemm_mentee_id ). @Michael, what do you think?