surawut-jirasaktavee opened a new issue, #45877:
URL: https://github.com/apache/superset/issues/45877

   ### Bug description
   
   Chart-data results for semantic views (`datasource_type: "semantic_view"`, 
`superset/semantic_layers/`) are cached under the same key for every user, even 
with the `CACHE_QUERY_BY_USER` feature flag on. When a semantic-layer provider 
returns results that depend on the user, one user can get another user's cached 
result.
   
   #### How to reproduce
   
   Environment: Superset master (a8c13c6), `SEMANTIC_LAYERS` on, a shared data 
cache (for example, Redis), `CACHE_QUERY_BY_USER: True`. The semantic-layer 
provider returns results that depend on the querying user (for example, the 
upstream engine applies per-user row filtering).
   
   1. User A runs a chart on a semantic view. A gets the rows A is allowed to 
see.
   2. User B, who is allowed to see different rows, runs the same chart query. 
B gets A's result, with `is_cached: true`.
   3. Clear the cache and reverse the order: A gets B's cached result.
   
   Both responses have the same `cache_key`.
   
   #### Expected results
   
   With `CACHE_QUERY_BY_USER` on, each user gets their own result-cache entry, 
as for datasets.
   
   #### Actual results
   
   All users share one cache entry per query. The flag is silently ignored for 
semantic views.
   
   #### Root cause (refs at 4e6d03bf99)
   
   1. `QueryObject.cache_key` adds the per-user key by calling 
`add_impersonation_cache_key_if_needed(self.datasource.database, cache_dict)` 
inside `try/except AttributeError` 
([superset/common/query_object.py#L727-L733](https://github.com/apache/superset/blob/4e6d03bf99223e82cd6b5c4c8a3ba806dc24cb83/superset/common/query_object.py#L727-L733)).
 A semantic view has no `.database`, so the `AttributeError` is swallowed and 
no user key is added.
   2. `SemanticView.get_extra_cache_keys` returns only `[metadata_generation, 
"semantic-null-filters-v1", optional result version]`, with nothing per user 
([superset/semantic_layers/models.py#L902-L908](https://github.com/apache/superset/blob/4e6d03bf99223e82cd6b5c4c8a3ba806dc24cb83/superset/semantic_layers/models.py#L902-L908)).
   3. `QueryContextProcessor.query_cache_key` builds the key from those values 
([superset/common/query_context_processor.py#L456-L481](https://github.com/apache/superset/blob/4e6d03bf99223e82cd6b5c4c8a3ba806dc24cb83/superset/common/query_context_processor.py#L456-L481)).
 `get_df_payload_result` reads the ordinary result cache with that key before 
the datasource runs 
([#L278-L298](https://github.com/apache/superset/blob/4e6d03bf99223e82cd6b5c4c8a3ba806dc24cb83/superset/common/query_context_processor.py#L278-L298)).
 So the experimental containment cache (`SEMANTIC_LAYER_CONTAINMENT_CACHE`) 
never runs on a hit, and its `EXECUTION_CONTEXT` scope cannot prevent the 
cross-user hit.
   
   #### Possible fix
   
   One option: when `CACHE_QUERY_BY_USER` is on, 
`SemanticView.get_extra_cache_keys` adds a per-user partition: 
`("semantic-user", identity_digest)` from 
`superset.semantic_layers.execution.current_host_execution_context()`. This is 
the SDK's opaque partition token (HMAC over installation namespace, principal, 
effective role IDs and guest flag).
   
   - Flag off: the key is unchanged, so existing caches stay valid.
   - Embedded guests get no partition. The digest does not tell guest tokens 
apart, and the docs say it must not be used as a guest partition key. Semantic 
views refuse guest row rules, and connection mode runs every guest under the 
same upstream account, so guests can safely share results.
   - `CACHE_IMPERSONATION` is not mapped. For datasets it applies only when the 
database has `impersonate_user`, and semantic views have no such setting.
   
   ### Screenshots/recordings
   
   _No response_
   
   ### Superset version
   
   master / latest-dev
   
   ### Python version
   
   3.11
   
   ### Node version
   
   Not applicable
   
   ### Browser
   
   Chrome
   
   ### Additional context
   
   Reproduced on master (a8c13c6); not tested on a release.
   
   I can contribute to this if it's considered a bug, and I'm open to other 
approaches.
   
   ### Checklist
   
   - [ ] I have searched Superset docs and Slack and didn't find a solution to 
my problem.
   - [x] I have searched the GitHub issue tracker and didn't find a similar bug 
report.
   - [ ] I have checked Superset's logs for errors and if I found a relevant 
Python stacktrace, I included it here as text in the "additional context" 
section.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to