mistercrunch closed pull request #4755: Pass granularity from backend to 
frontend as ISO duration
URL: https://github.com/apache/incubator-superset/pull/4755
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/superset/assets/javascripts/explore/stores/controls.jsx 
b/superset/assets/javascripts/explore/stores/controls.jsx
index e4a37a20ed..d773ab4768 100644
--- a/superset/assets/javascripts/explore/stores/controls.jsx
+++ b/superset/assets/javascripts/explore/stores/controls.jsx
@@ -699,21 +699,21 @@ export const controls = {
     freeForm: true,
     label: t('Time Granularity'),
     default: 'one day',
-    choices: formatSelectOptions([
-      'all',
-      '5 seconds',
-      '30 seconds',
-      '1 minute',
-      '5 minutes',
-      '1 hour',
-      '6 hour',
-      '1 day',
-      '7 days',
-      'week',
-      'week_starting_sunday',
-      'week_ending_saturday',
-      'month',
-    ]),
+    choices: [
+      [null, 'all'],
+      ['PT5S', '5 seconds'],
+      ['PT30S', '30 seconds'],
+      ['PT1M', '1 minute'],
+      ['PT5M', '5 minutes'],
+      ['PT1H', '1 hour'],
+      ['PT6H', '6 hour'],
+      ['P1D', '1 day'],
+      ['P7D', '7 days'],
+      ['P1W', 'week'],
+      ['P1W', 'week_starting_sunday'],
+      ['P1W', 'week_ending_saturday'],
+      ['P1M', 'month'],
+    ],
     description: t('The time granularity for the visualization. Note that you 
' +
     'can type and use simple natural language as in `10 seconds`, ' +
     '`1 day` or `56 weeks`'),
diff --git a/superset/assets/package.json b/superset/assets/package.json
index 6b271b4f3a..ba4c1959bf 100644
--- a/superset/assets/package.json
+++ b/superset/assets/package.json
@@ -79,6 +79,7 @@
     "object.entries": "^1.0.4",
     "object.keys": "^0.1.0",
     "object.values": "^1.0.4",
+    "parse-iso-duration": "^1.0.0",
     "po2json": "^0.4.5",
     "prop-types": "^15.6.0",
     "react": "^15.6.2",
diff --git a/superset/assets/visualizations/deckgl/layers/scatter.jsx 
b/superset/assets/visualizations/deckgl/layers/scatter.jsx
index 3d8e99cb76..052a7ab7c1 100644
--- a/superset/assets/visualizations/deckgl/layers/scatter.jsx
+++ b/superset/assets/visualizations/deckgl/layers/scatter.jsx
@@ -4,6 +4,7 @@ import React from 'react';
 import ReactDOM from 'react-dom';
 import PropTypes from 'prop-types';
 
+import parseIsoDuration from 'parse-iso-duration';
 import { ScatterplotLayer } from 'deck.gl';
 
 import AnimatableDeckGLContainer from '../AnimatableDeckGLContainer';
@@ -14,27 +15,6 @@ import { getColorFromScheme, hexToRGB } from 
'../../../javascripts/modules/color
 import { unitToRadius } from '../../../javascripts/modules/geo';
 import sandboxedEval from '../../../javascripts/modules/sandbox';
 
-function getStep(timeGrain) {
-  // grain in milliseconds
-  const MINUTE = 60 * 1000;
-  const HOUR = 60 * MINUTE;
-  const DAY = 24 * HOUR;
-  const WEEK = 7 * DAY;
-  const MONTH = 30 * DAY;
-  const YEAR = 365 * DAY;
-
-  const milliseconds = {
-    'Time Column': MINUTE,
-    min: MINUTE,
-    hour: HOUR,
-    day: DAY,
-    week: WEEK,
-    month: MONTH,
-    year: YEAR,
-  };
-
-  return milliseconds[timeGrain];
-}
 
 function getPoints(data) {
   return data.map(d => d.position);
@@ -117,7 +97,7 @@ class DeckGLScatter extends React.PureComponent {
   /* eslint-disable no-unused-vars */
   static getDerivedStateFromProps(nextProps, prevState) {
     const fd = nextProps.slice.formData;
-    const timeGrain = fd.time_grain_sqla || fd.granularity || 'min';
+    const timeGrain = fd.time_grain_sqla || fd.granularity || 'PT1M';
 
     // find start and end based on the data
     const timestamps = nextProps.payload.data.features.map(f => f.__timestamp);
@@ -125,7 +105,7 @@ class DeckGLScatter extends React.PureComponent {
     let end = Math.max(...timestamps);
 
     // lock start and end to the closest steps
-    const step = getStep(timeGrain);
+    const step = parseIsoDuration(timeGrain);
     start -= start % step;
     end += step - end % step;
 
diff --git a/superset/assets/yarn.lock b/superset/assets/yarn.lock
index 935cf62f64..ded00d8f2d 100644
--- a/superset/assets/yarn.lock
+++ b/superset/assets/yarn.lock
@@ -6567,6 +6567,10 @@ parse-glob@^3.0.4:
     is-extglob "^1.0.0"
     is-glob "^2.0.0"
 
+parse-iso-duration@^1.0.0:
+  version "1.0.0"
+  resolved 
"https://registry.yarnpkg.com/parse-iso-duration/-/parse-iso-duration-1.0.0.tgz#b923ab898a8ff8f42bdc9ee5db6e22808c48a864";
+
 parse-json@^2.1.0, parse-json@^2.2.0:
   version "2.2.0"
   resolved 
"https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9";
diff --git a/superset/connectors/sqla/models.py 
b/superset/connectors/sqla/models.py
index c8ee40269c..7e9a94cfd0 100644
--- a/superset/connectors/sqla/models.py
+++ b/superset/connectors/sqla/models.py
@@ -376,7 +376,7 @@ def data(self):
         if self.type == 'table':
             grains = self.database.grains() or []
             if grains:
-                grains = [(g.name, g.name) for g in grains]
+                grains = [(g.duration, g.name) for g in grains]
             d['granularity_sqla'] = utils.choicify(self.dttm_cols)
             d['time_grain_sqla'] = grains
         return d
diff --git a/superset/db_engine_specs.py b/superset/db_engine_specs.py
index c9006bc280..85ff9dbb80 100644
--- a/superset/db_engine_specs.py
+++ b/superset/db_engine_specs.py
@@ -47,7 +47,7 @@
 tracking_url_trans = conf.get('TRACKING_URL_TRANSFORMER')
 hive_poll_interval = conf.get('HIVE_POLL_INTERVAL')
 
-Grain = namedtuple('Grain', 'name label function')
+Grain = namedtuple('Grain', 'name label function duration')
 
 
 class LimitMethod(object):
@@ -287,23 +287,23 @@ class PostgresBaseEngineSpec(BaseEngineSpec):
     engine = ''
 
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
+        Grain('Time Column', _('Time Column'), '{col}', None),
         Grain('second', _('second'),
-              "DATE_TRUNC('second', {col}) AT TIME ZONE 'UTC'"),
+              "DATE_TRUNC('second', {col}) AT TIME ZONE 'UTC'", 'PT1S'),
         Grain('minute', _('minute'),
-              "DATE_TRUNC('minute', {col}) AT TIME ZONE 'UTC'"),
+              "DATE_TRUNC('minute', {col}) AT TIME ZONE 'UTC'", 'PT1M'),
         Grain('hour', _('hour'),
-              "DATE_TRUNC('hour', {col}) AT TIME ZONE 'UTC'"),
+              "DATE_TRUNC('hour', {col}) AT TIME ZONE 'UTC'", 'PT1H'),
         Grain('day', _('day'),
-              "DATE_TRUNC('day', {col}) AT TIME ZONE 'UTC'"),
+              "DATE_TRUNC('day', {col}) AT TIME ZONE 'UTC'", 'P1D'),
         Grain('week', _('week'),
-              "DATE_TRUNC('week', {col}) AT TIME ZONE 'UTC'"),
+              "DATE_TRUNC('week', {col}) AT TIME ZONE 'UTC'", 'P1W'),
         Grain('month', _('month'),
-              "DATE_TRUNC('month', {col}) AT TIME ZONE 'UTC'"),
+              "DATE_TRUNC('month', {col}) AT TIME ZONE 'UTC'", 'P1M'),
         Grain('quarter', _('quarter'),
-              "DATE_TRUNC('quarter', {col}) AT TIME ZONE 'UTC'"),
+              "DATE_TRUNC('quarter', {col}) AT TIME ZONE 'UTC'", 'P0.25Y'),
         Grain('year', _('year'),
-              "DATE_TRUNC('year', {col}) AT TIME ZONE 'UTC'"),
+              "DATE_TRUNC('year', {col}) AT TIME ZONE 'UTC'", 'P1Y'),
     )
 
     @classmethod
@@ -346,14 +346,14 @@ class OracleEngineSpec(PostgresBaseEngineSpec):
     engine = 'oracle'
 
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
-        Grain('minute', _('minute'), "TRUNC(TO_DATE({col}), 'MI')"),
-        Grain('hour', _('hour'), "TRUNC(TO_DATE({col}), 'HH')"),
-        Grain('day', _('day'), "TRUNC(TO_DATE({col}), 'DDD')"),
-        Grain('week', _('week'), "TRUNC(TO_DATE({col}), 'WW')"),
-        Grain('month', _('month'), "TRUNC(TO_DATE({col}), 'MONTH')"),
-        Grain('quarter', _('quarter'), "TRUNC(TO_DATE({col}), 'Q')"),
-        Grain('year', _('year'), "TRUNC(TO_DATE({col}), 'YEAR')"),
+        Grain('Time Column', _('Time Column'), '{col}', None),
+        Grain('minute', _('minute'), "TRUNC(TO_DATE({col}), 'MI')", 'PT1M'),
+        Grain('hour', _('hour'), "TRUNC(TO_DATE({col}), 'HH')", 'PT1H'),
+        Grain('day', _('day'), "TRUNC(TO_DATE({col}), 'DDD')", 'P1D'),
+        Grain('week', _('week'), "TRUNC(TO_DATE({col}), 'WW')", 'P1W'),
+        Grain('month', _('month'), "TRUNC(TO_DATE({col}), 'MONTH')", 'P1M'),
+        Grain('quarter', _('quarter'), "TRUNC(TO_DATE({col}), 'Q')", 'P0.25Y'),
+        Grain('year', _('year'), "TRUNC(TO_DATE({col}), 'YEAR')", 'P1Y'),
     )
 
     @classmethod
@@ -366,36 +366,44 @@ def convert_dttm(cls, target_type, dttm):
 class Db2EngineSpec(BaseEngineSpec):
     engine = 'ibm_db_sa'
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
+        Grain('Time Column', _('Time Column'), '{col}', None),
         Grain('second', _('second'),
               'CAST({col} as TIMESTAMP)'
-              ' - MICROSECOND({col}) MICROSECONDS'),
+              ' - MICROSECOND({col}) MICROSECONDS',
+              'PT1S'),
         Grain('minute', _('minute'),
               'CAST({col} as TIMESTAMP)'
               ' - SECOND({col}) SECONDS'
-              ' - MICROSECOND({col}) MICROSECONDS'),
+              ' - MICROSECOND({col}) MICROSECONDS',
+              'PT1M'),
         Grain('hour', _('hour'),
               'CAST({col} as TIMESTAMP)'
               ' - MINUTE({col}) MINUTES'
               ' - SECOND({col}) SECONDS'
-              ' - MICROSECOND({col}) MICROSECONDS '),
+              ' - MICROSECOND({col}) MICROSECONDS ',
+              'PT1H'),
         Grain('day', _('day'),
               'CAST({col} as TIMESTAMP)'
               ' - HOUR({col}) HOURS'
               ' - MINUTE({col}) MINUTES'
               ' - SECOND({col}) SECONDS'
-              ' - MICROSECOND({col}) MICROSECONDS '),
+              ' - MICROSECOND({col}) MICROSECONDS ',
+              'P1D'),
         Grain('week', _('week'),
-              '{col} - (DAYOFWEEK({col})) DAYS'),
+              '{col} - (DAYOFWEEK({col})) DAYS',
+              'P1W'),
         Grain('month', _('month'),
-              '{col} - (DAY({col})-1) DAYS'),
+              '{col} - (DAY({col})-1) DAYS',
+              'P1M'),
         Grain('quarter', _('quarter'),
               '{col} - (DAY({col})-1) DAYS'
               ' - (MONTH({col})-1) MONTHS'
-              ' + ((QUARTER({col})-1) * 3) MONTHS'),
+              ' + ((QUARTER({col})-1) * 3) MONTHS',
+              'P0.25Y'),
         Grain('year', _('year'),
               '{col} - (DAY({col})-1) DAYS'
-              ' - (MONTH({col})-1) MONTHS'),
+              ' - (MONTH({col})-1) MONTHS',
+              'P1Y'),
     )
 
     @classmethod
@@ -410,14 +418,17 @@ def convert_dttm(cls, target_type, dttm):
 class SqliteEngineSpec(BaseEngineSpec):
     engine = 'sqlite'
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
+        Grain('Time Column', _('Time Column'), '{col}', None),
         Grain('hour', _('hour'),
-              "DATETIME(STRFTIME('%Y-%m-%dT%H:00:00', {col}))"),
-        Grain('day', _('day'), 'DATE({col})'),
+              "DATETIME(STRFTIME('%Y-%m-%dT%H:00:00', {col}))",
+              'PT1H'),
+        Grain('day', _('day'), 'DATE({col})', 'P1D'),
         Grain('week', _('week'),
-              "DATE({col}, -strftime('%w', {col}) || ' days')"),
+              "DATE({col}, -strftime('%w', {col}) || ' days')",
+              'P1W'),
         Grain('month', _('month'),
-              "DATE({col}, -strftime('%d', {col}) || ' days', '+1 day')"),
+              "DATE({col}, -strftime('%d', {col}) || ' days', '+1 day')",
+              'P1M'),
     )
 
     @classmethod
@@ -460,26 +471,34 @@ class MySQLEngineSpec(BaseEngineSpec):
     engine = 'mysql'
     cursor_execute_kwargs = {'args': {}}
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
+        Grain('Time Column', _('Time Column'), '{col}', None),
         Grain('second', _('second'), 'DATE_ADD(DATE({col}), '
               'INTERVAL (HOUR({col})*60*60 + MINUTE({col})*60'
-              ' + SECOND({col})) SECOND)'),
+              ' + SECOND({col})) SECOND)',
+              'PT1S'),
         Grain('minute', _('minute'), 'DATE_ADD(DATE({col}), '
-              'INTERVAL (HOUR({col})*60 + MINUTE({col})) MINUTE)'),
+              'INTERVAL (HOUR({col})*60 + MINUTE({col})) MINUTE)',
+              'PT1M'),
         Grain('hour', _('hour'), 'DATE_ADD(DATE({col}), '
-              'INTERVAL HOUR({col}) HOUR)'),
-        Grain('day', _('day'), 'DATE({col})'),
+              'INTERVAL HOUR({col}) HOUR)',
+              'PT1H'),
+        Grain('day', _('day'), 'DATE({col})', 'P1D'),
         Grain('week', _('week'), 'DATE(DATE_SUB({col}, '
-              'INTERVAL DAYOFWEEK({col}) - 1 DAY))'),
+              'INTERVAL DAYOFWEEK({col}) - 1 DAY))',
+              'P1W'),
         Grain('month', _('month'), 'DATE(DATE_SUB({col}, '
-              'INTERVAL DAYOFMONTH({col}) - 1 DAY))'),
+              'INTERVAL DAYOFMONTH({col}) - 1 DAY))',
+              'P1M'),
         Grain('quarter', _('quarter'), 'MAKEDATE(YEAR({col}), 1) '
-              '+ INTERVAL QUARTER({col}) QUARTER - INTERVAL 1 QUARTER'),
+              '+ INTERVAL QUARTER({col}) QUARTER - INTERVAL 1 QUARTER',
+              'P0.25Y'),
         Grain('year', _('year'), 'DATE(DATE_SUB({col}, '
-              'INTERVAL DAYOFYEAR({col}) - 1 DAY))'),
+              'INTERVAL DAYOFYEAR({col}) - 1 DAY))',
+              'P1Y'),
         Grain('week_start_monday', _('week_start_monday'),
               'DATE(DATE_SUB({col}, '
-              'INTERVAL DAYOFWEEK(DATE_SUB({col}, INTERVAL 1 DAY)) - 1 DAY))'),
+              'INTERVAL DAYOFWEEK(DATE_SUB({col}, INTERVAL 1 DAY)) - 1 DAY))',
+              'P1W'),
     )
 
     @classmethod
@@ -516,27 +535,39 @@ class PrestoEngineSpec(BaseEngineSpec):
     cursor_execute_kwargs = {'parameters': None}
 
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
+        Grain('Time Column', _('Time Column'), '{col}', None),
         Grain('second', _('second'),
-              "date_trunc('second', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('second', CAST({col} AS TIMESTAMP))",
+              'PT1S'),
         Grain('minute', _('minute'),
-              "date_trunc('minute', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('minute', CAST({col} AS TIMESTAMP))",
+              'PT1M'),
         Grain('hour', _('hour'),
-              "date_trunc('hour', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('hour', CAST({col} AS TIMESTAMP))",
+              'PT1H'),
         Grain('day', _('day'),
-              "date_trunc('day', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('day', CAST({col} AS TIMESTAMP))",
+              'P1D'),
         Grain('week', _('week'),
-              "date_trunc('week', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('week', CAST({col} AS TIMESTAMP))",
+              'P1W'),
         Grain('month', _('month'),
-              "date_trunc('month', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('month', CAST({col} AS TIMESTAMP))",
+              'P1M'),
         Grain('quarter', _('quarter'),
-              "date_trunc('quarter', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('quarter', CAST({col} AS TIMESTAMP))",
+              'P0.25Y'),
         Grain('week_ending_saturday', _('week_ending_saturday'),
               "date_add('day', 5, date_trunc('week', date_add('day', 1, "
-              'CAST({col} AS TIMESTAMP))))'),
+              'CAST({col} AS TIMESTAMP))))',
+              'P1W'),
         Grain('week_start_sunday', _('week_start_sunday'),
               "date_add('day', -1, date_trunc('week', "
-              "date_add('day', 1, CAST({col} AS TIMESTAMP))))"),
+              "date_add('day', 1, CAST({col} AS TIMESTAMP))))",
+              'P1W'),
+        Grain('year', _('year'),
+              "date_trunc('year', CAST({col} AS TIMESTAMP))",
+              'P1Y'),
     )
 
     @classmethod
@@ -1054,27 +1085,37 @@ class MssqlEngineSpec(BaseEngineSpec):
     epoch_to_dttm = "dateadd(S, {col}, '1970-01-01')"
 
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
+        Grain('Time Column', _('Time Column'), '{col}', None),
         Grain('second', _('second'), 'DATEADD(second, '
-              "DATEDIFF(second, '2000-01-01', {col}), '2000-01-01')"),
+              "DATEDIFF(second, '2000-01-01', {col}), '2000-01-01')",
+              'PT1S'),
         Grain('minute', _('minute'), 'DATEADD(minute, '
-              'DATEDIFF(minute, 0, {col}), 0)'),
+              'DATEDIFF(minute, 0, {col}), 0)',
+              'PT1M'),
         Grain('5 minute', _('5 minute'), 'DATEADD(minute, '
-              'DATEDIFF(minute, 0, {col}) / 5 * 5, 0)'),
+              'DATEDIFF(minute, 0, {col}) / 5 * 5, 0)',
+              'PT5M'),
         Grain('half hour', _('half hour'), 'DATEADD(minute, '
-              'DATEDIFF(minute, 0, {col}) / 30 * 30, 0)'),
+              'DATEDIFF(minute, 0, {col}) / 30 * 30, 0)',
+              'PT0.5H'),
         Grain('hour', _('hour'), 'DATEADD(hour, '
-              'DATEDIFF(hour, 0, {col}), 0)'),
+              'DATEDIFF(hour, 0, {col}), 0)',
+              'PT1H'),
         Grain('day', _('day'), 'DATEADD(day, '
-              'DATEDIFF(day, 0, {col}), 0)'),
+              'DATEDIFF(day, 0, {col}), 0)',
+              'P1D'),
         Grain('week', _('week'), 'DATEADD(week, '
-              'DATEDIFF(week, 0, {col}), 0)'),
+              'DATEDIFF(week, 0, {col}), 0)',
+              'P1W'),
         Grain('month', _('month'), 'DATEADD(month, '
-              'DATEDIFF(month, 0, {col}), 0)'),
+              'DATEDIFF(month, 0, {col}), 0)',
+              'P1M'),
         Grain('quarter', _('quarter'), 'DATEADD(quarter, '
-              'DATEDIFF(quarter, 0, {col}), 0)'),
+              'DATEDIFF(quarter, 0, {col}), 0)',
+              'P0.25Y'),
         Grain('year', _('year'), 'DATEADD(year, '
-              'DATEDIFF(year, 0, {col}), 0)'),
+              'DATEDIFF(year, 0, {col}), 0)',
+              'P1Y'),
     )
 
     @classmethod
@@ -1086,27 +1127,36 @@ class AthenaEngineSpec(BaseEngineSpec):
     engine = 'awsathena'
 
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
+        Grain('Time Column', _('Time Column'), '{col}', None),
         Grain('second', _('second'),
-              "date_trunc('second', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('second', CAST({col} AS TIMESTAMP))",
+              'PT1S'),
         Grain('minute', _('minute'),
-              "date_trunc('minute', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('minute', CAST({col} AS TIMESTAMP))",
+              'PT1M'),
         Grain('hour', _('hour'),
-              "date_trunc('hour', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('hour', CAST({col} AS TIMESTAMP))",
+              'PT1H'),
         Grain('day', _('day'),
-              "date_trunc('day', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('day', CAST({col} AS TIMESTAMP))",
+              'P1D'),
         Grain('week', _('week'),
-              "date_trunc('week', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('week', CAST({col} AS TIMESTAMP))",
+              'P1W'),
         Grain('month', _('month'),
-              "date_trunc('month', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('month', CAST({col} AS TIMESTAMP))",
+              'P1M'),
         Grain('quarter', _('quarter'),
-              "date_trunc('quarter', CAST({col} AS TIMESTAMP))"),
+              "date_trunc('quarter', CAST({col} AS TIMESTAMP))",
+              'P0.25Y'),
         Grain('week_ending_saturday', _('week_ending_saturday'),
               "date_add('day', 5, date_trunc('week', date_add('day', 1, "
-              'CAST({col} AS TIMESTAMP))))'),
+              'CAST({col} AS TIMESTAMP))))',
+              'P1W'),
         Grain('week_start_sunday', _('week_start_sunday'),
               "date_add('day', -1, date_trunc('week', "
-              "date_add('day', 1, CAST({col} AS TIMESTAMP))))"),
+              "date_add('day', 1, CAST({col} AS TIMESTAMP))))",
+              'P1W'),
     )
 
     @classmethod
@@ -1132,23 +1182,31 @@ class ClickHouseEngineSpec(BaseEngineSpec):
     time_secondary_columns = True
     time_groupby_inline = True
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
+        Grain('Time Column', _('Time Column'), '{col}', None),
         Grain('minute', _('minute'),
-              'toStartOfMinute(toDateTime({col}))'),
+              'toStartOfMinute(toDateTime({col}))',
+              'PT1M'),
         Grain('5 minute', _('5 minute'),
-              'toDateTime(intDiv(toUInt32(toDateTime({col})), 300)*300)'),
+              'toDateTime(intDiv(toUInt32(toDateTime({col})), 300)*300)',
+              'PT5M'),
         Grain('10 minute', _('10 minute'),
-              'toDateTime(intDiv(toUInt32(toDateTime({col})), 600)*600)'),
+              'toDateTime(intDiv(toUInt32(toDateTime({col})), 600)*600)',
+              'PT10M'),
         Grain('hour', _('hour'),
-              'toStartOfHour(toDateTime({col}))'),
+              'toStartOfHour(toDateTime({col}))',
+              'PT1H'),
         Grain('day', _('day'),
-              'toStartOfDay(toDateTime({col}))'),
+              'toStartOfDay(toDateTime({col}))',
+              'P1D'),
         Grain('month', _('month'),
-              'toStartOfMonth(toDateTime({col}))'),
+              'toStartOfMonth(toDateTime({col}))',
+              'P1M'),
         Grain('quarter', _('quarter'),
-              'toStartOfQuarter(toDateTime({col}))'),
+              'toStartOfQuarter(toDateTime({col}))',
+              'P0.25Y'),
         Grain('year', _('year'),
-              'toStartOfYear(toDateTime({col}))'),
+              'toStartOfYear(toDateTime({col}))',
+              'P1Y'),
     )
 
     @classmethod
@@ -1169,15 +1227,16 @@ class BQEngineSpec(BaseEngineSpec):
     engine = 'bigquery'
 
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
-        Grain('second', _('second'), 'TIMESTAMP_TRUNC({col}, SECOND)'),
-        Grain('minute', _('minute'), 'TIMESTAMP_TRUNC({col}, MINUTE)'),
-        Grain('hour', _('hour'), 'TIMESTAMP_TRUNC({col}, HOUR)'),
-        Grain('day', _('day'), 'TIMESTAMP_TRUNC({col}, DAY)'),
-        Grain('week', _('week'), 'TIMESTAMP_TRUNC({col}, WEEK)'),
-        Grain('month', _('month'), 'TIMESTAMP_TRUNC({col}, MONTH)'),
-        Grain('quarter', _('quarter'), 'TIMESTAMP_TRUNC({col}, QUARTER)'),
-        Grain('year', _('year'), 'TIMESTAMP_TRUNC({col}, YEAR)'),
+        Grain('Time Column', _('Time Column'), '{col}', None),
+        Grain('second', _('second'), 'TIMESTAMP_TRUNC({col}, SECOND)', 'PT1S'),
+        Grain('minute', _('minute'), 'TIMESTAMP_TRUNC({col}, MINUTE)', 'PT1M'),
+        Grain('hour', _('hour'), 'TIMESTAMP_TRUNC({col}, HOUR)', 'PT1H'),
+        Grain('day', _('day'), 'TIMESTAMP_TRUNC({col}, DAY)', 'P1D'),
+        Grain('week', _('week'), 'TIMESTAMP_TRUNC({col}, WEEK)', 'P1W'),
+        Grain('month', _('month'), 'TIMESTAMP_TRUNC({col}, MONTH)', 'P1M'),
+        Grain('quarter', _('quarter'),
+              'TIMESTAMP_TRUNC({col}, QUARTER)', 'P0.25Y'),
+        Grain('year', _('year'), 'TIMESTAMP_TRUNC({col}, YEAR)', 'P1Y'),
     )
 
     @classmethod
@@ -1201,14 +1260,14 @@ class ImpalaEngineSpec(BaseEngineSpec):
     engine = 'impala'
 
     time_grains = (
-        Grain('Time Column', _('Time Column'), '{col}'),
-        Grain('minute', _('minute'), "TRUNC({col}, 'MI')"),
-        Grain('hour', _('hour'), "TRUNC({col}, 'HH')"),
-        Grain('day', _('day'), "TRUNC({col}, 'DD')"),
-        Grain('week', _('week'), "TRUNC({col}, 'WW')"),
-        Grain('month', _('month'), "TRUNC({col}, 'MONTH')"),
-        Grain('quarter', _('quarter'), "TRUNC({col}, 'Q')"),
-        Grain('year', _('year'), "TRUNC({col}, 'YYYY')"),
+        Grain('Time Column', _('Time Column'), '{col}', None),
+        Grain('minute', _('minute'), "TRUNC({col}, 'MI')", 'PT1M'),
+        Grain('hour', _('hour'), "TRUNC({col}, 'HH')", 'PT1H'),
+        Grain('day', _('day'), "TRUNC({col}, 'DD')", 'P1D'),
+        Grain('week', _('week'), "TRUNC({col}, 'WW')", 'P1W'),
+        Grain('month', _('month'), "TRUNC({col}, 'MONTH')", 'P1M'),
+        Grain('quarter', _('quarter'), "TRUNC({col}, 'Q')", 'P0.25Y'),
+        Grain('year', _('year'), "TRUNC({col}, 'YYYY')", 'P1Y'),
     )
 
     @classmethod
diff --git a/superset/models/core.py b/superset/models/core.py
index 6eef48c688..5ff737e83b 100644
--- a/superset/models/core.py
+++ b/superset/models/core.py
@@ -786,7 +786,7 @@ def grains(self):
         return self.db_engine_spec.time_grains
 
     def grains_dict(self):
-        return {grain.name: grain for grain in self.grains()}
+        return {grain.duration: grain for grain in self.grains()}
 
     def get_extra(self):
         extra = {}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to