-
Notifications
You must be signed in to change notification settings - Fork 14.6k
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
Add separate limit setting for SqlLab #4941
Conversation
I don't have time to really review now but wanted to make sure you've taken this https://github.com/apache/incubator-superset/blob/master/superset/assets/src/SqlLab/components/SqlEditor.jsx#L195 into consideration |
Yeah I have. I think that should still show up as it indicates whether the limit was hit. It should retain the current behavior of not showing up if the number of rows returned is less than the limit applied. (or are you referring to some other behavior?) |
Codecov Report
@@ Coverage Diff @@
## master #4941 +/- ##
=========================================
- Coverage 77.01% 77% -0.02%
=========================================
Files 64 64
Lines 9508 9516 +8
=========================================
+ Hits 7323 7328 +5
- Misses 2185 2188 +3
Continue to review full report at Codecov.
|
Sorry about the delay. Let's get this through. Mind rebasing? |
@mistercrunch There are a few things to consider given the current changes in master. Since now you are fetching the limit if it exists in the query, should the query's written limit override the one specified in the For example, if I have a query like:
and the
whereas in the to-be-rebased version, I have to apply either This can lead to even more confusion if we have a query with multiple limits, for example:
Does the user know that only the (As an aside, for the query:
Neither of these limits are fetched with the regex.) I think whichever route we do end up going with, the Let me know if I'm misunderstanding how implementation of limiting (in current master) works, or if there is a better way to resolve this conflict that makes more sense. |
@jeffreythewang a few recommendations for us get this through.
With the three changes here, it should work. I'm happy to help out with any of the parts. |
7945995
to
a49771e
Compare
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 we're going with having the UI box be the central point of all limit information for the user, then #5774 can be abandoned, and code related to that can be removed.
query = Query( | ||
database_id=int(database_id), | ||
limit=mydb.db_engine_spec.get_limit_from_sql(sql), | ||
limit=min(lim for lim in limits if lim is not None), |
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 built this with the assumption that we are going to do limiting via query replacement within the context of SQL Lab, so only the smaller limit is chosen.
73745cd
to
a49771e
Compare
@@ -366,6 +366,8 @@ export const initialState = { | |||
workspaceQueries: [], | |||
queriesLastUpdate: 0, | |||
activeSouthPaneTab: 'Results', | |||
defaultQueryLimit: 100, | |||
maxRow: 10000, |
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.
Can we make these defaults get passed from the backend's config.py to the frontend?
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.
These defaults are solely for unit tests.
style={{ cursor: 'pointer' }} | ||
onClick={this.handleToggle.bind(this)} | ||
> | ||
LIMIT {this.props.value || this.props.maxRow || '∞'} |
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.
Why is infinity still a possibility?
superset/config.py
Outdated
@@ -282,6 +282,9 @@ | |||
# in the results backend. This also becomes the limit when exporting CSVs | |||
SQL_MAX_ROW = 100000 | |||
|
|||
# Default row limit for SQL Lab queries | |||
DEFAULT_SQLLAB_LIMIT = 10000 | |||
|
|||
# Limit to be returned to the frontend. | |||
DISPLAY_MAX_ROW = 1000 |
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.
Can we change this to 10K or make it equal to DEFAULT_SQLLAB_LIMIT?
LGTM, thanks for working on this Jeff. I've asked @graceguo-supercat to take a second look in case I missed anything. |
const value = 100; | ||
wrapper = shallow(factory({ ...defaultProps, value })); | ||
wrapper.find(Label).first().simulate('click'); | ||
setTimeout(() => { |
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.
setTimeout may cause flaky when running in Travis CI, do you really need it? also I saw in the ListControl you have Overlay, Popover, but you test on Tooltip component?
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 replaced Tooltip
assertions with assertions on validationErrors
instead.
6b57ccc
to
c955053
Compare
Note that this is not ready to be merged until we find a way to load in the default values without clearing the existing state of the redux store. |
hi @jeffreythewang Superset use redux-localstorage store sql lab user queries. Currently we sync sql_lab Redux's complete store state with localStorage. check It makes sense that sql_lab configuration should be set from server-side (by passing through bootstrap data), and only user data(mostly queries) are stored in localStorage. |
hi @jeffreythewang I talked this feature with @kristw. He has a nice suggestion: can we allow query limit for each different tab?
|
@graceguo-supercat Yup that is how it currently works in my implementation. Each tab has it's own |
} | ||
|
||
setValueAndClose(val) { | ||
this.setState({ textValue: val }, this.submitAndClose.bind(this)); |
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 the binding in constructor so it won't create new function every time this gets called.
|
||
isValidLimit(limit) { | ||
const value = parseInt(limit, 10); | ||
return !(isNaN(value) || value <= 0 || (this.props.maxRow && value > this.props.maxRow)); |
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.
Use Number.isNaN
instead of isNaN
bsStyle="primary" | ||
className="float-left ok" | ||
disabled={!isValid} | ||
onClick={this.submitAndClose.bind(this)} |
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.
bind in constructor once.
<Overlay | ||
rootClose | ||
show={this.state.showOverlay} | ||
onHide={this.handleHide.bind(this)} |
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.
bind in constructor.
<div> | ||
<Label | ||
style={{ cursor: 'pointer' }} | ||
onClick={this.handleToggle.bind(this)} |
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.
bind in constructor
const errorMsg = 'Row limit must be positive integer' + | ||
(this.props.maxRow ? ` and below ${this.props.maxRow}` : ''); | ||
return ( | ||
<Popover id="sqllab-limit-results"> |
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.
Is the id
necessary?
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.
This is primarily for getting rid of the warning. Do we want to remove it?
const textValue = this.state.textValue; | ||
const isValid = this.isValidLimit(textValue); | ||
const errorMsg = 'Row limit must be positive integer' + | ||
(this.props.maxRow ? ` and below ${this.props.maxRow}` : ''); |
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.
and below
=> not greater than
condition is value <= maxRow
?
I've updated this with a working implementation for updating How I tested:
@graceguo-supercat I initially tried using |
Use separate param for wrap sql Get query limit from config unit tests for limit control rendering in sql editor py unit test pg tests Add max rows limit Remove concept of infinity, always require defined limits consistency Assert on validation errors instead of tooltip fix unit tests attempt persist state pr comments and linting
8e90fa7
to
dd66a8e
Compare
superset/config.py
Outdated
# Limit to be returned to the frontend. | ||
DISPLAY_MAX_ROW = 1000 | ||
# Default row limit for SQL Lab queries | ||
DEFAULT_SQLLAB_LIMIT = 10000 |
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.
@mistercrunch Sql Lab used to only render 1000 rows for each query, but fetch a much bigger number of rows of results. After this feature, sql lab will fetch and render same number of results.
Do you have any suggestion on this default query limit number?
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!
* Add separate limit setting for SqlLab Use separate param for wrap sql Get query limit from config unit tests for limit control rendering in sql editor py unit test pg tests Add max rows limit Remove concept of infinity, always require defined limits consistency Assert on validation errors instead of tooltip fix unit tests attempt persist state pr comments and linting * load configs in via common param * default to 1k
Summary
Description
A common problem people have is that they input a query in SqlLab to preview their data before hitting visualize to create a table, and then it takes forever to run. This can be a pain (on them and potentially on the database).
Currently one workaround is to manually enter a limit in the query editor, visualizing (which creates the datasource), and then later removing it from the base query (by editing the created datasource). With this in mind, an additional/alternative solution might be to allow users to edit the sub-query in the visualize modal before creating their datasource.
So here's a way to have a limit only in the context of SQL editor. The limit is only applied as a wrapper for select queries, and not saved in any persistent database.
Examples
Related PR
#4834 - I like this idea, but not sure if every database supports prefetching. If going with this route, I'd have a configurable page size.
Related Issues
#4588