You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by GitBox <gi...@apache.org> on 2021/02/22 10:22:35 UTC

[GitHub] [superset] villebro opened a new pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

villebro opened a new pull request #13271:
URL: https://github.com/apache/superset/pull/13271


   ### SUMMARY
   This PR adds some features to `/api/v1/chart/data` needed for native filters, namely:
   - support for retrieval of the total row count of a query (needed for calculating page count when doing server side pagination)
   - support for retrieval of time grains
   - support for retrieval of datasource columns
   - support for retrieving data from multiple datasources in the same request (not needed quite yet, but this adds support for the feature as it will come up later)
   
   This does add some clutter to the `QueryContext`, but since chart plugins currently only have proper access to the chart data endpoint, this is the cleanest solution I could come up with to avoid having to either 1) make huge refactoring to `superset-ui/core` or 2) perform custom REST API calls in `transformProps`.
   
   ### TEST PLAN
   CI + added tests
   
   ### ADDITIONAL INFORMATION
   <!--- Check any relevant boxes with "x" -->
   <!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
   - [ ] Has associated issue:
   - [ ] Changes UI
   - [ ] Requires DB Migration.
   - [ ] Confirm DB Migration upgrade and downgrade tested.
   - [ ] Introduces new feature or API
   - [ ] Removes existing feature or API
   


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] ktmud commented on a change in pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
ktmud commented on a change in pull request #13271:
URL: https://github.com/apache/superset/pull/13271#discussion_r586731445



##########
File path: superset/common/query_actions.py
##########
@@ -0,0 +1,182 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+import copy
+import math
+from typing import Any, Callable, cast, Dict, List, Optional, TYPE_CHECKING
+
+from flask_babel import _
+
+from superset import app
+from superset.connectors.base.models import BaseDatasource
+from superset.exceptions import QueryObjectValidationError
+from superset.utils.core import (
+    ChartDataResultType,
+    extract_column_dtype,
+    extract_dataframe_dtypes,
+    get_time_filter_status,
+    QueryStatus,
+)
+
+if TYPE_CHECKING:
+    from superset.common.query_context import QueryContext
+    from superset.common.query_object import QueryObject
+
+config = app.config
+
+
+def _get_datasource(
+    query_context: "QueryContext", query_obj: "QueryObject"
+) -> BaseDatasource:
+    return query_obj.datasource or query_context.datasource
+
+
+def _get_columns(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "data": [
+            {
+                "column_name": col.column_name,
+                "verbose_name": col.verbose_name,
+                "dtype": extract_column_dtype(col),
+            }
+            for col in datasource.columns
+        ]
+    }
+
+
+def _get_timegrains(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "data": [
+            {
+                "name": grain.name,
+                "function": grain.function,
+                "duration": grain.duration,
+            }
+            for grain in datasource.database.grains()
+        ]
+    }
+
+
+def _get_query(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool,
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "query": datasource.get_query_str(query_obj.to_dict()),
+        "language": datasource.query_language,
+    }
+
+
+def _get_full(
+    query_context: "QueryContext",
+    query_obj: "QueryObject",
+    force_cached: Optional[bool] = False,
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    result_type = query_obj.result_type or query_context.result_type
+    payload = query_context.get_df_payload(query_obj, force_cached=force_cached)
+    df = payload["df"]
+    status = payload["status"]
+    if status != QueryStatus.FAILED:
+        payload["colnames"] = list(df.columns)
+        payload["coltypes"] = extract_dataframe_dtypes(df)
+        payload["data"] = query_context.get_data(df)
+    del payload["df"]
+
+    filters = query_obj.filter
+    filter_columns = cast(List[str], [flt.get("col") for flt in filters])
+    columns = set(datasource.column_names)
+    applied_time_columns, rejected_time_columns = get_time_filter_status(
+        datasource, query_obj.applied_time_extras
+    )
+    payload["applied_filters"] = [
+        {"column": col} for col in filter_columns if col in columns
+    ] + applied_time_columns
+    payload["rejected_filters"] = [
+        {"reason": "not_in_datasource", "column": col}
+        for col in filter_columns
+        if col not in columns
+    ] + rejected_time_columns
+
+    if result_type == ChartDataResultType.RESULTS and status != QueryStatus.FAILED:
+        return {"data": payload["data"]}
+    return payload
+
+
+def _get_samples(
+    query_context: "QueryContext", query_obj: "QueryObject", force_cached: bool = False
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    row_limit = query_obj.row_limit or math.inf
+    query_obj = copy.copy(query_obj)
+    query_obj.is_timeseries = False
+    query_obj.orderby = []
+    query_obj.groupby = []
+    query_obj.metrics = []
+    query_obj.post_processing = []
+    query_obj.row_limit = min(row_limit, config["SAMPLES_ROW_LIMIT"])
+    query_obj.row_offset = 0
+    query_obj.columns = [o.column_name for o in datasource.columns]
+    return _get_full(query_context, query_obj, force_cached)
+
+
+def _get_results(
+    query_context: "QueryContext", query_obj: "QueryObject", force_cached: bool = False
+) -> Dict[str, Any]:
+    payload = _get_full(query_context, query_obj, force_cached)
+    return {"data": payload["data"]}
+
+
+_result_type_functions: Dict[
+    ChartDataResultType, Callable[["QueryContext", "QueryObject", bool], Dict[str, Any]]
+] = {
+    ChartDataResultType.COLUMNS: _get_columns,
+    ChartDataResultType.TIMEGRAINS: _get_timegrains,
+    ChartDataResultType.QUERY: _get_query,
+    ChartDataResultType.SAMPLES: _get_samples,
+    ChartDataResultType.FULL: _get_full,
+    ChartDataResultType.RESULTS: _get_results,

Review comment:
       Wouldn't you still have that mapping if you just create a `_get_rowcount` function that sets `QueryObjects`'s `is_rowcount` to `True`?  I see no difference in setting `is_rowcount` in a `_get_rowcount` function than manipulating other fields of `QueryObject` in `_get_samples` and `_get_query`.
   
   The reason why I think a new result type makes more sense is that from the client-side point of view,  `ResultType.SAMPLES`, `ResultType.QUERY`, and `ResultType.ROW_COUNT` are mutually exclusive, i.e., you cannot have a `QueryObject` with both `result_type = ResultType.SAMPLES` and `is_rowcount = True`.




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] villebro commented on a change in pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
villebro commented on a change in pull request #13271:
URL: https://github.com/apache/superset/pull/13271#discussion_r580986478



##########
File path: superset/common/query_context.py
##########
@@ -152,13 +152,39 @@ def get_single_payload(
         self, query_obj: QueryObject, force_cached: Optional[bool] = False,
     ) -> Dict[str, Any]:
         """Return results payload for a single quey"""
-        if self.result_type == utils.ChartDataResultType.QUERY:
+        result_type = query_obj.result_type or self.result_type
+        datasource = query_obj.datasource or self.datasource
+        if result_type == utils.ChartDataResultType.COLUMNS:

Review comment:
       This is a superb idea!




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] villebro merged pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
villebro merged pull request #13271:
URL: https://github.com/apache/superset/pull/13271


   


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] codecov-io commented on pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
codecov-io commented on pull request #13271:
URL: https://github.com/apache/superset/pull/13271#issuecomment-783325452


   # [Codecov](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=h1) Report
   > Merging [#13271](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=desc) (c875131) into [master](https://codecov.io/gh/apache/superset/commit/9b5e66b728190e0dde5e6ddfb0f018cbdd8e5283?el=desc) (9b5e66b) will **increase** coverage by `7.69%`.
   > The diff coverage is `88.46%`.
   
   [![Impacted file tree graph](https://codecov.io/gh/apache/superset/pull/13271/graphs/tree.svg?width=650&height=150&src=pr&token=KsB0fHcx6l)](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=tree)
   
   ```diff
   @@            Coverage Diff             @@
   ##           master   #13271      +/-   ##
   ==========================================
   + Coverage   72.29%   79.99%   +7.69%     
   ==========================================
     Files         864      298     -566     
     Lines       44883    24314   -20569     
     Branches     5403        0    -5403     
   ==========================================
   - Hits        32450    19449   -13001     
   + Misses      12224     4865    -7359     
   + Partials      209        0     -209     
   ```
   
   | Flag | Coverage Δ | |
   |---|---|---|
   | javascript | `?` | |
   | python | `79.99% <88.46%> (-0.85%)` | :arrow_down: |
   
   Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.
   
   | [Impacted Files](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=tree) | Coverage Δ | |
   |---|---|---|
   | [superset/utils/cache.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvdXRpbHMvY2FjaGUucHk=) | `76.34% <ø> (ø)` | |
   | [superset/connectors/druid/models.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29ubmVjdG9ycy9kcnVpZC9tb2RlbHMucHk=) | `82.06% <50.00%> (-0.08%)` | :arrow_down: |
   | [superset/common/query\_object.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29tbW9uL3F1ZXJ5X29iamVjdC5weQ==) | `90.27% <81.25%> (-1.27%)` | :arrow_down: |
   | [superset/connectors/sqla/models.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29ubmVjdG9ycy9zcWxhL21vZGVscy5weQ==) | `84.58% <87.50%> (-6.00%)` | :arrow_down: |
   | [superset/utils/core.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvdXRpbHMvY29yZS5weQ==) | `88.39% <88.88%> (+0.12%)` | :arrow_up: |
   | [superset/charts/schemas.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY2hhcnRzL3NjaGVtYXMucHk=) | `100.00% <100.00%> (ø)` | |
   | [superset/common/query\_context.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29tbW9uL3F1ZXJ5X2NvbnRleHQucHk=) | `84.75% <100.00%> (-0.04%)` | :arrow_down: |
   | [superset/db\_engines/hive.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvZGJfZW5naW5lcy9oaXZlLnB5) | `0.00% <0.00%> (-85.72%)` | :arrow_down: |
   | [superset/sql\_validators/postgres.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvc3FsX3ZhbGlkYXRvcnMvcG9zdGdyZXMucHk=) | `50.00% <0.00%> (-50.00%)` | :arrow_down: |
   | [superset/db\_engine\_specs/hive.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvZGJfZW5naW5lX3NwZWNzL2hpdmUucHk=) | `73.84% <0.00%> (-16.93%)` | :arrow_down: |
   | ... and [583 more](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree-more) | |
   
   ------
   
   [Continue to review full report at Codecov](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=continue).
   > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
   > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
   > Powered by [Codecov](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=footer). Last update [9b5e66b...c875131](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
   


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] codecov-io edited a comment on pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #13271:
URL: https://github.com/apache/superset/pull/13271#issuecomment-783325452


   # [Codecov](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=h1) Report
   > Merging [#13271](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=desc) (9146bb8) into [master](https://codecov.io/gh/apache/superset/commit/e37c2bf8fd7a671b00c62e621f4046a212aded24?el=desc) (e37c2bf) will **increase** coverage by `15.70%`.
   > The diff coverage is `89.76%`.
   
   [![Impacted file tree graph](https://codecov.io/gh/apache/superset/pull/13271/graphs/tree.svg?width=650&height=150&src=pr&token=KsB0fHcx6l)](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=tree)
   
   ```diff
   @@             Coverage Diff             @@
   ##           master   #13271       +/-   ##
   ===========================================
   + Coverage   64.23%   79.94%   +15.70%     
   ===========================================
     Files         971      300      -671     
     Lines       45178    24353    -20825     
     Branches     4129        0     -4129     
   ===========================================
   - Hits        29019    19468     -9551     
   + Misses      16159     4885    -11274     
   ```
   
   | Flag | Coverage Δ | |
   |---|---|---|
   | cypress | `?` | |
   | python | `79.94% <89.76%> (+12.57%)` | :arrow_up: |
   
   Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.
   
   | [Impacted Files](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=tree) | Coverage Δ | |
   |---|---|---|
   | [superset/utils/cache.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvdXRpbHMvY2FjaGUucHk=) | `76.34% <ø> (ø)` | |
   | [superset/connectors/druid/models.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29ubmVjdG9ycy9kcnVpZC9tb2RlbHMucHk=) | `82.06% <50.00%> (-0.08%)` | :arrow_down: |
   | [superset/common/query\_context.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29tbW9uL3F1ZXJ5X2NvbnRleHQucHk=) | `81.52% <75.00%> (-3.28%)` | :arrow_down: |
   | [superset/common/query\_object.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29tbW9uL3F1ZXJ5X29iamVjdC5weQ==) | `90.27% <81.25%> (-1.27%)` | :arrow_down: |
   | [superset/connectors/sqla/models.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29ubmVjdG9ycy9zcWxhL21vZGVscy5weQ==) | `89.62% <87.50%> (-0.96%)` | :arrow_down: |
   | [superset/utils/core.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvdXRpbHMvY29yZS5weQ==) | `88.45% <92.30%> (+0.18%)` | :arrow_up: |
   | [superset/common/actions.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29tbW9uL2FjdGlvbnMucHk=) | `95.38% <95.38%> (ø)` | |
   | [superset/charts/schemas.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY2hhcnRzL3NjaGVtYXMucHk=) | `100.00% <100.00%> (ø)` | |
   | [superset/sql\_validators/postgres.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvc3FsX3ZhbGlkYXRvcnMvcG9zdGdyZXMucHk=) | `50.00% <0.00%> (-50.00%)` | :arrow_down: |
   | [superset/views/database/views.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvdmlld3MvZGF0YWJhc2Uvdmlld3MucHk=) | `62.69% <0.00%> (-24.88%)` | :arrow_down: |
   | ... and [704 more](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree-more) | |
   
   ------
   
   [Continue to review full report at Codecov](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=continue).
   > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
   > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
   > Powered by [Codecov](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=footer). Last update [e37c2bf...9146bb8](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
   


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] villebro commented on a change in pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
villebro commented on a change in pull request #13271:
URL: https://github.com/apache/superset/pull/13271#discussion_r580139698



##########
File path: superset/common/query_object.py
##########
@@ -271,6 +288,10 @@ def cache_key(self, **extra: Any) -> str:
         """
         cache_dict = self.to_dict()
         cache_dict.update(extra)
+        if self.datasource:
+            cache_dict["datasource"] = self.datasource.uid
+        if self.result_type:
+            cache_dict["result_type"] = self.result_type

Review comment:
       These are only added to the dict if defined to avoid invalidating cache keys of currently cached objects.




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] codecov-io edited a comment on pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #13271:
URL: https://github.com/apache/superset/pull/13271#issuecomment-783325452


   # [Codecov](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=h1) Report
   > Merging [#13271](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=desc) (9146bb8) into [master](https://codecov.io/gh/apache/superset/commit/e37c2bf8fd7a671b00c62e621f4046a212aded24?el=desc) (e37c2bf) will **increase** coverage by `15.72%`.
   > The diff coverage is `89.76%`.
   
   [![Impacted file tree graph](https://codecov.io/gh/apache/superset/pull/13271/graphs/tree.svg?width=650&height=150&src=pr&token=KsB0fHcx6l)](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=tree)
   
   ```diff
   @@             Coverage Diff             @@
   ##           master   #13271       +/-   ##
   ===========================================
   + Coverage   64.23%   79.95%   +15.72%     
   ===========================================
     Files         971      300      -671     
     Lines       45178    24381    -20797     
     Branches     4129        0     -4129     
   ===========================================
   - Hits        29019    19495     -9524     
   + Misses      16159     4886    -11273     
   ```
   
   | Flag | Coverage Δ | |
   |---|---|---|
   | cypress | `?` | |
   | python | `79.95% <89.76%> (+12.59%)` | :arrow_up: |
   
   Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.
   
   | [Impacted Files](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=tree) | Coverage Δ | |
   |---|---|---|
   | [superset/utils/cache.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvdXRpbHMvY2FjaGUucHk=) | `76.34% <ø> (ø)` | |
   | [superset/connectors/druid/models.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29ubmVjdG9ycy9kcnVpZC9tb2RlbHMucHk=) | `82.06% <50.00%> (-0.08%)` | :arrow_down: |
   | [superset/common/query\_context.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29tbW9uL3F1ZXJ5X2NvbnRleHQucHk=) | `81.52% <75.00%> (-3.28%)` | :arrow_down: |
   | [superset/common/query\_object.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29tbW9uL3F1ZXJ5X29iamVjdC5weQ==) | `90.27% <81.25%> (-1.27%)` | :arrow_down: |
   | [superset/connectors/sqla/models.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29ubmVjdG9ycy9zcWxhL21vZGVscy5weQ==) | `89.63% <87.50%> (-0.94%)` | :arrow_down: |
   | [superset/utils/core.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvdXRpbHMvY29yZS5weQ==) | `88.45% <92.30%> (+0.18%)` | :arrow_up: |
   | [superset/common/actions.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY29tbW9uL2FjdGlvbnMucHk=) | `95.38% <95.38%> (ø)` | |
   | [superset/charts/schemas.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvY2hhcnRzL3NjaGVtYXMucHk=) | `100.00% <100.00%> (ø)` | |
   | [superset/sql\_validators/postgres.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvc3FsX3ZhbGlkYXRvcnMvcG9zdGdyZXMucHk=) | `50.00% <0.00%> (-50.00%)` | :arrow_down: |
   | [superset/views/database/views.py](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree#diff-c3VwZXJzZXQvdmlld3MvZGF0YWJhc2Uvdmlld3MucHk=) | `62.69% <0.00%> (-24.88%)` | :arrow_down: |
   | ... and [698 more](https://codecov.io/gh/apache/superset/pull/13271/diff?src=pr&el=tree-more) | |
   
   ------
   
   [Continue to review full report at Codecov](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=continue).
   > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
   > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
   > Powered by [Codecov](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=footer). Last update [e37c2bf...9146bb8](https://codecov.io/gh/apache/superset/pull/13271?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
   


----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] villebro commented on a change in pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
villebro commented on a change in pull request #13271:
URL: https://github.com/apache/superset/pull/13271#discussion_r580986715



##########
File path: superset/common/query_object.py
##########
@@ -107,8 +115,16 @@ def __init__(
         columns: Optional[List[str]] = None,
         orderby: Optional[List[List[str]]] = None,
         post_processing: Optional[List[Optional[Dict[str, Any]]]] = None,
+        is_rowcount: bool = False,
         **kwargs: Any,
     ):
+        self.is_rowcount = is_rowcount
+        self.datasource = None
+        if datasource:
+            self.datasource = ConnectorRegistry.get_datasource(
+                str(datasource["type"]), int(datasource["id"]), db.session
+            )

Review comment:
       Perfect opportunity to introduce `TypedDict`




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] ktmud commented on a change in pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
ktmud commented on a change in pull request #13271:
URL: https://github.com/apache/superset/pull/13271#discussion_r586687878



##########
File path: superset/common/query_actions.py
##########
@@ -0,0 +1,182 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+import copy
+import math
+from typing import Any, Callable, cast, Dict, List, Optional, TYPE_CHECKING
+
+from flask_babel import _
+
+from superset import app
+from superset.connectors.base.models import BaseDatasource
+from superset.exceptions import QueryObjectValidationError
+from superset.utils.core import (
+    ChartDataResultType,
+    extract_column_dtype,
+    extract_dataframe_dtypes,
+    get_time_filter_status,
+    QueryStatus,
+)
+
+if TYPE_CHECKING:
+    from superset.common.query_context import QueryContext
+    from superset.common.query_object import QueryObject
+
+config = app.config
+
+
+def _get_datasource(
+    query_context: "QueryContext", query_obj: "QueryObject"
+) -> BaseDatasource:
+    return query_obj.datasource or query_context.datasource
+
+
+def _get_columns(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "data": [
+            {
+                "column_name": col.column_name,
+                "verbose_name": col.verbose_name,
+                "dtype": extract_column_dtype(col),
+            }
+            for col in datasource.columns
+        ]
+    }
+
+
+def _get_timegrains(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "data": [
+            {
+                "name": grain.name,
+                "function": grain.function,
+                "duration": grain.duration,
+            }
+            for grain in datasource.database.grains()
+        ]
+    }
+
+
+def _get_query(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool,
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "query": datasource.get_query_str(query_obj.to_dict()),
+        "language": datasource.query_language,
+    }
+
+
+def _get_full(
+    query_context: "QueryContext",
+    query_obj: "QueryObject",
+    force_cached: Optional[bool] = False,
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    result_type = query_obj.result_type or query_context.result_type
+    payload = query_context.get_df_payload(query_obj, force_cached=force_cached)
+    df = payload["df"]
+    status = payload["status"]
+    if status != QueryStatus.FAILED:
+        payload["colnames"] = list(df.columns)
+        payload["coltypes"] = extract_dataframe_dtypes(df)
+        payload["data"] = query_context.get_data(df)
+    del payload["df"]
+
+    filters = query_obj.filter
+    filter_columns = cast(List[str], [flt.get("col") for flt in filters])
+    columns = set(datasource.column_names)
+    applied_time_columns, rejected_time_columns = get_time_filter_status(
+        datasource, query_obj.applied_time_extras
+    )
+    payload["applied_filters"] = [
+        {"column": col} for col in filter_columns if col in columns
+    ] + applied_time_columns
+    payload["rejected_filters"] = [
+        {"reason": "not_in_datasource", "column": col}
+        for col in filter_columns
+        if col not in columns
+    ] + rejected_time_columns
+
+    if result_type == ChartDataResultType.RESULTS and status != QueryStatus.FAILED:
+        return {"data": payload["data"]}
+    return payload
+
+
+def _get_samples(
+    query_context: "QueryContext", query_obj: "QueryObject", force_cached: bool = False
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    row_limit = query_obj.row_limit or math.inf
+    query_obj = copy.copy(query_obj)
+    query_obj.is_timeseries = False
+    query_obj.orderby = []
+    query_obj.groupby = []
+    query_obj.metrics = []
+    query_obj.post_processing = []
+    query_obj.row_limit = min(row_limit, config["SAMPLES_ROW_LIMIT"])
+    query_obj.row_offset = 0
+    query_obj.columns = [o.column_name for o in datasource.columns]
+    return _get_full(query_context, query_obj, force_cached)
+
+
+def _get_results(
+    query_context: "QueryContext", query_obj: "QueryObject", force_cached: bool = False
+) -> Dict[str, Any]:
+    payload = _get_full(query_context, query_obj, force_cached)
+    return {"data": payload["data"]}
+
+
+_result_type_functions: Dict[
+    ChartDataResultType, Callable[["QueryContext", "QueryObject", bool], Dict[str, Any]]
+] = {
+    ChartDataResultType.COLUMNS: _get_columns,
+    ChartDataResultType.TIMEGRAINS: _get_timegrains,
+    ChartDataResultType.QUERY: _get_query,
+    ChartDataResultType.SAMPLES: _get_samples,
+    ChartDataResultType.FULL: _get_full,
+    ChartDataResultType.RESULTS: _get_results,

Review comment:
       @villebro Sorry for being late to the party, but it there a reason why `is_rowcount` is not implemented as another `ChartDataResultType`?




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] villebro commented on a change in pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
villebro commented on a change in pull request #13271:
URL: https://github.com/apache/superset/pull/13271#discussion_r587182362



##########
File path: superset/common/query_actions.py
##########
@@ -0,0 +1,182 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+import copy
+import math
+from typing import Any, Callable, cast, Dict, List, Optional, TYPE_CHECKING
+
+from flask_babel import _
+
+from superset import app
+from superset.connectors.base.models import BaseDatasource
+from superset.exceptions import QueryObjectValidationError
+from superset.utils.core import (
+    ChartDataResultType,
+    extract_column_dtype,
+    extract_dataframe_dtypes,
+    get_time_filter_status,
+    QueryStatus,
+)
+
+if TYPE_CHECKING:
+    from superset.common.query_context import QueryContext
+    from superset.common.query_object import QueryObject
+
+config = app.config
+
+
+def _get_datasource(
+    query_context: "QueryContext", query_obj: "QueryObject"
+) -> BaseDatasource:
+    return query_obj.datasource or query_context.datasource
+
+
+def _get_columns(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "data": [
+            {
+                "column_name": col.column_name,
+                "verbose_name": col.verbose_name,
+                "dtype": extract_column_dtype(col),
+            }
+            for col in datasource.columns
+        ]
+    }
+
+
+def _get_timegrains(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "data": [
+            {
+                "name": grain.name,
+                "function": grain.function,
+                "duration": grain.duration,
+            }
+            for grain in datasource.database.grains()
+        ]
+    }
+
+
+def _get_query(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool,
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "query": datasource.get_query_str(query_obj.to_dict()),
+        "language": datasource.query_language,
+    }
+
+
+def _get_full(
+    query_context: "QueryContext",
+    query_obj: "QueryObject",
+    force_cached: Optional[bool] = False,
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    result_type = query_obj.result_type or query_context.result_type
+    payload = query_context.get_df_payload(query_obj, force_cached=force_cached)
+    df = payload["df"]
+    status = payload["status"]
+    if status != QueryStatus.FAILED:
+        payload["colnames"] = list(df.columns)
+        payload["coltypes"] = extract_dataframe_dtypes(df)
+        payload["data"] = query_context.get_data(df)
+    del payload["df"]
+
+    filters = query_obj.filter
+    filter_columns = cast(List[str], [flt.get("col") for flt in filters])
+    columns = set(datasource.column_names)
+    applied_time_columns, rejected_time_columns = get_time_filter_status(
+        datasource, query_obj.applied_time_extras
+    )
+    payload["applied_filters"] = [
+        {"column": col} for col in filter_columns if col in columns
+    ] + applied_time_columns
+    payload["rejected_filters"] = [
+        {"reason": "not_in_datasource", "column": col}
+        for col in filter_columns
+        if col not in columns
+    ] + rejected_time_columns
+
+    if result_type == ChartDataResultType.RESULTS and status != QueryStatus.FAILED:
+        return {"data": payload["data"]}
+    return payload
+
+
+def _get_samples(
+    query_context: "QueryContext", query_obj: "QueryObject", force_cached: bool = False
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    row_limit = query_obj.row_limit or math.inf
+    query_obj = copy.copy(query_obj)
+    query_obj.is_timeseries = False
+    query_obj.orderby = []
+    query_obj.groupby = []
+    query_obj.metrics = []
+    query_obj.post_processing = []
+    query_obj.row_limit = min(row_limit, config["SAMPLES_ROW_LIMIT"])
+    query_obj.row_offset = 0
+    query_obj.columns = [o.column_name for o in datasource.columns]
+    return _get_full(query_context, query_obj, force_cached)
+
+
+def _get_results(
+    query_context: "QueryContext", query_obj: "QueryObject", force_cached: bool = False
+) -> Dict[str, Any]:
+    payload = _get_full(query_context, query_obj, force_cached)
+    return {"data": payload["data"]}
+
+
+_result_type_functions: Dict[
+    ChartDataResultType, Callable[["QueryContext", "QueryObject", bool], Dict[str, Any]]
+] = {
+    ChartDataResultType.COLUMNS: _get_columns,
+    ChartDataResultType.TIMEGRAINS: _get_timegrains,
+    ChartDataResultType.QUERY: _get_query,
+    ChartDataResultType.SAMPLES: _get_samples,
+    ChartDataResultType.FULL: _get_full,
+    ChartDataResultType.RESULTS: _get_results,

Review comment:
       I don't mind adding a result type as a convenience method for fetching the row count. However, the preferred method for retrieving row counts should IMO be explicitly setting `is_rowcount` on `QueryObject`, as it will make it possible to set `ResultType.QUERY` on `QueryContext` and by doing so fetch only the queries for all `QueryObject`s (we don't yet support showing queries for multiple queries, but I hope we can add it soon): https://github.com/apache/superset/blob/ca27b00f3a2ce6f1a2b4f2e4a6586b3c3fc578a5/superset-frontend/src/explore/components/DisplayQueryButton.jsx#L170




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] villebro commented on a change in pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
villebro commented on a change in pull request #13271:
URL: https://github.com/apache/superset/pull/13271#discussion_r586704874



##########
File path: superset/common/query_actions.py
##########
@@ -0,0 +1,182 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+import copy
+import math
+from typing import Any, Callable, cast, Dict, List, Optional, TYPE_CHECKING
+
+from flask_babel import _
+
+from superset import app
+from superset.connectors.base.models import BaseDatasource
+from superset.exceptions import QueryObjectValidationError
+from superset.utils.core import (
+    ChartDataResultType,
+    extract_column_dtype,
+    extract_dataframe_dtypes,
+    get_time_filter_status,
+    QueryStatus,
+)
+
+if TYPE_CHECKING:
+    from superset.common.query_context import QueryContext
+    from superset.common.query_object import QueryObject
+
+config = app.config
+
+
+def _get_datasource(
+    query_context: "QueryContext", query_obj: "QueryObject"
+) -> BaseDatasource:
+    return query_obj.datasource or query_context.datasource
+
+
+def _get_columns(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "data": [
+            {
+                "column_name": col.column_name,
+                "verbose_name": col.verbose_name,
+                "dtype": extract_column_dtype(col),
+            }
+            for col in datasource.columns
+        ]
+    }
+
+
+def _get_timegrains(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "data": [
+            {
+                "name": grain.name,
+                "function": grain.function,
+                "duration": grain.duration,
+            }
+            for grain in datasource.database.grains()
+        ]
+    }
+
+
+def _get_query(
+    query_context: "QueryContext", query_obj: "QueryObject", _: bool,
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    return {
+        "query": datasource.get_query_str(query_obj.to_dict()),
+        "language": datasource.query_language,
+    }
+
+
+def _get_full(
+    query_context: "QueryContext",
+    query_obj: "QueryObject",
+    force_cached: Optional[bool] = False,
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    result_type = query_obj.result_type or query_context.result_type
+    payload = query_context.get_df_payload(query_obj, force_cached=force_cached)
+    df = payload["df"]
+    status = payload["status"]
+    if status != QueryStatus.FAILED:
+        payload["colnames"] = list(df.columns)
+        payload["coltypes"] = extract_dataframe_dtypes(df)
+        payload["data"] = query_context.get_data(df)
+    del payload["df"]
+
+    filters = query_obj.filter
+    filter_columns = cast(List[str], [flt.get("col") for flt in filters])
+    columns = set(datasource.column_names)
+    applied_time_columns, rejected_time_columns = get_time_filter_status(
+        datasource, query_obj.applied_time_extras
+    )
+    payload["applied_filters"] = [
+        {"column": col} for col in filter_columns if col in columns
+    ] + applied_time_columns
+    payload["rejected_filters"] = [
+        {"reason": "not_in_datasource", "column": col}
+        for col in filter_columns
+        if col not in columns
+    ] + rejected_time_columns
+
+    if result_type == ChartDataResultType.RESULTS and status != QueryStatus.FAILED:
+        return {"data": payload["data"]}
+    return payload
+
+
+def _get_samples(
+    query_context: "QueryContext", query_obj: "QueryObject", force_cached: bool = False
+) -> Dict[str, Any]:
+    datasource = _get_datasource(query_context, query_obj)
+    row_limit = query_obj.row_limit or math.inf
+    query_obj = copy.copy(query_obj)
+    query_obj.is_timeseries = False
+    query_obj.orderby = []
+    query_obj.groupby = []
+    query_obj.metrics = []
+    query_obj.post_processing = []
+    query_obj.row_limit = min(row_limit, config["SAMPLES_ROW_LIMIT"])
+    query_obj.row_offset = 0
+    query_obj.columns = [o.column_name for o in datasource.columns]
+    return _get_full(query_context, query_obj, force_cached)
+
+
+def _get_results(
+    query_context: "QueryContext", query_obj: "QueryObject", force_cached: bool = False
+) -> Dict[str, Any]:
+    payload = _get_full(query_context, query_obj, force_cached)
+    return {"data": payload["data"]}
+
+
+_result_type_functions: Dict[
+    ChartDataResultType, Callable[["QueryContext", "QueryObject", bool], Dict[str, Any]]
+] = {
+    ChartDataResultType.COLUMNS: _get_columns,
+    ChartDataResultType.TIMEGRAINS: _get_timegrains,
+    ChartDataResultType.QUERY: _get_query,
+    ChartDataResultType.SAMPLES: _get_samples,
+    ChartDataResultType.FULL: _get_full,
+    ChartDataResultType.RESULTS: _get_results,

Review comment:
       That's the way I thought about implementing it first, but I felt it better to implement it as a `QueryObject` property, as it has to be passed to the SQLA model as it affects the rendered query (I feel `QueryObject` should be mostly 1-1 mapped to the query dict that's unpacked into `get_sqla_query`).




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] dpgaspar commented on a change in pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
dpgaspar commented on a change in pull request #13271:
URL: https://github.com/apache/superset/pull/13271#discussion_r580423331



##########
File path: superset/common/query_context.py
##########
@@ -152,13 +152,39 @@ def get_single_payload(
         self, query_obj: QueryObject, force_cached: Optional[bool] = False,
     ) -> Dict[str, Any]:
         """Return results payload for a single quey"""
-        if self.result_type == utils.ChartDataResultType.QUERY:
+        result_type = query_obj.result_type or self.result_type

Review comment:
       nit: could make sense to document the constructor since, not passing `result_type` assumes it is `FULL` or passed on the `query_obj`

##########
File path: superset/common/query_object.py
##########
@@ -107,8 +115,16 @@ def __init__(
         columns: Optional[List[str]] = None,
         orderby: Optional[List[List[str]]] = None,
         post_processing: Optional[List[Optional[Dict[str, Any]]]] = None,
+        is_rowcount: bool = False,
         **kwargs: Any,
     ):
+        self.is_rowcount = is_rowcount
+        self.datasource = None
+        if datasource:
+            self.datasource = ConnectorRegistry.get_datasource(
+                str(datasource["type"]), int(datasource["id"]), db.session
+            )

Review comment:
       This input does not seem validated at this point. What happens if the `datasource["id"]` does not exist?

##########
File path: superset/common/query_context.py
##########
@@ -152,13 +152,39 @@ def get_single_payload(
         self, query_obj: QueryObject, force_cached: Optional[bool] = False,
     ) -> Dict[str, Any]:
         """Return results payload for a single quey"""
-        if self.result_type == utils.ChartDataResultType.QUERY:
+        result_type = query_obj.result_type or self.result_type
+        datasource = query_obj.datasource or self.datasource
+        if result_type == utils.ChartDataResultType.COLUMNS:

Review comment:
       since these can grow further, could make the code look cleaner if we create a simple `Dict` that maps to functions with the actual comprehensions, something like:
   
   ``` python
   result_type_map = {
       utils.ChartDataResultType.COLUMNS: get_result_type_columns,
       utils.ChartDataResultType.TIMEGRAINS: get_result_type_time_grains,
       utils.ChartDataResultType.QUERY: get_result_type_query
   }
   ```  
   

##########
File path: superset/connectors/sqla/models.py
##########
@@ -1253,10 +1254,19 @@ def get_sqla_query(  # pylint: disable=too-many-arguments,too-many-locals,too-ma
                     result.df, dimensions, groupby_exprs_sans_timestamp
                 )
                 qry = qry.where(top_groups)
+        if is_rowcount:
+            if not db_engine_spec.allows_subqueries:
+                raise QueryObjectValidationError("Database does not support subqueries")

Review comment:
       nit: can this surface to the UI? if use `_("Database ....")` if not ignore me :P 




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


[GitHub] [superset] villebro commented on a change in pull request #13271: feat(chart-data): add rowcount, timegrain and column result types

Posted by GitBox <gi...@apache.org>.
villebro commented on a change in pull request #13271:
URL: https://github.com/apache/superset/pull/13271#discussion_r580988845



##########
File path: superset/utils/core.py
##########
@@ -83,6 +83,7 @@
 from sqlalchemy.engine.reflection import Inspector
 from sqlalchemy.sql.type_api import Variant
 from sqlalchemy.types import TEXT, TypeDecorator
+from typing_extensions import TypedDict

Review comment:
       Importing from `typing_extensions` for backward compatibility as `TypeDict` is introduced in Python 3.8




----------------------------------------------------------------
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.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org