-
Notifications
You must be signed in to change notification settings - Fork 14k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Support multiple queries per request #11880
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
look stright forward
extending the object and keeping backward comparability to a single query response
Codecov Report
@@ Coverage Diff @@
## master #11880 +/- ##
==========================================
+ Coverage 63.37% 63.60% +0.23%
==========================================
Files 970 481 -489
Lines 47937 29682 -18255
Branches 4736 0 -4736
==========================================
- Hits 30380 18880 -11500
+ Misses 17370 10802 -6568
+ Partials 187 0 -187
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
@simchanielsen there's currently a PR open implementing async queries for charts (SIP-39) that I'm hoping to get merged in the next week or so. I'm curious how you see multiple queries working with this async model, and what changes you're proposing on the backend to support this. Also curious, in general, what the use cases are for multiple queries in a visualization. |
@robdiciuccio A classic use-case for multiple queries is uplifting table pagination in which you query the page data and second the total item count for determining how many pages to display |
And about async queries, once feature is mature we can consider supporting multiple queries there as well |
@robdiciuccio based on my latest review of the async PR, I don't anticipate this feature will cause any complications with said feature. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM on first pass, but I'd be interested in seeing what the cached status looks like. I assume it should be like this:
- If all queries missed the cache, no cache pill is visible.
- If at least one result came from the cache, the cache pill is visible.
- On hover the cache status of all queries should be visible?
Curious to hear your thoughts.
const cachedWhen = moment.utc(cachedDttm).fromNow(); | ||
const cachedWhen = cachedDttm.map(itemCachedDttm => | ||
moment.utc(itemCachedDttm).fromNow(), | ||
); | ||
const updatedWhen = updatedDttm ? moment.utc(updatedDttm).fromNow() : ''; | ||
const refreshTooltip = isCached | ||
? t('Cached %s', cachedWhen) | ||
: (updatedWhen && t('Fetched %s', updatedWhen)) || ''; | ||
const getCachedTitle = itemCached => { | ||
return itemCached | ||
? t('Cached %s', cachedWhen) | ||
: updatedWhen && t('Fetched %s', updatedWhen); | ||
}; | ||
let refreshTooltip = isCached.map(getCachedTitle) || ''; | ||
// If all queries have same cache time we can unit them to one | ||
refreshTooltip = [...new Set(refreshTooltip)].join(', '); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you share a screenshot of what this looks like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@villebro So basically if all requests will have same time it will look like"
And if different then like this (just emulate by code changes for screenshot):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should instead have something like this for the case when there are more than one result:
Force refresh
Query 1: Fetched a minute ago
Query 2: Fetched 3 minutes ago
Query 3: Not cached
Also, we should think about how to display multiple results in the "View Results" tab. But that can wait; let's just make sure the user experience is unchanged for single queries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@simchanielsen
could you share the new screenshot?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. As this feature requires superset-ui/core: "^0.15.15"
, it won't yet function without the bump. So you may potentially want to wait for the dashboard native filter to merge which should happen shortly (it bumps all relevant deps). If this is urgent, feel free to add the bump to this PR.
What's still unclear to me are the proposed backend changes to support multiple queries, and how that will affect the async query feature, which will be coming out of draft status this week.
|
Is there a SIP that references support for multiple queries in charts? |
@robdiciuccio BE already supports running multiple queries for a long time now. |
@robdiciuccio here's my take on the topic:
|
Thanks for the context @villebro. Good to know the plan is not to modify the backend here. |
const isFaded = refreshOverlayVisible && !errorMessage; | ||
this.renderContainerStartTime = Logger.getTimestamp(); | ||
if (chartStatus === 'failed') { | ||
return this.renderErrorMessage(); | ||
return queriesResponse.map(item => this.renderErrorMessage(item)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a screenshot of multiple errors rendered in a chart?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robdiciuccio Hi good catch, I didn't check it properly for all kinds of charts (new/old). I pushed now some small fix for it. Basically for now for new api there is no case that it returns more than 1 error per request even for multi queries, but if it will return we can support it, but for now it will be only one error.
P.S. If you have some more places where I can check this functionality, update me please, because I'm new in Superset so I don't know all places and cases of its usages :)
Attaching screenshots after my fix for charts:
), | ||
); | ||
return dispatch( | ||
chartUpdateSucceeded(queryResponse, queriesResponse, key), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the thinking behind adding another value here rather than replacing the current queryResponse
? This is essentially doubling the data that's being passed around to components.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robdiciuccio hmm... good point, actually I wanted avoid refactoring of a lot places in code, but now I see I think I can handle it, I also will add someone more to review, where I see that my refactor will affect his parts of code to be sure.
I pushed now refactored code as you proposed and asked @etr2460 to review also... I tested these changes in explore/dashboard in areas that I know, but if there are some other places, that I need to test please update me.
I also see that affected some code that @suddjian implemented, may be it can be good to add him as reviewer?
Thanks
It's backward compatible feature so can be merged unrelated |
@@ -132,12 +132,12 @@ export const selectIndicatorsForChart = ( | |||
// for now we only need to know which columns are compatible/incompatible, | |||
// so grab the columns from the applied/rejected filters | |||
const appliedColumns: Set<string> = new Set( | |||
(chart?.queryResponse?.applied_filters || []).map( | |||
(chart?.queriesResponse?.[0]?.applied_filters || []).map( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@etr2460 Hi I see you implemented this part of code, I refactored it to use multi queries, can you please look that my changes not break some functionality. Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I implemented this logic. The goal of these two lines is to get a set of all the filters that were applied on a chart, and the filters that were rejected (due to the column not existing in the dataset), in order to display them in the filter badge.
If a chart makes multiple queries, it would probably be more correct to add the applied_filters
and rejected_filters
from each of the queries, instead of just the first one. But that really depends on how dashboard filters works with multiple queries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a chart makes multiple queries, it would probably be more correct to add the
applied_filters
andrejected_filters
from each of the queries, instead of just the first one. But that really depends on how dashboard filters works with multiple queries.
I think we should probably be applying the same filters to all QueryObject
s. Since a QueryContext
currently only supports a single datasource, the applied/rejected columns should be identical. However, temporal filters will only be applicable for QueryObject
s with is_temporal: true
.
chartStackTrace: action.queryResponse | ||
? action.queryResponse.stacktrace | ||
queriesResponse: action.queriesResponse, | ||
chartStackTrace: action.queriesResponse |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@etr2460 and also this one please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the error message changes are fine
Can this be merged? |
Hi @simchanielsen, heads-up that the async queries PR has been merged, which may affect how the chart actions are called here. Happy to answer any questions about the changes. |
@@ -361,38 +361,36 @@ export function exploreJSON( | |||
|
|||
const chartDataRequestCaught = chartDataRequest | |||
.then(response => { | |||
const queriesResponse = response.result; | |||
|
|||
if (isFeatureEnabled(FeatureFlag.GLOBAL_ASYNC_QUERIES)) { | |||
// deal with getChartDataRequest transforming the response data | |||
const result = 'result' in response ? response.result[0] : response; | |||
return dispatch(chartUpdateQueued(result, key)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robdiciuccio should we continue sending a single result to chartUpdateQuered action?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the return value here is a async job metadata payload.
Can we review and merge ? |
Running this locally with the
Also:
Looking into the cause. |
* upstream/master: (55 commits) feat(explore): time picker enhancement (apache#11418) feat: update alert/report icons and column order (apache#12081) feat(explore): metrics and filters controls redesign (apache#12095) feat(alerts/reports): add refresh action (apache#12071) chore: add latest tag action (apache#11148) fix(reports): increase crontab size and alert fixes (apache#12056) Small typo fix in Athena connection docs (apache#12099) feat(queries): security perm simplification (apache#12072) feat(databases): security perm simplification (apache#12036) feat(dashboards): security permissions simplification (apache#12012) feat(logs): security permissions simplification (apache#12061) chore: Remove unused CodeModal (apache#11972) Fix typescript error (apache#12074) fix: handle context-dependent feature flags in CLI (apache#12088) fix: Fix "View in SQLLab" bug (apache#12086) feat(alert/report): add 'not null' condition option to modal (apache#12077) bumping superset ui to 15.18 and deckgl to 0.3.2 (apache#12078) fix: Python dependencies in apache#11499 (apache#12079) reset active tab on open (apache#12048) fix: improve import flow UI/UX (apache#12070) ...
@robdiciuccio I've added necessary changes. |
@amitmiran137 CI has been slightly flaky lately. I restarted, let's see if this fixes it. |
* refactor: add queriesData fields for multiple queries * feat: support multi queries request * lint: fix lint * lint: fix lint * lint: fix lint * fix: fix CR notes * fix: fix CR notes * fix: fix CR notes * fix: fix error case for multi queries * feat: change queryResponse to queriesResponse * fix: revert webpack * test: fix tests * chore: lint * chore: adjust asyncEvent to multiple results * fix: lint * fix: eslint * fix: another eslint rule Co-authored-by: Amit Miran <[email protected]> Co-authored-by: amitmiran137 <[email protected]>
* refactor: add queriesData fields for multiple queries * feat: support multi queries request * lint: fix lint * lint: fix lint * lint: fix lint * fix: fix CR notes * fix: fix CR notes * fix: fix CR notes * fix: fix error case for multi queries * feat: change queryResponse to queriesResponse * fix: revert webpack * test: fix tests * chore: lint * chore: adjust asyncEvent to multiple results * fix: lint * fix: eslint * fix: another eslint rule Co-authored-by: Amit Miran <[email protected]> Co-authored-by: amitmiran137 <[email protected]>
SUMMARY
This feat give opportunity to get from BE response multiple query results and pass them to Chart plugins
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Network Response:
Results in chart plugin before:
Results in chart plugin after:
TEST PLAN
Build request with multiple queries
Related to: apache-superset/superset-ui#846
ADDITIONAL INFORMATION