I've installed entityqueue in a D8 site with a PostgreSQL database. I can create a taxonomy term entity queue and add terms into it without problems, but then, when I try to create a view and add a queue relationship to it, I get the following SQL error:
SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: bigint = character varying LINE 4: ...y_subqueue__items ON taxonomy_term_field_data.tid = entity_s... ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.: SELECT taxonomy_term_field_data.tid AS tid, items_taxonomy_term_field_data.name AS items_taxonomy_term_field_data_name FROM {taxonomy_term_field_data} taxonomy_term_field_data INNER JOIN {entity_subqueue__items} entity_subqueue__items ON taxonomy_term_field_data.tid = entity_subqueue__items.items_target_id INNER JOIN {entity_subqueue} items_taxonomy_term_field_data ON entity_subqueue__items.entity_id = items_taxonomy_term_field_data.name WHERE (( (items_taxonomy_term_field_data.name = :db_condition_placeholder_0) )) LIMIT 11 OFFSET 0; Array ( [:db_condition_placeholder_0] => marcas )
If I run that query directly into database I get the same error:
> SELECT taxonomy_term_field_data.tid AS tid, items_taxonomy_term_field_data.name AS items_taxonomy_term_field_data_name
FROM taxonomy_term_field_data taxonomy_term_field_data
INNER JOIN entity_subqueue__items entity_subqueue__items ON taxonomy_term_field_data.tid = entity_subqueue__items.items_target_id
INNER JOIN entity_subqueue items_taxonomy_term_field_data ON entity_subqueue__items.entity_id = items_taxonomy_term_field_data.name
WHERE (( (items_taxonomy_term_field_data.name = 'marcas') ))
LIMIT 11 OFFSET 0
ERROR: operator does not exist: bigint = character varying
LINE 3: ...y_subqueue__items ON taxonomy_term_field_data.tid = entity_s...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Query failed
PostgreSQL said: operator does not exist: bigint = character varying
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Also seen a related comment in #2643928-18: Can't save view with entity queue relationship
Comment | File | Size | Author |
---|---|---|---|
#24 | 2747079-24.patch | 7.36 KB | amateescu |
#16 | entityqueue-2747079-16.patch | 838 bytes | dimr |
Comments
Comment #2
skuark CreditAttribution: skuark commentedComment #3
viswanathsai CreditAttribution: viswanathsai commentedHi,
Even i got the SQL Error with view, when i added content queue in the relationship. Can anyone resolve this issue.
Comment #4
dimr CreditAttribution: dimr commentedHi all,
I have got the same error using Entityqueue 8.x-1.0-alpha6 and Drupal core 8.3.2.
Any idea to find a solution?
Comment #5
bryanbraun CreditAttribution: bryanbraun commentedI ran into the same thing and wanted to add some detail to help debug.
The problem is in the first INNER JOIN. The
tid
field is stored in postgres as a number (bigint) and theitems_target_id
is stored as a string (character varying). Postgres can't join across different datatypes. You can confirm this issue by running the same query while typecasting theitems_target_id
to a bigint (after which the query will work):So why is the
items_target_id
a string?I'm not 100% sure, but I found some code in EntityQueue's field definitions that suggest that some settings in the
items
field are defaulting to strings:I'm not sure why we need to allow both integers and strings to be stored in this field, but I'll bet that's causing the issue for postgres.
Comment #6
sylus CreditAttribution: sylus commentedI just came across this issue today on postgres as well. Just highlighting the relevant code from EntityReferenceItem which takes into account the target_type @ https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Field%21P...
Comment #7
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThat's because entity queue needs to be able to store references (through its entity reference field) to both content and config entities. Content entities mostly use integer IDs while config entities have string IDs.
It's very unfortunate that postgres doesn't allow joins on different data types but I can't really propose any solution for this.
https://dba.stackexchange.com/a/42991 suggests a functional index for the column that stores integer IDs, but that would have to be added to all the tables of every content entity type. Any other suggestions?
Comment #8
RenrhafI'm also experiencing this issue. Does anyone have a solution or patch ?
Comment #9
mabdullah2010 CreditAttribution: mabdullah2010 at Debug Academy commentedI was also experiencing the error. I am working with a postgres db, and my entityqueues only contain nodes, so this hacky workaround worked for me:
basically just casting the target_type field to a bigint since I can be confident this is safe in my specific use case. Can someone more knowledgeable speak on the fragility of this workaround?
I hope this is helpful.
Comment #10
sylus CreditAttribution: sylus commentedThanks for the tip @mabdullah2010 I based my solution off of yours:
Comment #11
safetypinI'm baffled that Drupal hasn't standardized the ID column type. That seems like the right way to resolve this issue, but that also seems like a pretty long road.
If the issue is resolved by typecasting the column, couldn't you test if the join is operating on a config entity and then write a different database query as suggested in #9 & #10 that typecasts the column if it's a content entity?
If a few modules allow entities to be created using an ID that does not conform to the rest of Drupal standards for entity IDs, it seems to me like it would be a good idea for them to make changes necessary to conform to standards.
Comment #12
safetypinMy attempt to implement the views_query_alter in #9 & #10 has resulted in a different error that I don't quite understand:
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "plugin.manager.field_formatter_enhancer". Did you mean this: "plugin.manager.field.formatter"? in Drupal\Component\DependencyInjection\Container->get() (line 157 of core/lib/Drupal/Component/DependencyInjection/Container.php).
Comment #13
Chris Pergantis CreditAttribution: Chris Pergantis as a volunteer commentedIf all you are using is MySQL then you will not have this issue, however most other database engines are strict on the comparing of strings and numbers. MSSQL, ORACLE, IBM DB2, PostGreSQL and most database engines.
examples
https://stackoverflow.com/questions/1146928/numeric-comparisons-on-strin...
https://stackoverflow.com/questions/32051667/compare-number-column-with-...
https://stackoverflow.com/questions/10489703/db2-how-to-check-if-varchar...
Comment #14
safetypinThe second example in #13 looks like it might be a very simple solution: always cast the integer column to a string before comparison to the string column.
Comment #15
Chris Pergantis CreditAttribution: Chris Pergantis as a volunteer commentedIt might be wise to cast both sides as string for future use and avoidance of other entity string types for an ID.
Comment #16
dimr CreditAttribution: dimr commentedI have created a patch file from #10, because I have tried and works for me, but I thought that it could be useful have it as a patch directly.
Comment #17
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedThe problem with the approach from #10 / #16 is that it will break as soon as there is an entity queue which references an entity type with a string ID..
Comment #18
Chris Pergantis CreditAttribution: Chris Pergantis as a volunteer commentedBetter to cast both as strings for MySQL and any other DB.
Comment #19
sagesolutions CreditAttribution: sagesolutions commentedLooks like we have 2 options:
1) Cast both to strings
This will guarantee no type issues in all databases.
2) Make 2 different queries
One query for int to int matching for content entities, and another one for config entities.
I choose casting both to strings.
Comment #20
sagesolutions CreditAttribution: sagesolutions commentedWhat if we reduced the functionality of Entityqueue to only have the ability to add content into queues. If we remove the ability to add configuration, we can set the entity_subqueue__items to an int instead of a varchar.
We would still have the ability to add the following into queues:
I'm not sure how many users would need the entityqueue for configuration, so I'm not sure if this is a viable solution.
Comment #21
amateescu CreditAttribution: amateescu for Pfizer, Inc. commented@sagesolutions, content entities are also allowed to have string identifiers :) In fact, there is a new entity type in Drupal 8.6 which does exactly that, the Workspace entity type.
Comment #22
sagesolutions CreditAttribution: sagesolutions commentedThat's just great...
Back to the drawing board on this one.
i was thinking adding another table...
What if we added another table entity_subqueue__items_target or similar, which has an id (int), and the items_target_id (string).
Then, the entity_subqueue__items table could reference the entity_subqueue__items_target id field.
Unfortunatley, I think this still wont work, because we would still want to (for example) join taxonomy tids to the items_target_id.
I guess casting everything to strings is still a solution.
Comment #23
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedYep, it's the only viable solution in my opinion..
Comment #24
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedI spent some time today and looked into this and I found a nice way of solving this in our custom views relationship handler. We can look up the field type definition of the queue's target entity type, and if it's an integer we do a SQL standard
CAST()
on the items field, which should work on all DB engines :)Committed the patch attached to 8.x-1.x Thanks everyone for all the useful conversation here!
Comment #27
jcandan CreditAttribution: jcandan as a volunteer commentedI completely agree with Flag module issue comment 2929733-5, that this should be addressed in views and not in a contributed module. I have submitted a patch to core to address this.