Here's a patch to make the cache plugins respect the changes to a query and arguments made by db_rewrite_sql() and substitutions.
My use case for this is that I have a site with the Domain Access module where I have Views listing content unique for each site and without this patch content cached for one domain will also be shown on the other because the node access currently isn't applied to the query prior to the hashing of it into the cache's key.
Also this site is using the module "Views exclude previous" which through substitutions makes sure that the same nodes doesn't appear in more than one Views list on the current page. Without this patch the cache won't respect the exclusions since those are applied after the hashing of the query into the cache's key has already been made.
I'm unsure whether it's the correct way to save the rewritten and substituted queries and arguments in the build_info array - but as I see it there is no other good way of doing it.
Comments
Comment #1
voxpelli commentedOf course we can't rely on build_info since that persists across many executes which may result in different substitutions.
Here's a new patch that instead relies on a new execute_info variable which I've changed the cache plugins to also rely on.
Comment #2
voxpelli commentedDon't know where I got my last comment from - a View can only be executed once so my last patch should be ignored.
Comment #3
merlinofchaos commentedOne problem with this is that cache is not theo nly thing that uses build_info['query']. For example, the data there is displayed during preview, and I consciously do *not* want to display the rewritten version, because rewrites are subject to change and would add significant confusion.
I think we would have to provide a different version query to use as the key without changing the build_info['query'] one. But that also leads to problems with people trying to change this query.
Maybe we just need to run it through db_rewrite_sql prior to caching and live with running this twice. It's not a big deal there...we're caching.
Comment #4
voxpelli commentedTalking with merlinofchaos we concluded that this issue needs a Views 3 patch to be committed and that the solution in #1 probably is sufficient for Views 2.
Comment #5
merlinofchaos commentedOne other possibility is that we could acquire the data from hook_node_grants() but that only works for node queries. Other things could be rewritten other ways. :/
Comment #6
steven jones commentedI'm struggling with this on an open atrium site, that has ***CURRENT_GID*** in pretty much every view, which means I can't cache anything!
What work is outstanding to get this into the 2.x branch of views? or are we working on a solution in 3.x too?
Comment #7
steven jones commentedI've added the meat of #2 to my caching plugin over here: #874506: Views caching flawed and it works just fine. So this fix for 2.x is working nicely.
Comment #8
dawehnerWe are waiting for a patch for 3.x
So what's the problem with the 3.x version of the patch
First http://drupal.org/node/835968
The db_rewrite_sql calls doesn't make sense here but they have to be runned before the checking of the cache plugin so they cannot be in query::execute.
So voxpelli and me discussed and decided to introduce a pre_execute function for query backends which is runned before checking the cache.
Okay here is a patch. This needs intensive review
Comment #9
voxpelli commentedAfter more discussion on IRC with both merlin and dereine I came up with a new approach that moves most of the query dependent data in the cache plug in to a new method in the query plug in.
I've just move the build_info stuff in there - but a follow up patch should perhaps move even more info in there.
Also - moving this to Views 3 as we need a patch there first.
Comment #10
voxpelli commentedMistakenly removed db_rewrite_sql() completely... Fixed in this patch.
Comment #11
itsnotme commentedI'm struggling with it too, in an OG-based Intranet project. (Views 2)
*hopes for a fix, willing to test*
Comment #12
steven jones commented@itsnotme Patch from #2 works fine with views 2.
Comment #13
dawehnerHere is a small rerole because query settings went it.
I also tested the patch a bit, played around so i think earl could have a look at it
Comment #14
itsnotme commented#2? (There is no patch.)
I tried #1 but it doesn't seem to have an effect...?
Comment #15
voxpelli commented@itsnotme: The patch in #2 should work - please define "doesn't seem to have an effect" - what effect are you expecting that you don't get with this patch?
Comment #16
dawehnerSure #2 is #1
If you use the patch you have to clear every cache which views had stored.
Comment #17
itsnotme commentedI emptied all and any caches now, afais.
My expected result would be that I see a "Used cached results" line for certain time-cached views.
I get this for content-based views after applying the fix Stephen posted in#7.
The time-cached views are delivered in blocks. The output is handled correctly, aka shows "Used cached output". I have Views 2.8.
Comment #18
voxpelli commentedMe and dereine feel that this is ready for review and committing by merlin, assigning it to him
Comment #19
voxpelli commentedComment #20
merlinofchaos commentedPatch in #13 does not apply.
Comment #21
voxpelli commentedReroll, should work as well as the prior patch - but hasn't verified
Comment #22
merlinofchaos commentedI know this can't apply to 7.x
Comment #23
dawehnerThis one is kind of fun.
db_rewrite_sql does not exist so it might be impossible to get the query with/without the node access.
Comment #24
dawehnerUnassign myself.
Personally i think this is impossible because the node access is runned during execute, but who knows.
Comment #25
voxpelli commentedSelectQueryInterface::preExecute() could probably be used as a substitute for db_rewrite_sql() - that ould enable us to port this patch to D7.
Comment #26
dawehnerAt least the caching does currently uses preExecute to get a well query.
Comment #27
dawehnerAs preExecute is executed in the query you could argue that the rewritten sql is already part of the cache, so let's mark this as fixed.
Comment #29
crea commentedSo, is the caching in Views 6.x-2.x broken ?