Updated: Comment #153

Problem/Motivation

Drupal's current method of determining whether a specified user has access to a node is reported to have significant performance issues on a site using node access with a large number of grants.

Proposed resolution

A patch has been prepared, however it appears to be unclear as to what functionality/performance testing might be required or how it would be undertaken.

Remaining tasks

  • (todo) commit patch #133

------------------------------------------------------------

Not sure if its faster, but I thought it might:

function node_access($op, $node = NULL) { 
  // ...

  // If the module did not override the access rights, use those set in the
  // node_access table.
  if ($op != 'create' && $node->nid && $node->status) {
    $grants = array();
    foreach (node_access_grants($op) as $realm => $gids) {
      foreach ($gids as $gid) {
        $grants[] = "(gid = $gid AND realm = '$realm')";
      }
    } 

  // ...
}
function node_access($op, $node = NULL) { 
  // ...

  // If the module did not override the access rights, use those set in the
  // node_access table.
  if ($op != 'create' && $node->nid && $node->status) {
    $grants = array();
    foreach (node_access_grants($op) as $realm => $gids) {
      $grants[] = "((realm = '$realm') AND (gid = ".implode(' OR gid = ', $gids)."))";
    } 

  // ...
}

Difference is that realm is just checked once; not per gid. But it is possible that mysql/postgre server already do this, I don't know.

CommentFileSizeAuthor
#170 interdiff.txt663 bytesrenatog
#170 drupal-106721-optimize_node_access_queries-170.patch3.02 KBrenatog
#133 drupal-106721-optimize_node_access_queries-133.patch3.03 KBq0rban
#121 106721-drupal-optomize-queries-1349080-121-do-not-test.patch3.42 KBhefox
#118 106721-drupal-optomize-queries-1349080-do-not-test.patch3.39 KBhefox
#116 106721-drupal-optomize-queries-1349080.patch3.39 KBhefox
#115 drupal-106721-optimize_node_access_queries-115.patch3.05 KBhefox
#110 drupal-106721-optimize_node_access_queries-110.patch3.05 KBhefox
#105 drupal-optimize_node_access_queries-106721-105.patch2.61 KBsheldonkreger
#81 drupal-106721-optimize_node_access_queries-81.patch2.6 KBerikwebb
#72 drupal-optimize_node_access_queries-106721-D7-71-do-not-test.patch2.6 KBezra-g
#71 drupal-optimize_node_access_queries-106721-71.patch3.4 KBmsonnabaum
#69 interdiff.txt2.14 KBmsonnabaum
#69 drupal-optimize_node_access_queries-106721-69.patch3.36 KBmsonnabaum
#67 drupal-optimize_node_access_queries-106721-D7-do-not-test.patch2.63 KBmsonnabaum
#66 drupal-optimize_node_access_queries-106721-66.patch3.29 KBmsonnabaum
#62 drupal-optimize_node_access_queries-106721-62.patch3.02 KBmsonnabaum
#59 drupal-optimize_node_access_queries-106721-D7-do-not-test.patch3.78 KBmsonnabaum
#58 drupal-optimize_node_access_queries-106721-58.patch3.03 KBmsonnabaum
#57 106721-57optimize_node_access_queries.patch1.87 KBjoelpittet
#52 drupal-optimize_node_access_queries-106721-52.patch1.49 KBoleg.medvedev
#50 drupal-optimize_node_access_queries-106721-50.patch1.88 KBerikwebb
#41 106721-optimize-node-access-query-building-41.patch2.7 KBjrglasgow
#32 106721-optimize-node-access-query-building-30.patch3.26 KBlotyrin
#31 106721-optimize-node-access-query-building-30.patch3.67 KBlotyrin
#30 106721-optimize-node-access-query-28.patch3.67 KBlotyrin
#28 106721-optimize-node-access-query-28.patch3.67 KBlotyrin
#23 drupal-optimize_node_access_queries-106721-23.patch1.88 KBerikwebb
#14 node_access_performance_2.patch770 bytesdawehner
#8 node_access.patch813 bytescatch
#5 node_access_optimize.patch794 bytesbdragon
#2 node_accessl.patch765 bytescatch
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

casey’s picture

Oww, another optimization might be adding a LIMIT. Since it's only quering whether there is at least 1 match it should be possible to add "LIMIT 1": query is finished when a match is found.

catch’s picture

Version: 5.x-dev » 6.x-dev
Status: Postponed (maintainer needs more info) » Needs review
FileSize
765 bytes

rolled into patch, upped version, setting to needs review, didn't add limit in to this patch.

moshe weitzman’s picture

interesting. your probably need a very large node access table for this to matter. groups.drupal.org has pretty fast node access queries so there isn't much room to improve. just one example though.

catch’s picture

Status: Needs review » Needs work

No longer applies.

bdragon’s picture

Status: Needs work » Needs review
FileSize
794 bytes

Free reroll courtesy of patch bingo.

moshe weitzman’s picture

Version: 6.x-dev » 7.x-dev

good idea, but a bit late now ... benchmarks might help people get more interested, though I'm not sure that is a prerequisite.

moshe weitzman’s picture

good idea, but a bit late now.

catch’s picture

FileSize
813 bytes

Re-roll to remove some offset. I'm not set up for benchmarks, yet, but agree that'd be nice here.

lilou’s picture

Patch still apply.

cburschka’s picture

If you tell me what real-world conditions need to apply for this to matter, I can try creating them with the devel generator. I'd stress test this with a large database and see if it makes an appreciable difference.

I very much doubt this will be committed without some benchmarks to prove it is worthwhile (or even that it doesn't slow it down).

Status: Needs review » Needs work

The last submitted patch failed testing.

lilou’s picture

Status: Needs work » Needs review
David Strauss’s picture

Subscribing

dawehner’s picture

just a reroll to the latest version and a fix of codestyle

does anyone know how to test this intelligent

catch’s picture

Status: Needs review » Needs work

We should probably have a test_node_grants module, set some grants and ensure that users have the appropriate viewing rights. Maybe two modules to handle the interactions. I don't think this patch should go in without a test like that. Additionally, this query needs converting to dbtng.

ajayg’s picture

1. just want to point out the above patch is not sufficient. You will need to make similar changes to "_node_access_where_sql" function below as well as it overrides for modules using hook_dbrewrite_sql.

2. Another thought
instead of

$grants[] = "((realm = '$realm') AND (gid = ".implode(' OR gid = ', $gids)."))";

This may be better perhaps? (but I can not prove with data.)

$grants[] = "(realm = '$realm' AND gid in (".implode(' , ', $gids)."))";

I tried to benchmark all 3 conditions (A. WIthout the patch B. With the patch C. With "In" clause instead of OR clause as above.) Unfortunately my data is not conclusive. For all first invocations I would get 3 digits (190 millisecond) query time and with subsequent invocation it would be in in single digits(3 milliseconds). SO I am thinking my data/environment is not pristine. Also the difference between all 3 tests (ABC) was not significant.

ajayg’s picture

Ok here is my second try with a clean environment with mysql query cache turned off.

I tried patch but as used "IN" clause from my comments above, For tracker there is slight improvement
before patch

Executed 232 queries in 510.51 milliseconds. Page execution time was 750.65 ms.
Executed 232 queries in 510.38 milliseconds. Page execution time was 750.31 ms.
Executed 232 queries in 509.5 milliseconds. Page execution time was 749.92 ms.

After patch

Executed 232 queries in 502.94 milliseconds. Page execution time was 743.57 ms.
Executed 232 queries in 501.72 milliseconds. Page execution time was 738.95 ms.
Executed 232 queries in 501.93 milliseconds. Page execution time was 742.45 ms.

However for a normal node page the difference is less obvious. The page has a related content view block.
before patch

Executed 265 queries in 105.15 milliseconds.  Page execution time was 597 ms.
Executed 265 queries in 104.33 milliseconds. Page execution time was 595.01 ms.
Executed 265 queries in 104.86 milliseconds. Page execution time was 595.47 ms.

After patch

Executed 265 queries in 104.54 milliseconds. Page execution time was 587.45 ms.
Executed 265 queries in 111.47 milliseconds. Page execution time was 593.68 ms.
Executed 265 queries in 111.47 milliseconds. Page execution time was 593.68 ms
casey’s picture

Did you also try using LIMIT 1? I think this would also improves performance since the query is finished on the first match.

ajayg’s picture

where exactly (how) you would add the LIMIT clause? I could not find it in any of the code above other than your comment? can you write some code? Also if we add LIMIT here, whats happens to the limit added by query , say pager query?

casey’s picture

Well, instead of using COUNT(*) use LIMIT 1. See http://www.dbawill.org/2008/08/08/in-mysql-count-or-limit-1-to-determine... for more info.

ajayg’s picture

But there is no Count(*) in this particular patch. So if you need to change the query, which query need to change? I just tested the patch which dynamically adds the criteria for an existing query.
Do you mean something like

$grants[] = "((realm = '$realm') AND (gid = ".implode(' OR gid = ', $gids).")) limit 1";

But then how you will determine where the preceding query uses select fieldname1, fieldname 2 or select count(*).

Your idea may be correct but I am not understanding implementation details for all use cases. Could you please submit exact patch?

casey’s picture

Ah I now see what you mean :) I originally posted this issue about the function node_access() which does use COUNT(*) in its query. But in the comments you also mentioned that _node_access_where_sql() needs similar changes. And you are right of course. I haven't looked very well to the patches and was under the impression that they applied to node_access().

erikwebb’s picture

Title: optimize node_access query » Optimize node access queries
Status: Needs work » Needs review
Issue tags: +Performance, +Node access
FileSize
1.88 KB

It looks like this issue hasn't been touched in quite a while. My patch is essentially a re-roll with DBTNG in the mix. I ran into this issue with a client running tac_lite with a large number of terms. I want to submit this patch for 7.x for d.o testing (along with the client testing this), then push into 8.x afterwards.

erikwebb’s picture

Priority: Normal » Major

Bumping the priority because this change has a massive improvement on any site using node access with a large number of grants.

tim.plunkett’s picture

Version: 7.x-dev » 8.x-dev
Issue tags: +Needs backport to D7

This makes sense, but it should go into D8 first.

EDIT: I see you said that in #23 :)

erikwebb’s picture

Status: Needs review » Needs work
Issue tags: +Performance, +Node access, +Needs backport to D7

The last submitted patch, drupal-optimize_node_access_queries-106721-23.patch, failed testing.

lotyrin’s picture

Status: Needs work » Needs review
FileSize
3.67 KB

Rolled for 8.x and made the same change to a fourth query.

Status: Needs review » Needs work

The last submitted patch, 106721-optimize-node-access-query-28.patch, failed testing.

lotyrin’s picture

Derp. Guess I should run more of the test suite and/or wait til I'm sober and rested to write patches.

lotyrin’s picture

Status: Needs work » Needs review
FileSize
3.67 KB

Or maybe that's not all my problems? :P

lotyrin’s picture

Status: Needs review » Needs work
FileSize
3.26 KB
lotyrin’s picture

Status: Needs work » Needs review
lotyrin’s picture

So, I had planned to test this on other database drivers (just in case) but it looks like that's not going to happen because of issues like #1799310: WebTestBase->setUp() broken for sqlite.

YesCT’s picture

Status: Needs review » Needs work

The last submitted patch, 106721-optimize-node-access-query-building-30.patch, failed testing.

lotyrin’s picture

Status: Needs work » Needs review
kerasai’s picture

Status: Needs review » Needs work
Issue tags: +Performance, +Node access, +Needs backport to D7

The last submitted patch, 106721-optimize-node-access-query-building-30.patch, failed testing.

jrglasgow’s picture

Assigned: Unassigned » jrglasgow
jrglasgow’s picture

Status: Needs work » Needs review
FileSize
2.7 KB

rerolled the patch in #32

jrglasgow’s picture

Assigned: jrglasgow » Unassigned

Status: Needs review » Needs work
Issue tags: -Performance, -Node access, -Needs backport to D7

The last submitted patch, 106721-optimize-node-access-query-building-41.patch, failed testing.

bdragon’s picture

Status: Needs work » Needs review
zzrwood’s picture

Status: Needs review » Needs work
Issue tags: +Performance, +Node access, +Needs backport to D7

The last submitted patch, 106721-optimize-node-access-query-building-41.patch, failed testing.

Anonymous’s picture

Issue summary: View changes

Updated issue summary.

joelpittet’s picture

Issue tags: +Needs reroll

This one needs a re-roll.
@see http://drupal.org/patch/reroll

jeanfei’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll

I think, that the patch doesn't need to be re-roll anymore.
The node access queries were replaced by checkAllGrants() method in NodeAccessController.
I think that this issue should be closed, but I suggest somebody else to check again.

kristiaanvandeneynde’s picture

Version: 8.x-dev » 7.x-dev

So let's put it in D7 then?

erikwebb’s picture

I believe my patch was the last for D7. We can re-start over from here.

kristiaanvandeneynde’s picture

Status: Needs review » Needs work

You should check whether the $gids array contains any items before using it in an IN query.
Otherwise, PDO will throw exceptions whenever $gids is empty.

kristiaanvandeneynde’s picture

Issue summary: View changes

Issue summary updated

oleg.medvedev’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
1.49 KB
kristiaanvandeneynde’s picture

Looks good now

andyceo’s picture

Status: Needs review » Reviewed & tested by the community
andyceo’s picture

David_Rothstein’s picture

Version: 7.x-dev » 8.x-dev
Status: Reviewed & tested by the community » Needs work

Still needs to go in Drupal 8 first (code is in core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php).

joelpittet’s picture

Status: Needs work » Needs review
FileSize
1.87 KB

Here's the d8 version.

msonnabaum’s picture

Here's a new version for D8.

I ran into this on a D7 site with a many node grants, which resulted in severael seconds worth of DatabaseCondition::compile(). This approach doesn't really fix the query much (I think mysql's parser will figure that out just fine), but it helps a ton in assembling the query.

I also extracted this logic into it's own static helper method, since we repeat it three times. I made it static because it's a pure function and it's possible that contrib will need it (views would in D7).

msonnabaum’s picture

Status: Needs review » Needs work

The last submitted patch, 58: drupal-optimize_node_access_queries-106721-58.patch, failed testing.

kristiaanvandeneynde’s picture

D7 looks good, dunno why 8 fails

msonnabaum’s picture

Status: Needs work » Needs review
FileSize
3.02 KB

Think I see what happened.

Berdir’s picture

  1. +++ b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
    @@ -264,4 +243,19 @@ public function deleteNodeRecords(array $nids) {
     
    +  static function addGrantsToQuery($node_access_grants) {
    +    $grants = new Condition("OR");
    +    $grants = $query->orConditionGroup();
    +    foreach ($node_access_grants as $realm => $gids) {
    +      if (!empty($gids)) {
    +        $grants->condition(db_and()
    

    I know you don't like you write documentation ;), but this will need a proper docblock and $node_access_grants should be type hinted as an array.

Status: Needs review » Needs work

The last submitted patch, 62: drupal-optimize_node_access_queries-106721-62.patch, failed testing.

The last submitted patch, 62: drupal-optimize_node_access_queries-106721-62.patch, failed testing.

msonnabaum’s picture

Status: Needs work » Needs review
FileSize
3.29 KB

Fair enough.

msonnabaum’s picture

Also reuploading the D7 version, the one I posted earlier was bad.

Wim Leers’s picture

Status: Needs review » Needs work

Nitpick review.

  1. +++ b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
    @@ -264,4 +243,26 @@ public function deleteNodeRecords(array $nids) {
    +   * Helper function to add node access grants to a query.
    ...
    +  static function addGrantsToQuery(array $node_access_grants) {
    

    This doesn't add anything, it *builds* an object. So what about buildGrantsCondition()?

    Furthermore, all function/method docblocks should begin with a verb AFAIK.

  2. +++ b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
    @@ -264,4 +243,26 @@ public function deleteNodeRecords(array $nids) {
    +   * @param $node_access_grants
    

    Missing the typehint.

  3. +++ b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
    @@ -264,4 +243,26 @@ public function deleteNodeRecords(array $nids) {
    +   *   An array of grants, matching the return value of node_access_grants.
    ...
    +   *   A condition object to be passed to $query->condition.
    

    s/node_access_grants/node_access_grants()/
    s/$query->condition/$query->condition()/

    Without the parentheses, it looks like you're talking about a DB table/variable/concept and an object property, respectively, rather than functions.

    Also, maybe:

    s/matching the return value of/as returned by/

    ?

msonnabaum’s picture

Status: Needs work » Needs review
FileSize
3.36 KB
2.14 KB

Good call on the method name. I originally had it take the query as an arg and add the condition, but didnt update the name when I changed it.

Everything else in #68 should be addressed.

Crell’s picture

+++ b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
@@ -264,4 +243,28 @@ public function deleteNodeRecords(array $nids) {
+        $grants->condition(db_and()

Another reason I dislike static methods: You can't inject the connection here properly.

At minimum, we should use \Drupal or Database:: here rather than the function.

Although I'd prefer to just make it a normal method and inject the connection. I don't know if AND/OR handling varies by database, but in practice I think we have it setup such that it could.

msonnabaum’s picture

db_and is an inconsistency considering that i used the class version above it, so I'm fixing that.

The rest I disagree with because no connection should be involved here.

ezra-g’s picture

Here's a re-roll of #59 (D7) that fixes some issues applying (contains a /docroot path and some changes to the 7.x contrib Views module), so that we can include this improvement in Commons 7.x.

kristiaanvandeneynde’s picture

Looks good to me.

(Same code for a while now, so I can keep repeating this :) )

Crell’s picture

Status: Needs review » Reviewed & tested by the community

I will compromise on new Condition().

andypost’s picture

andypost’s picture

andypost’s picture

catch’s picture

Title: Optimize node access queries » Optimize node access query building
Version: 8.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Needs review

killes did some benchmarks of this approach for a 6.x site but I can't find them on this issue. iirc the results were it made some queries worse, some better, and was neutral for others. That sounds somewhat similar to Mark's findings as well.

I think this is worth it for less time spent in PHP and we can call the query changes neutral, so going ahead and committing, but retitling so we don't make any exciting claims.

Wim Leers’s picture

It wasn't 100% clear to me whether this was indeed committed & pushed, but it is: http://drupalcode.org/project/drupal.git/commit/d1d797046ffe79faf45d0aa0.... Yay :)

Crell’s picture

The patch in #72 needs to be rerolled so testbot can find it. If it passes, that's also RTBC IMO.

erikwebb’s picture

Crell’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, Erik!

Wim Leers’s picture

+++ b/modules/node/node.module
@@ -3075,6 +3069,20 @@ function node_access($op, $node, $account = NULL) {
+function node_add_node_grants_to_query($node_access_grants) {

Missing docs!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 81: drupal-106721-optimize_node_access_queries-81.patch, failed testing.

longwave’s picture

Status: Needs work » Needs review
mgifford’s picture

Status: Needs review » Reviewed & tested by the community

Back to rtbc. Bad bot!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 81: drupal-106721-optimize_node_access_queries-81.patch, failed testing.

joelpittet’s picture

Status: Needs work » Reviewed & tested by the community

Will it blend?

dcam’s picture

donquixote’s picture

Sorry, I still had no chance to test this - but it looks good.
A test I ran with a smaller version of this patch reduced the memory load from ~828MB to ~225MB on a particular site, but this was an extreme situation with I think ~500 Organic groups on one user.

@catch (#78)

iirc the results were it made some queries worse, some better, and was neutral for others.

I could imagine that smaller queries with only one or a few gids are better off with OR instead of IN.
If we care about this, we could add a simple if() to distinguish these cases.
Also, I wonder if the "gid IN (..)" should not rather happen AFTER the "realm = .." check, since I imagine the former to be more expensive.
On the other hand, the "gid IN (..)" is more likely to evaluate to FALSE, making it more likely that MySQL can skip the "realm = ...".

  foreach ($node_access_grants as $realm => $gids) {
    if (empty($gids)) {
      continue;
    }
    elseif (count($gids) <= THRESHOLD) {
      foreach ($gids as $gid) {
        $grants->condition(db_and()
          // gid first
          ->condition('gid', $gid)
          ->condition('realm', $realm)
        );
      }
    }
    else {
      $grants->condition(db_and()
        // realm first
        ->condition('realm', $realm)
        ->condition('gid', $gids, 'IN')
      );
    }
  }

We would have to find the ideal number for THRESHOLD. Maybe it is just 1.

This being said: Since this is already committed to D8, we might go ahead as planned and do this fine-tuning in a follow-up.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 81: drupal-106721-optimize_node_access_queries-81.patch, failed testing.

Status: Needs work » Needs review
mgifford’s picture

Status: Needs review » Reviewed & tested by the community

Bad bot.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 81: drupal-106721-optimize_node_access_queries-81.patch, failed testing.

joelpittet’s picture

Status: Needs work » Reviewed & tested by the community

weri’s picture

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 81: drupal-106721-optimize_node_access_queries-81.patch, failed testing.

Status: Needs work » Needs review
dcam’s picture

Status: Needs review » Reviewed & tested by the community

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 81: drupal-106721-optimize_node_access_queries-81.patch, failed testing.

Status: Needs work » Needs review
dcam’s picture

Status: Needs review » Reviewed & tested by the community
sheldonkreger’s picture

I rolled 81 against 7.32. Here is the patch. I suspect many people will like to use this. Please double check my work!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 105: drupal-optimize_node_access_queries-106721-105.patch, failed testing.

sheldonkreger’s picture

Status: Needs work » Reviewed & tested by the community

Sorry :-/

sheldonkreger’s picture

Do not use patch in 105, it breaks node access checks.

David_Rothstein’s picture

Status: Reviewed & tested by the community » Needs work

Looking at #81:

@@ -3402,17 +3403,7 @@ function _node_query_node_access_alter($query, $type) {
       $subquery = db_select('node_access', 'na')
        ->fields('na', array('nid'));
 
-      $grant_conditions = db_or();
-      // If any grant exists for the specified user, then user has access
-      // to the node for the specified operation.
-      foreach ($grants as $realm => $gids) {
-        foreach ($gids as $gid) {
-          $grant_conditions->condition(db_and()
-            ->condition('na.gid', $gid)
-            ->condition('na.realm', $realm)
-          );
-        }
-      }
+      $grant_conditions = node_add_node_grants_to_query(node_access_grants($op, $account));
  1. Why is this calling node_access_grants() again rather than using the existing $grants variable? This can potentially result in a significant number of extra calls to node_access_grants(), which invokes hooks, etc.
  2. node_add_node_grants_to_query() will not use the 'na' table alias that the previous code did. Is that safe, given that the query which is being altered by this function could essentially be any arbitrary query?

(#1 looks like a D7-only issue, but I think #2 might apply to D8 as well.)

Also, #83 points out the node_add_node_grants_to_query() function needs PHPDoc.... (If that were the only issue I would have fixed it myself on commit or what not, but given the other issues we should take care of this one too.)

hefox’s picture

Status: Needs work » Needs review
FileSize
3.05 KB

Reroll addressing above points

Status: Needs review » Needs work

The last submitted patch, 110: drupal-106721-optimize_node_access_queries-110.patch, failed testing.

hefox’s picture

o.O

#15 {main}
Uncaught exception thrown in shutdown function.

PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table &#039;drupaltestbotmysql.simpletest792722cache_block&#039; doesn&#039;t exist: DELETE FROM {cache_block}
WHERE (expire &lt;&gt; :db_condition_placeholder_0) AND (expire &lt; :db_condition_placeholder_1) ; Array
(
[:db_condition_placeholder_0] =&gt; 0
[:db_condition_placeholder_1] =&gt; 1425667806
)
in cache_clear_all() (line 167 of /var/lib/drupaltestbot/sites/default/files/checkout/includes/cache.inc).


Uncaught exception thrown in shutdown function.

PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table &#039;drupaltestbotmysql.simpletest792722cache_bootstrap&#039; doesn&#039;t exist: DELETE FROM {cache_bootstrap}
WHERE (cid = :db_condition_placeholder_0) ; Array
(
[:db_condition_placeholder_0] =&gt; variables

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 110: drupal-106721-optimize_node_access_queries-110.patch, failed testing.

hefox’s picture

Status: Needs work » Needs review
FileSize
3.05 KB

oops, forgot to default new arg for table alias

hefox’s picture

Need a version that will apply with #1349080: node_access filters out accessible nodes when node is left joined

The changes that need to be done should work fine without #1349080: node_access filters out accessible nodes when node is left joined, so sending this in for testing also (e.g. did not add do-not-test)

Status: Needs review » Needs work

The last submitted patch, 116: 106721-drupal-optomize-queries-1349080.patch, failed testing.

hefox’s picture

FileSize
3.39 KB

Or maybe it does conflict

hefox’s picture

Status: Needs work » Needs review

Sorry for the noise, trying to get this back to needs review

hefox’s picture

Again, sorry the noise but had an oops above of course

hefox’s picture

After looking into further, the part that conflicted with this patch was added after a working patch #1349080: node_access filters out accessible nodes when node is left joined to fix an conflict between two modules. It sounds like reason it was added was to fix a bug that that conflict produced, so instead for openatrium went with patch 195 for #1349080: node_access filters out accessible nodes when node is left joined and 115 for this issue.

Status: Needs review » Needs work

The last submitted patch, 116: 106721-drupal-optomize-queries-1349080.patch, failed testing.

ohthehugemanatee’s picture

Status: Needs work » Needs review

Patch 115 on this issue applies cleanly and appears to fix the issue. Can we get more reviewers?

kristiaanvandeneynde’s picture

Looks fine except:

+++ b/modules/node/node.module
@@ -3083,6 +3077,34 @@ function node_access($op, $node, $account = NULL) {
+ *   The grants to add to the query, usually gotten via: ¶

Trailing whitespace.

gifad’s picture

I'm not php specialist, but the code for :

function node_add_node_grants_to_query($node_access_grants, $table_alias = '') {
  $grants = db_or();
  $prefix = $table_alias ? $table_alias . '.' : '';

should read :

function node_add_node_grants_to_query($node_access_grants, $table_alias = NULL) {
  $grants = db_or();
  $prefix = $table_alias ? $table_alias . '.' : '';

or :

function node_add_node_grants_to_query($node_access_grants, $table_alias = '') {
  $grants = db_or();
  $prefix = !empty($table_alias) ? $table_alias . '.' : '';

or am I missing something ?

pounard’s picture

Nope, '' is false if you if around.

kristiaanvandeneynde’s picture

gifad’s picture

Ok, thanks, and sorry for the noise...

pounard’s picture

No problem.

Chris Charlton’s picture

Anything holding this back?

Vergil.K’s picture

This fixes performance issue for large sites which live on grants. Can we get more reviewers to review and close this ASAP?

pounard’s picture

So far so good for me, I just need to apply it on a live project and run its tests to really say it's RTBC but I will need some days maybe weeks to confirm.

dcam’s picture

I hesitate to discourage additional reviews with performance testing, but I would like to point out that the basic patch was already RTBC and was rejected based on a code review, not because it didn't fix the problem. If someone can verify that:

1. This is the functionally the same fix that went into D8.
2. The issues in #109 have been addressed.

...then I'd say it could go back to RTBC.

From my brief perspective, I'd have to say that the issues have somewhat been addressed. Yes, a docblock was written, but it looks like it was completely written from scratch. This function had a docblock in D8. I think we should re-use it instead, but I don't care so much that I'll set this back to NW for that. @David_Rothstein could change it on commit, if he wanted.

  • catch committed d1d7970 on 8.3.x
    Issue #106721 by msonnabaum, lotyrin, erikwebb, catch, ezra-g,...

  • catch committed d1d7970 on 8.3.x
    Issue #106721 by msonnabaum, lotyrin, erikwebb, catch, ezra-g,...
ajayg’s picture

Anything holding this back to be committed in 7.x? Looking at the issue I see some of my earlier comments going as back as 8 years ago. :)

kristiaanvandeneynde’s picture

Someone needs to set it to RTBC to get it on a committer's radar, I guess.

ajayg’s picture

@Pounard Is there any chance you tried the patch, as you mentioned? I am in the middle of a migration to 7x for a large install, so can't try till it is completely migrated.

  • catch committed d1d7970 on 8.4.x
    Issue #106721 by msonnabaum, lotyrin, erikwebb, catch, ezra-g,...

  • catch committed d1d7970 on 8.4.x
    Issue #106721 by msonnabaum, lotyrin, erikwebb, catch, ezra-g,...
joseph.olstad’s picture

subscribing***EDIT*** Followup soon.

colan’s picture

@joseph.olstad: It's no longer necessary to add a new comment to subscribe to an issue. Simply click on the Follow link at the top-right.

joseph.olstad’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs backport to D7 +Drupal 7.60 target

RTBC #133

FYI: patch #81 is in use by over 600 acquia commons distribution installs.

Remaining tasks: commit patch #133

joseph.olstad’s picture

joseph.olstad’s picture

Status: Needs review » Reviewed & tested by the community

RTBC patch 133

FYI: patch #81 is in use by over 600 acquia commons distribution installs.

Remaining tasks: commit patch #133

joseph.olstad’s picture

Issue summary: View changes
joseph.olstad’s picture

Issue summary: View changes
joseph.olstad’s picture

Issue tags: -Drupal 7.60 target +Drupal 7.70 target

Bumping to 7.70. This didn't make it into 7.60

joseph.olstad’s picture

joseph.olstad’s picture

joseph.olstad’s picture

joseph.olstad’s picture

MustangGB’s picture

Issue tags: -Drupal 7.68 target +Drupal 7.69 target
MustangGB’s picture

Issue tags: -Drupal 7.69 target +Drupal 7.70 target
joseph.olstad’s picture

mcdruid’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -Drupal 7.74 target

Patch #133 seems to have problems with the PHP 5.3 and MySQL 8 tests.

We'll need to address those before we can consider committing this.

joseph.olstad’s picture

@mcdruid , all those tests came out green, please refresh this page.
Please have another look at the test results.

joseph.olstad’s picture

Status: Needs work » Reviewed & tested by the community

back to RTBC
patch #133 is testing all green on all tests after tests were re-triggered. Testbot issue on previous runs is flushed out.

mcdruid’s picture

Issue tags: +Pending Drupal 7 commit

Yup, you're right @joseph.olstad - the test fails were unrelated and they both passed when re-tested.

The patch looks very similar to what's now in 9.2.x here:

https://git.drupalcode.org/project/drupal/-/blob/9.2.0-alpha1/core/modul...

I might tweak the docblock on commit to match the above in order to avoid the "North American past participle of get" :) but then Drupal does use American English...

Anyway, I think the patch looks good, and I'll ask Fabianx for final review in the next few days.

Fabianx’s picture

RTBC + 1 -- patch is the same as D9

IMHO it fixes a bug when an empty array is passed to IN() -- it might be that this somehow leads to that condition not being added, because I would have expected a SQL error in that case.

Anyway, this is good to go and I see no harm to match D8/D9/D10 behavior here.

Let's get this in after 14 years ;).

MustangGB’s picture

If you're feeling in the node_access mood, also checkout #3176634: [D7] node_access filters out accessible nodes when node is left joined.

renatog’s picture

Status: Reviewed & tested by the community » Needs work

Please could you use early return on node_add_node_grants_to_query?

From

foreach ($node_access_grants as $realm => $gids) {
  if (!empty($gids)) {
    $grants->condition(db_and()
      ->condition($prefix . 'gid', $gids, 'IN')
      ->condition($prefix . 'realm', $realm)
    );
  }
}

To:

foreach ($node_access_grants as $realm => $gids) {

  if (empty($gids)) {
    continue;
  } 

  $grants->condition(db_and()
    ->condition($prefix . 'gid', $gids, 'IN')
    ->condition($prefix . 'realm', $realm)
  );
}
renatog’s picture

Status: Needs work » Needs review
FileSize
3.02 KB
663 bytes

Follow the new patch using early return

mcdruid’s picture

Status: Needs review » Reviewed & tested by the community

@RenatoG thanks, but we'll stick with #133 as that's very close to what's in D9 (see #166).

If you feel strongly that this can be improved, you should submit an issue for D9 per the backport policy.

izmeez’s picture

@RenatoG if you do open an issue for D9 please put a link here so we can follow. Thanks.

renatog’s picture

Makes sense, let's do this. Thank you people

renatog’s picture

Opened at the 9.x version

izmeez’s picture

ok, is this pending commit? Thanks

mcdruid’s picture

Yes, #133 should be committed before the next release.

izmeez’s picture

Thanks, just wasn't sure if it needed the Pending commit tag.

  • mcdruid committed 1ce9af2 on 7.x
    Issue #106721 by msonnabaum, hefox, lotyrin, erikwebb, catch, RenatoG,...
mcdruid’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Pending Drupal 7 commit

Thank you everybody!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

joseph.olstad’s picture

Would be cool to see a performance benchmark of 7.0 vs 7.81
Nice milestone here!