Problem/Motivation
See #1759144: taxonomy_update_7005 on pgsql returns error "column "td" of relation "taxonomy_update_7005" does not exist" for an initial description of the bug and an actual example that triggers it in the Drupal 7 codebase.
The code in Drupal\Core\Database\Driver\pgsql::orderBy() looks identical in Drupal 8, so I assume the bug exists there too.
Proposed resolution
Determine if there is no need for the orderBy method, and add tests for the bug in the problem/motivation section above.
Remaining tasks
- Write patch - DONE
- Review patch - DONE
- Reply to the question by @catch's comment in #29 - DONE - see #61.
User interface changes
None.
API changes
This is not an API change, but a behavior change. The pgsql driver no longer makes an assumption about what it does or does not need to do during an orderBy. Contrib developers may need to make changes if they rely on select queries with ambiguous fields when using distinct and orderBy. These queries do not appear in Drupal core so the driver should not need to make these adjustments automatically.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#83 | interdiff-ea58ef.txt | 981 bytes | larowlan |
#75 | 2057693-nr-bot.txt | 2.55 KB | needs-review-queue-bot |
#73 | interdiff_71_73.txt | 514 bytes | Arantxio |
#73 | 2057693-73.patch | 6.68 KB | Arantxio |
#50 | 2057693-50.patch | 6.08 KB | ridhimaabrol24 |
Comments
Comment #1
Steven Jones CreditAttribution: Steven Jones commentedComment #2
David_Rothstein CreditAttribution: David_Rothstein commentedAssuming the category was switched by mistake..
Comment #3
Steven Jones CreditAttribution: Steven Jones commentedSorry! No idea how the component got changed.
Comment #4
jhedstromComment #6
marthinal CreditAttribution: marthinal commentedI had this problem working on FACETS.
Here is the query:
And here is the error:
I've fixed the problem adding the expression before the orderBy() and it works because we verify the expression from the Driver:
So the solution is something like this:
Comment #7
daffie CreditAttribution: daffie commented@marthinal: Good work with solving the problem. Can you make a patch.
I am afraid that a test must be added o make sure that the problem is fixed and that is does not return.
Comment #8
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedNot sure why this can't be fixed in 8.1.x?
Comment #9
daffie CreditAttribution: daffie commentedThe method Drupal\Core\Database\Driver\pgsql\Select::orderBy adds fields that are needed for the order by clause. Lets remove that part and see what the testbot does.
Comment #10
daffie CreditAttribution: daffie commentedThis problem is not solvable. What they do in #1759144: taxonomy_update_7005 on pgsql returns error "column "td" of relation "taxonomy_update_7005" does not exist" is the following:
This result in the following query:
And this is a query that PostgreSQL does not like. The column "td.id" is not added to the select part of the query and results in: "SQLSTATE[42703]: Undefined column: 7 ERROR: column tp.id does not exist".
The documentation from Drupal\Core\Database\Driver\pgsql\Select::orderBy states:
Comment #11
daffie CreditAttribution: daffie commentedTest added to prove my point.
Comment #12
daffie CreditAttribution: daffie commentedIn the method Drupal\Core\Database\Driver\pgsql\Select::orderBy the order by field is added to the select fields. In the patch is that part removed. To show that that will not fix the problem.
Comment #15
daffie CreditAttribution: daffie commentedI did it wrong. Should have selcted from the test table and inserted in the test_people table. Not the other way around. The test table has an extra column ("id").
Next try.
Comment #16
daffie CreditAttribution: daffie commentedAdded a test to make sure that we do not need the addField functionality in Drupal\Core\Database\Driver\pgsql\Select::orderBy.
I have tried to find out when the addField functionality was added to Drupal\Core\Database\Driver\pgsql\Select::orderBy. Why it was added and for which issue/use case. The most I could find out was that @webchick added it on 2010-11-29 for Drupal 7.x and it was the initial commit. So not very helpful.
Comment #17
daffie CreditAttribution: daffie commentedPlease ignore my comments #9 - #12, because they are wrong. Wrong tests with wrong conclusions.
I have added two test:
This issue is ready for a good review.
Comment #18
bzrudi71 CreditAttribution: bzrudi71 commentedInteresting to see no fails with all that code removed. Maybe this was added back in D7 for some special upgrade path requirement or such, no idea. I really like the idea to get rid of all that code and test coverage shows it is indeed not needed for D8 to pass tests. I will try to test the patch over the weekend on a real D8 site with PG as database backend (and lot's of own modules using orderby's) before doing review.
Thanks @daffie!
Comment #20
bzrudi71 CreditAttribution: bzrudi71 commentedIt took some time, but here we go :)
I testet the patch locally and can't find anything broken, nice! Additionally we have passing tests and new test too. During review I just found some nits...
needs some update/removal
and
* Tests that the INSERT INTO ... SELECT (fields) ... with ORDER BY.
the "that the" part is obsolete.
Other than that RTBC from my side
Comment #21
bzrudi71 CreditAttribution: bzrudi71 commentedComment #22
daffie CreditAttribution: daffie commented@bzrudi71: Thanks for the review. For both points: great find!.
Comment #23
daffie CreditAttribution: daffie commentedChanging the parent issue to #2564307: [meta] Remaining Drupal 10/11 PostgreSQL issues.
Comment #24
mradcliffeIs there a test that tries to do a similar query? I tried searching for one, but didn't have much luck searching all the orderBy and join and distinct queries in core. Is it something we should test?
Sorry to not get to this within a reasonable time. :(
Edit: there's probably an appropriate table in database_test module that could be added to SelectComplexTest.
Comment #25
bzrudi71 CreditAttribution: bzrudi71 commentedThis type of query seems not to be used anywhere in core (I guess). And why should the pg driver be responsible of "automagically" adding fields to make it work? ;)
This may be true but I still think it makes more sense to change the query itself to do what one want's todo, no? :)
Comment #26
mradcliffeUpdated issue summary.
Comment #27
mradcliffeI didn't mean to RTBC it myself.
Comment #28
bzrudi71 CreditAttribution: bzrudi71 commentedThanks a lot for the great IS update @mradcliffe! I'm happy with this massive code cleanup and the possible performance impact, so let's see what the committers think. :)
RTBC
Comment #29
catchSo removing all this is great, but #890994: Entity query tests fail on PostgreSQL added this code, and I don't see the original issue mentioned here - so it'd be good to double check it won't regress that bug. Especially for any likely 7.x backport if not 8.x
Comment #34
bzrudi71 CreditAttribution: bzrudi71 commentedComment #35
savkaviktor16@gmail.com CreditAttribution: savkaviktor16@gmail.com at Skilld commentedRe-rolled
Comment #36
savkaviktor16@gmail.com CreditAttribution: savkaviktor16@gmail.com at Skilld commentedComment #38
mradcliffeThank you for the re-roll, @Saviktor. Nice, only deprecation items to fix up. :-)
I guess should be
Connection->select('test', 't)
instead along with the appropriate db_insert.Comment #39
savkaviktor16@gmail.com CreditAttribution: savkaviktor16@gmail.com at Skilld commentedThanks for review, @mradcliffe! Here is updated patch
Comment #40
savkaviktor16@gmail.com CreditAttribution: savkaviktor16@gmail.com at Skilld commentedComment #42
m.stentaI ran into this issue on D7, so I created a simple patch. I'm attaching it here in case anyone else would find it useful. It can be the start of a D7 backport, if there is demand for that. It does not include any updates to automated tests yet.
The D8 patch is still "Needs Review", per @catch's comment #29 above (and I assume the same will apply to the D7 patch).
Comment #45
daffie CreditAttribution: daffie commentedComment #46
steinmb CreditAttribution: steinmb as a volunteer commented@m.stenta sure you uploaded the right patch?
Comment #47
daffie CreditAttribution: daffie commentedThe patch for D9 needs to be rerolled.
Comment #48
ridhimaabrol24 CreditAttribution: ridhimaabrol24 at Srijan | A Material+ Company for Drupal India Association commentedRerolled patch #39 for 9.1.x. Please review!
Comment #50
ridhimaabrol24 CreditAttribution: ridhimaabrol24 at Srijan | A Material+ Company for Drupal India Association commentedFixing failed test
Comment #51
m.stenta@steinmb - I think so? Note that it was for D7, not D9, if that was confusing. We are including my D7 patch in the farmOS distribution to fix the issue with D7+PostgreSQL: https://github.com/farmOS/farmOS/blob/7.x-1.x/drupal-org-core.make
Comment #52
steinmb CreditAttribution: steinmb as a volunteer commented@m.stena I know. What confused me was that the patch removed the entire orderBy() and added nothing.
Comment #53
m.stenta@steinmb Gotcha. :-)
Yes, to summarize (it's been a while so hopefully I am remembering correctly): the issue was that Drupal was overriding the default
SelectQuery
class when a PostgreSQL database was being used, which added additional logic to theSelectQuery::orderBy()
. This logic caused the issue described here. So removing that method from the class causes Drupal to use the defaultorderBy()
logic, which fixes the issue. My patch did not include any tests, so it was only removing code (the overridden method), not adding any.Notably, we can't forget to review @catch's comment in #29 above:
Hope that makes sense!
Comment #54
steinmb CreditAttribution: steinmb as a volunteer commentedAha! :-D Thank you for taking the time getting me up to speed. I really appreciate it.
Comment #56
quietone CreditAttribution: quietone as a volunteer commentedUpdate remaining tasks.
Comment #60
jonathanshawThe test coverage added here addresses the problem found in this issue, the insert query. However, the issue that caused the problematic code #890994: Entity query tests fail on PostgreSQL does not appear to have added test coverage for the problem it was addressing.
Therefore I think the only way we can know if it is safe to remove this code is to add test coverage for the original problem:
If the code is needed, the simplest fix here might be to wrap it in a conditional so it is only used when needed or not used in an insert.
I asked @berdir (who wrote the original code in #890994: Entity query tests fail on PostgreSQL). He said:
Comment #61
Berdir> However, the issue that caused the problematic code #890994: Entity query tests fail on PostgreSQL does not appear to have added test coverage for the problem it was addressing.
We did not have PostgreSQL testing the way we do today. we were working our way through the failing tests on PostgreSQL. I didn't add new tests because it didn't have to, it fixed existing fails in HEAD.
So no, IMHO this does not require new tests.
Comment #62
daffie CreditAttribution: daffie commentedBack in the day we had a number of strange fixes for PostgreSQL when you ran queries that were made for MySQL. Most if not all are fixed. As the subsystem maintainer I have confidence that we can remove the code. In the worsed case some code will fail. I do not think so, but I cannot oversee everything. Nothing in Drupal core breaks. We have new tests that show that it is not happening any more. For me it is a go.
We should add a comment that the table "test_people" does not have a column called "id". Therefor if the PostgreSQL database adds the column to the result of the select query with order by, the insert query should fail.
Could we change this to
fetchAll()
and test that we have only one column "name".The patch needs a reroll.
Comment #64
Ankit.Gupta CreditAttribution: Ankit.Gupta at Dotsquares Ltd. commentedReroll the patch #50 with Drupal 10.1.x
Comment #65
daffie CreditAttribution: daffie at Finalist commentedHi Ankit,
Thank you for the reroll. I have 2 remarks:
These 2 methods need to be public methods.
Comment #66
Akram KhanUpdated patch address #65 and fix CCF #64
assertEqual( ) is removed from drupal:10.x so we need to Use assertEquals( ) instead.
Comment #67
Akram KhanFixing CCF #66
assertIdentical( ) is deprecated in 10.x so use assertSame( ) instead
Comment #68
Akram KhanComment #69
mradcliffeI changed the status Needs work per @daffie's comment in #50 since the recent patches are incomplete. Hopefully including the changes will keep it green.
Comment #70
ArantxioRerolled the patch, with the code from #67 and #50.
Comment #71
ArantxioThe asterisks in the comment missed a space.
Comment #72
ArantxioAdjusted the PHPStan baseline, because there was a error for a variable that we have deleted with this patch.
Comment #73
ArantxioAccidentally added the updated filemode 755, but should have been 644.
Comment #74
daffie CreditAttribution: daffie at Finalist commentedAll changes look good to me.
The removed special code for PostgreSQL is for a version from a long time ago.
The added testing shows that the special code is no longer necessary.
For me it is RTBC.
Comment #75
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #76
nod_Problem with the bot disregard #75
Comment #78
daffie CreditAttribution: daffie at Finalist commentedBack to RTBC.
Comment #80
daffie CreditAttribution: daffie at Finalist commentedBack to RTBC
Comment #81
larowlanI think #61 addresses #29, removing that from the issue summary
Comment #82
larowlanIssue credits
Comment #83
larowlanI did some debugging of this, and was able to produce an entity query that errors on postgres with the following interdiff.
Is this something we should be supporting or is postgres stricter on that front? It works with MySQL.
I note this fails in HEAD too, so I assume 'not supported' on postgres (or rather - not valid SQL full stop, MySQL is just more tolerant).
Either way, this no longer applies - NW for that