A recent Search API commit (#2574611-36: Unify our two task systems) broke the tests (and module) on Postgres. After a bit of investigating I found the culprit to be an apparent Core bug regarding entity queries.
This method, as you can see, takes potentially multiple conditions and integrates them into an entity query. The 'IN' operator and an array type cast is used to uniformly treat single-valued and multi-valued conditions.
However, while it worked fine for MySQL and SQLite, the Postgres driver couldn't work with this correctly, but produced a query like the following:
SELECT 1 AS expression
FROM
{search_api_task} base_table
INNER JOIN {search_api_task} search_api_task ON search_api_task.id = base_table.id
WHERE (LOWER(search_api_task.type) IN (LOWER(:value1))) AND (LOWER(search_api_task.index_id) IN (LOWER(:value1)))
Note that both placeholders are called :value1, although they are different values. This, of course, leads to false matches.
I tried to create a test case to showcase this bug more clearly, or reproduce it with Core entity types, but I unfortunately didn't succeed. I don't really know what circumstances have to be present for this bug to occur. The entity type in question doesn't have a data table, though, and just uses a single table to store all fields. Maybe it only works with base fields? (Tried with nodes' nid and type fields, though, and also failed.)
Anyways, I know that the problem only exists with IN conditions since we managed to find a workaround by just using = instead where possible (see #2574611-49: Unify our two task systems).
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | Condition.patch | 547 bytes | IlBob |
Issue fork drupal-2734445
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 2734445-postgres-entity-queries
changes, plain diff MR !120
Comments
Comment #2
bzrudi71 commentedjust tagging...
Comment #3
daffie commentedMaybe I am doing something wrong, but with a PostgreSQL backend, I have made the following query:
The result of that query is:
As far as I can see is everything as it is suppoost to be.
Comment #4
drunken monkeyAs the issue title states, this issue only occurs for entity queries, not for normal database queries. But also only on Postgres, so I really don't know which "Component" is the correct one here. I don't know any of that code, so I have no clue where the bug could hide.
Also, as stated, I unfortunately wasn't able to reproduce this with Core entities, either. I'm just pretty sure my code with my custom entity type was correct, so I suspect a bug. And I hoped that someone who knows the Postgres driver code as well as the entity query code might know where to look for such a bug and maybe find it.
Comment #5
daffie commentedMoving this to the entity system, because:
Comment #12
IlBob commentedSame bug here with Postgresql DB, triggered by this code:
the code doesn't return any result with two conditions (there are entity that match in DB) , return results with only one condition the first or the second.
After a debug session I have found this code in core/lib/Drupal/Core/Entity/Query/Sql/pgsql/Condition.php
this seems wrong because it restart the placeholder number on every call and this leads to duplicate on multiple conditions.
The proposed patch declare $n as static and this solve the placeholder duplication.
Comment #13
hchonovCould you please try to implement a test based on the last steps, which seem to be able to reproduce the problem?
We test core with PostgreSQL and I will be surprised if we don't have Entity queries with multiple conditions.
Comment #19
daffie commentedThis issue is a duplicate of #3162603: EntityStorageBase::loadByProperties() is broken on PostgreSQL when using two or more case insensitive properties and that issue has a patch with a fix and testing for that fix.
Comment #20
mxr576Thanks @daffie, let's continue the work there.