Problem/Motivation
Method Schema::findTables() accepts an expression as argument. Its documentation gives as example cache_% and does not mention what the expected results will be when using this string.
A developer would assume the matched tables are all prefixed with cache_ (including the underscore), while actually all tables starting with cache + one more characters are included, for example cachetags table is included while a possible cache table will not be included.
Steps to reproduce
With drush php (or in a test), in a running drupal database:
\Drupal::database()->schema()->findTables('cache_%');
Expected behaviour: all tables with cache_ - including underscore - are returned.
Actual behaviour: cachetags table is returned together with the expected behaviour results
\Drupal::database()->schema()->findTables('_%');
Expected behaviour: tables prefixed with _ are returned. In a drupal installation this should return an empty array.
Actual behaviour: all drupal tables are returned.
Proposed resolution
If this is unexpected, let's fix it. If this is expected, document the behaviour. Expected, so document it. See #8.
Remaining tasks
Understand if this is expected, and document it, or unexpected, and fix it- Update documentation, and add a test so we don't revert the behaviour by mistake.
User interface changes
N/A
API changes
Possible changes, either in documentation or in some backwards compatibility whether the fix is disruptive for some table/db-storage scenarios.
Data model changes
N/A
Release notes snippet
If we need a Release Notes, add the snippet in here.
| Comment | File | Size | Author |
|---|---|---|---|
| #26 | interdiff-3269091-24-26.txt | 786 bytes | yogeshmpawar |
| #26 | 3269091-26.patch | 3.07 KB | yogeshmpawar |
| #23 | interdiff-16-23.txt | 1.48 KB | gambry |
| #23 | 3269091-23.patch | 3.07 KB | gambry |
Comments
Comment #2
gambryHere a test-only patch.
Comment #3
gambryOops. Needs Review to trigger testbot.
Comment #4
gambryThe test only patch in #2 should highlight the problem, although a
sort()is missing. I'll upload a test-only patch with the addition after testbot job completes.Comment #6
gambryComment #7
gambrySetting Needs Review only to trigger testbot against patch in #6.
Comment #8
alexpottOoh... nice find. It looks like we have explicit code to support % and _
See
So I think this issue should improve the documentation - which is currently:
I think this needs to document that both _ and % are treated as wildcards and it should document their meaning.
Comment #10
gambryUpdating IS to reflect this is a documentation problem.
Working on a patch.
Comment #11
gambryI went with a more-is-more approach, so document as much as possible. Also I preferred to remove 'cache_%' from the example, since it's really missleading, in favour of a more general "foo_%bar".
Does this need rollback to 9.4.x?
Comment #12
yogeshmpawarResolved CSpell errors.
Comment #14
yogeshmpawarComment #15
gambryHi @yogeshmpawar . Thank you for making updates to this patch. However adding "_" to the table names triggering the spellcheck errors is not the solution. The point is exactly to test "_" behaviour as well as avoiding misunderstanding in the documentation.
What I was thinking is to use another separator other than underscores for the words triggering the errors, i.e. using numbers like "0".
I don't think
foo0whatever0barwill trigger the error?Comment #16
gambryEven better! Using camelCase is allowed, so here fix for spellcheck errors on #11 using camelcase.
Comment #17
jonathanshawAll nits.
Nit: Sometimes the comment uses double quotes, sometimes single quotes
Better "any character, exactly one occurence" or "any character, a single occurence"?
does "any character,
multiple occurrences, lazy quantifier" mean "any characters, zero or more occurences"?
It would really help if you can give an example of the difference between the % and _ matching. Also it's kind of confusing that the matches also contain the underscore.
How's this:
The test looks great, this will be RTBC once the comment grammar is fixed.
Comment #18
joachim commentedA bit more nitpicking :)
I'm very much in favour of 'more is more' for documentation!
But I find the use of 'hint' here confusing.
Also, explaining these in terms regexp syntax doesn't seem right here, when it's much simpler to say that these are wildcards used by the MySQL LIKE operator.
Comment #19
gambryThanks both for your input.
Explaining what's happening in there can be tricky without falling in a spiral of lengthy docblock. But I like the suggestion in #17 so I'll try to apply them.
Only caveats:
Kind of, but we have to add the "lazy quantifier" bit at the end, which is the technical name of the "?" quantifier operator
The only reason why I put the
hintis because searching on the web for "regular expression ?" doesn't tell you what the "?" stands for. So the hints are really to avoid developers going crazy and look for what "/.*?/" syntax mean.And since I hint for one operator I might as well hint them all.
That is what is confusing. There
$table_expressionargument is not used in SQL LIKE. Schema::findTables() method first load all the tables in the running database and then a regular expression extract the matching results. So we have to use regexp syntax because that is what is used to find the tables.Needs work in order to address the feedbacks
Comment #20
joachim commented> The only reason why I put the hint is because searching on the web for "regular expression ?" doesn't tell you what the "?" stands for.
Yup, what I meant is that writing 'hint:' reads weirdly.
> There $table_expression argument is not used in SQL LIKE. Schema::findTables() method first load all the tables in the running database and then a regular expression extract the matching results
Right, but that's an implementation detail.
What this function does is: 'You can use SQL LIKE wildcards to work with table names'. We're in the domain of SQL queries, so it makes sense that this function uses SQL wildcards. We should document like that as well.
The reason the function's code converts them to regex is that you can't actually use wildcards with table names in SQL. But this function is allowing you to pretend that you can.
Comment #21
jonathanshawhttps://dev.mysql.com/doc/refman/8.0/en/pattern-matching.html
Therefore I suggest:
Comment #22
joachim commented#21 -- yup, perfect!
(Well, I think it's capitalised MySQL ;)
Comment #23
gambryI'm afraid there was more fun than expected. The spellcheck spit out most of those "fooXbar". I had to play with camelCase to get it working with wording from #21.
Please have another look.
Comment #24
jonathanshawNit: double apostrophe
I think we're there, trusting the apostrophe can be fixed on commit.
Comment #26
yogeshmpawarUpdated patch will address #24 & failed tests looks unrelated.
Comment #27
jonathanshawComment #28
alexpottCommitted 79925d2 and pushed to 10.0.x. Thanks!
Committed and pushed e9294d88bf to 9.4.x and 467d4fd1b3 to 9.3.x. Thanks!