Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
The classcore/modules/views/src/Plugin/views/filter/Combine.php
creates a CONCAT_WS()
expression from an array of fields. When the array has only one field element, the separator will not be added. Instead, we can just return the field. MS SQL Server requires at least three arguments for CONCAT_WS()
for this reason.
Comment | File | Size | Author |
---|---|---|---|
#8 | 3131379-8.patch | 2.62 KB | daffie |
#8 | interdiff-3131379-7-8.txt | 693 bytes | daffie |
#7 | 3131379-7-test-only-should-fail.patch | 1.26 KB | daffie |
Comments
Comment #2
BeakerboyPatch which uses the CONCAT_WS expression, only when there are multiple fields to concatenate together.
Comment #3
BeakerboyI should probably change it to:
because an empty field array makes just as little sense, and would probably yield an error with the existing code.
Comment #4
BeakerboyTesting a combine filter with no fields in the array.
Comment #5
daffie CreditAttribution: daffie commented$count == 1
.CONCAT_WS
.Comment #6
Beakerboy1. Adding more comments is certainly a good idea. In fact, if you have any idea why the foreach loop exists I would love to hear it. To me it reads like the foreach loop adds an additional single space character to the array, but only between existing fields. The implode will turn the array into a comma separated string. It seems like it could be simplified by getting rid of the foreach loop and changing the implosion to:
Then this all is used as the argument list for CONCAT_WS, which adds a single space between each argument. Again, we can instead just use a triple-space as the separator...but then again, why are we using three spaces anyways? The whole reason for adding the single-space as an argument seems pointless.
2. The new test was to check if MySQL was fine executing a CONCAT_WS with NO fields, just a seperator. I was thinking it would fail. I have to figure out how everything should work given this fact. Should the whole expression be dropped when the filter contains no fields? The core test FilterCombineTest::testNonFieldsRow() uses only one field, so it will follow the new execution path while all the other tests in the class will use the old one. The new execution path will be covered.
Comment #7
daffie CreditAttribution: daffie commentedFor #6.1.1: You are right. We can get rid of the foreach loop. I have changed the expression to make it more readable to:
$expression = implode(", ' ', ", $separated_fields);
.For #6.1.2: If we do: "The whole reason for adding the single-space as an argument seems pointless." We are changing the way the views filter works. I would do that in another issue. It will make this a far bigger change and would be out of scope for this issue.
For #6.2: Lets keep the change as simple as possible. That way less can go wrong.
Comment #8
daffie CreditAttribution: daffie commentedAdd the required comment to the patch.
Comment #10
BeakerboyI’ve reviewed the patch in #8 and successfully tested with sqlsrv.
Comment #11
BeakerboyI found an old issue for this that can probably be closed when this is.
Comment #12
Lendude#6.1.2 the 3-space logic is so that search strings that contain spaces are still only matched to single field values and not to multi-field values that exist only because we do the concatenation/LIKE trick. Like it or hate it, the 3 spaces are part of the trick :)
Comment #13
Beakerboy@lendude, why not just use three spaces as a seperator between fields instead of adding in a single-space string between fields and then concatinating another single space. Is it just to ensure there are six (or four?) spaces between fields when one is NULL? And if so, why is that important?
Comment #14
alexpottCan we open an issue to document this 3 space trick here - or at least point to documentation of it. I looked at this code and was thinking what's the point of the spaces.
Comment #15
LendudeThe three spaces 'why' is discussed on #2405907: Views combined filters add redundant separators in CONCAT_WS(). Feel free to open that back up and continue the discussion or repurpose it for a doc block update.
Comment #16
alexpottCommitted and pushed 5c72f9f050 to 9.1.x and 4d80b317ef to 9.0.x and 8920b79e53 to 8.9.x. Thanks!
Okay I've added a comment based on #12 as having something here is definitely better than nothing.
I've not backported to 8.8.x due to #3135747: assertStringContainsString() and related BC layer in 8.8.x does not work as expected
Comment #19
alexpottComment #21
Beakerboy@lendude
3 spaces makes sense in that regard, but the method of creating it is odd. Why is the function adding a single-space As a field, and then adding another in the CONCAT_WS. Why not just add three spaces between the actual fields?
Like this:
Comment #22
Lendude@Beakerboy like I said, feel free to open up the other issue. I really don't care how they are added, as long as they are :)