Closed (outdated)
Project:
ACL
Version:
7.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Support request
Assigned:
Unassigned
Reporter:
Created:
18 Apr 2012 at 19:27 UTC
Updated:
27 Feb 2025 at 07:05 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
salvisThank you for posting your patch, this will definitely be useful for other Oracle sites.
Please understand that committing this patch would invalidate almost two years of testing that went into ACL for D7, and this is a risk that I cannot take. We have 4500 known sites running ACL 7.x-1.0, and they expect to be able to update to a 1.1 that is just as solid as 1.0. The -dev versions receive very little testing out in the field, unfortunately, and I would not be able to release 1.1 and recommend upgrading to it.
This really needs to be fixed in the Oracle driver. There's no point in trying to "fix" thousands of contrib modules that aren't broken.
I'll leave this active until the Oracle driver is working.
If you (yes, YOU, the reader) try this patch, please leave feedback, so we can build some confidence for everyone in the Oracle boat.
Comment #2
brianV commentedI'd like to respond for a second.
Why would this patch 'invalidate almost two years of testing that went into ACL for D7'?
Provided the new db_select() calls generate the same queries as the old db_query() calls, then the functionality is unchanged - this is a mere 'housekeeping' patch that makes ACL run on the Oracle DB.
I agree. By rights it should be fixed in Oracle. But the fix is non-trivial, and not likely to happen any time soon. Also, we are not asking you to fix thousands of contrib modules. We are asking you to apply a single patch to a single module.
Comment #3
brianV commentedUpdated patch, with one of the queries fixed.
Comment #4
salvisWe have no way to ascertain this, for all supported databases, all supported PHP versions, all supported versions of all databases, all hardware platforms, etc. Obviously, for Oracle, your patch does not produce the same SQL, which proves this point.
The fact that you have to post a revised patch proves that you're not infallible. I'm not infallible either. Every commit that I make carries a certain risk, and it's my job as maintainer to manage that risk and to weigh it against the benefit of the patch.
What it boils down to is that I need to be convinced that a patch is beneficial overall. With less than a 100 installations of the Oracle driver and maybe one or two wishing to use ACL, the benefit of working around the issues in the dysfunctional Oracle driver is, sorry to say this, very small, compared to the over 4500 installations of ACL 7.x-1.0 who would have to bear the risks of the patch.
What do you hope to gain if I'd commit your patch?
Comment #5
brianV commentedBut that's exactly the point. When someone uses a db_query() function, they directly provide the SQL snippet which might be appropriate to MySQL, SQLite, and Postgres, but doesn't work on Oracle due to Oracle's slightly different SQL-standard implementation. The value of using db_select() (as well as db_insert, db_update, etc.) is that we can generate the correct queries in the driver instead of trying to rewrite the arbitrary user-provided SQL string that has been sent via db_query().
If Oracle-compatible statements were stuffed into db_query(), they would work just fine, but would quite likely break on on the other above-mentioned databases, once again due to the differing SQL standard implementations.
This is the core of why fixing db_query() isn't particularly simple or even feasible.
So on that note, I want to alter my statement in my previous comment to read 'Provided the new db_select() calls generate the same result sets on each database as the old db_query() calls, then the functionality is unchanged - this is a mere 'housekeeping' patch that makes ACL run on the Oracle DB.'
True, but that's why I post it as 'needs review', not RTBC ;). If I was infallible, I'd be making a whole lot more money. And I've had cured cancer by now.
I won't argue that point. In fact, your cautious approach makes you a good maintainer. I also in no way would expect you to commit this patch without doing due diligence with it.
That's a chicken-and-egg issue. There's not a lot of Oracle sites, because many contrib modules don't work with the Oracle driver (primarily due to db_query()). Same with ACL - it doesn't work on Oracle, so not much interest in it from the Oracle crowd.
But as I explain below, there is a lot of interest in Drupal from the government and large enterprise sectors where Oracle is prevalent, so I believe that as more contrib modules are made compliant, you'll see the installation number rise.
Very little directly. It's more along the lines of trying to make a better Drupal product for everyone.
Unfortunately, Oracle is still heavily used (and mandated) in government and enterprise projects. And that isn't likely to change in the short term. At the same time, Drupal is also gaining mind share in these organizations, but if a Drupal project wants to have a chance here, it has to run on Oracle.
Long story short, if this isn't committed, I personally don't lose much. I know about the patch; I wrote it and I can apply it. My current client loses a small bit - by not having it committed, it will need to be re-rolled as ACL grows and changes and applied as we do maintenance updates. But it's a large organization, we (unfortunately) have to do this for other modules for other (non-Oracle related) reasons anyways.
The big loss is that hugely useful modules, such as this, just don't work for these large Oracle-driven projects. That's what I am hoping to change - if I can get patches like this committed, it helps develop the market for Drupal in Oracle-driven government departments and large businesses. Having it somewhat buried in the issue queue isn't, in my mind, an optimal solution.
Comment #6
salvisComment #8
salvisOk, you've made a good case and I decided to spend my precious spare time to do a first review (see below). This has turned up two fatal errors.
As I wrote above, I can't claim to be infallible either, I may very well miss additional major errors, and I have no process to ensure that this patch will not break something.
We have a few tests, but the coverage is far from complete (see #761696: WANTED: SimpleTests for ACL), unfortunately...
BTW, I had to push an update to the -dev version to enable the tests that we do have, and I moved the acl.test file to the tests subdirectory, which makes your patches inapplicable now.
Here are the review results:
All SelectStatementInterface::condition() calls need to fully qualify the column names, i.e. you must prefix the column names with their table aliases.
The
->should go to the next line.addField() cannot be chained because it returns the field alias.
join() cannot be chained because it returns the table alias.
The FETCH_ASSOC should be passed to db_select().
The acl_id condition is not part of the ON clause, it's just a condition. The original code is not exactly clean because it has the ON condition in the WHERE clause. Your version puts it all into the ON clause, which would produce different SQL on all databases. DBTNG forces us to fix this, invalidating the testing.
The queries in the tests should be line-wrapped, too, to make them readable. I haven't looked at them yet.
Comment #9
brianV commentedI appreciate the time taken to review the patch.
What exactly do you mean?
I was following the first example at http://drupal.org/node/310075#joins with respect to that query, which seemed to indicate that was permissable. I've moved the acl_id condition off to a conditional.
Third revision, attached, should be more to your liking. Applies cleanly to latest -dev.
Comment #11
brianV commentedUpdated patch should fix test failures by passing PDO::FETCH_ASSOC as a driver option to the neccessary query.
Also, removed the unncesseary ->fetchAssoc() from _acl_edit_form() which was causing breakage when we tried to iterated over the results.
Comment #12
brianV commented...and I forgot to attach the patch.
Comment #13
salvisI'm not sure, maybe there could be a benefit to putting the conditions for the joining table into the ON clause of its JOIN (the example that you cite). But in our case, the additional condition is for the joined table and it seems to me that these should go to the WHERE clause. OTOH, INNER JOIN is symmetric, so there shouldn't really be a difference...
http://dev.mysql.com/doc/refman/5.0/en/join.html says
That makes sense. A clear separation also helps query altering.
We're down to minor issues now:
An empty line after every method (including the last one!) is helpful when you rearrange code. Don't remove it.
$query->execute()->fetchField()is generally accepted — it occurs 9 times in core. execute() and fetchField() don't add anything to the $query anymore, so they don't need to follow the same rules.Same here, leave it as it is.
Break before the
->.Same here. The rule as I understand it is that query method calls that add something to a query should always be aligned on a line of their own, except those that break the chain: if they are by themselves, they should be merged with
$queryon the same line.Don't.
I'm not sure fetchAll() is valid here. It's not documented.
Same as above.
Same here.
Same here.
Same here.
This is what we really want to have in all cases above, because they only test the count.
For all count queries, as long as we don't do distinct(), we don't need to specify a field. We're really looking for COUNT(*) but COUNT(primary_key) was supposed to be more efficient on MySQL. That's the only reason why it's there, but in DBTNG the MySQL driver should take care of that.
Comment #14
brianV commentedPlease find attached another revision that should cover everything you said above with one exception - I never removed the newlines at the end of the files. It appears that perhaps an empty whitespace character was removed by my editor.
Comment #16
brianV commentedNew revision attached to address the failing test.
I've retained fetchAll() for that single query as it makes the most sense in that usage. With respect to it being undocumented, I don't agree that that is the case; it's documented in the Result sets documentation at http://drupal.org/node/1251174.
However, I changed over the others to use countQuery() because it is indeed cleaner for just fetching a count.
Comment #17
brianV commentedActually attaching the patch this time.
Comment #19
brianV commentedFinal revision - was too much in a hurry the last two times. My apologies!
Comment #20
salvisYour editor must not do that.
Do we really need to specify fields() for the countQuery()s?
Comment #23
salvisThank you for the patches, brianV. I've rerolled #19 and fixed my comments in #20 as a service to the Oracle users.
However, https://www.drupal.org/node/310075 makes it clear that this is not the way to go. #1067802: Compare $connection->query() and $connection->select() performance shows that db_select() is considerably slower than db_query(). Node Access is a notorious performance killer, and blanket replacement of db_query() with db_select() would cause a performance hit for everyone, for the benefit of only a few Oracle installations.
If anyone wants to take this on, then we need to examine each db_query() that causes problems with Oracle and see how we can fix them. Are these just the ones linked in the OP? We may even have to special-case Oracle, if we don't find a way to support it with db_query().
Be warned though: this will require reviewers/testers on the MySQL side as well!
Comment #24
salvisTests passed.
I'm setting this to RTBC, but I won't commit it as explained in #23 above.
I would like to commit #2385183: Oracle Support though, if we can get that RTBC.
Comment #25
ey commentedI am also against that patch replacing
db_querywithdb_select, because of the performance impacts this would cause.The node access system is already a bottleneck for performance and every performance bit saved in this layer has big effects on the whole.
Comment #26
dillix commentedDrupal 7 has reached its EOL, so I'm closing this as outdated.