diff --git a/packages/cubejs-api-gateway/index.js b/packages/cubejs-api-gateway/index.js index d670a626b0d50..b3163fa88f865 100644 --- a/packages/cubejs-api-gateway/index.js +++ b/packages/cubejs-api-gateway/index.js @@ -22,7 +22,8 @@ const prepareAnnotation = (metaConfig, query) => { const annotation = (memberType) => (member) => { const path = member.split('.'); - const config = configMap[path[0]][memberType].find(m => m.name === member); + const memberWithoutGranularity = [path[0], path[1]].join('.'); + const config = configMap[path[0]][memberType].find(m => m.name === memberWithoutGranularity); if (!config) { return undefined; } @@ -39,7 +40,10 @@ const prepareAnnotation = (metaConfig, query) => { measures: R.fromPairs((query.measures || []).map(annotation('measures')).filter(a => !!a)), dimensions: R.fromPairs((query.dimensions || []).map(annotation('dimensions')).filter(a => !!a)), segments: R.fromPairs((query.segments || []).map(annotation('segments')).filter(a => !!a)), - timeDimensions: R.fromPairs((query.timeDimensions || []).map(td => annotation('dimensions')(td.dimension)).filter(a => !!a)), // TODO + timeDimensions: R.fromPairs((query.timeDimensions || []) + .filter(td => !!td.granularity) + .map(td => annotation('dimensions')(`${td.dimension}.${td.granularity}`)) + .filter(a => !!a)), }; }; @@ -59,11 +63,28 @@ const transformData = (aliasToMemberNameMap, annotation, data) => (data.map(r => if (!annotationForMember) { throw new UserError(`You requested hidden member: '${p[0]}'. Please make it visible using \`shown: true\``); } - return [ + const transformResult = [ memberName, transformValue(p[1], annotationForMember.type) ]; + + const path = memberName.split('.'); + + // TODO: deprecated: backward compatibility for referencing time dimensions without granularity + const memberNameWithoutGranularity = [path[0], path[1]].join('.'); + if (path.length === 3 && !annotation[memberNameWithoutGranularity]) { + return [ + transformResult, + [ + memberNameWithoutGranularity, + transformResult[1] + ] + ]; + } + + return [transformResult]; }), + R.unnest, R.fromPairs )(r))); diff --git a/packages/cubejs-client-core/dist/cubejs-client-core.esm.js b/packages/cubejs-client-core/dist/cubejs-client-core.esm.js index 371585a624901..7295a902fafb9 100644 --- a/packages/cubejs-client-core/dist/cubejs-client-core.esm.js +++ b/packages/cubejs-client-core/dist/cubejs-client-core.esm.js @@ -185,20 +185,34 @@ function () { var timeDimensions = (query.timeDimensions || []).filter(function (td) { return !!td.granularity; }); + var dimensions = query.dimensions || []; pivotConfig = pivotConfig || (timeDimensions.length ? { x: timeDimensions.map(function (td) { - return td.dimension; + return ResultSet.timeDimensionMember(td); }), - y: query.dimensions || [] + y: dimensions } : { - x: query.dimensions || [], + x: dimensions, y: [] }); - pivotConfig.x = pivotConfig.x || []; - pivotConfig.y = pivotConfig.y || []; + + var substituteTimeDimensionMembers = function substituteTimeDimensionMembers(axis) { + return axis.map(function (subDim) { + return timeDimensions.find(function (td) { + return td.dimension === subDim; + }) && !dimensions.find(function (d) { + return d === subDim; + }) ? ResultSet.timeDimensionMember(query.timeDimensions.find(function (td) { + return td.dimension === subDim; + })) : subDim; + }); + }; + + pivotConfig.x = substituteTimeDimensionMembers(pivotConfig.x || []); + pivotConfig.y = substituteTimeDimensionMembers(pivotConfig.y || []); var allIncludedDimensions = pivotConfig.x.concat(pivotConfig.y); var allDimensions = timeDimensions.map(function (td) { - return td.dimension; + return ResultSet.timeDimensionMember(td); }).concat(query.dimensions); pivotConfig.x = pivotConfig.x.concat(allDimensions.filter(function (d) { return allIncludedDimensions.indexOf(d) === -1; @@ -236,7 +250,7 @@ function () { if (!dateRange) { var dates = pipe(map(function (row) { - return row[timeDimension.dimension] && moment(row[timeDimension.dimension]); + return row[ResultSet.timeDimensionMember(timeDimension)] && moment(row[ResultSet.timeDimensionMember(timeDimension)]); }), filter(function (r) { return !!r; }))(this.loadResponse.data); @@ -280,7 +294,7 @@ function () { if (pivotConfig.fillMissingDates && pivotConfig.x.length === 1 && equals(pivotConfig.x, (this.loadResponse.query.timeDimensions || []).filter(function (td) { return !!td.granularity; }).map(function (td) { - return td.dimension; + return ResultSet.timeDimensionMember(td); }))) { var series = this.timeSeries(this.loadResponse.query.timeDimensions[0]); @@ -450,7 +464,7 @@ function () { }, { key: "tablePivot", value: function tablePivot(pivotConfig) { - var normalizedPivotConfig = this.normalizePivotConfig(pivotConfig); + var normalizedPivotConfig = this.normalizePivotConfig(pivotConfig || {}); var valueToObject = function valueToObject(valuesArray, measureValue) { return function (field, index) { @@ -584,6 +598,11 @@ function () { return this.loadResponse.data; } }], [{ + key: "timeDimensionMember", + value: function timeDimensionMember(td) { + return "".concat(td.dimension, ".").concat(td.granularity); + } + }, { key: "measureFromAxis", value: function measureFromAxis(axisValues) { return axisValues[axisValues.length - 1]; diff --git a/packages/cubejs-client-core/dist/cubejs-client-core.js b/packages/cubejs-client-core/dist/cubejs-client-core.js index 4027f5bb5b30a..707d25cbbe790 100644 --- a/packages/cubejs-client-core/dist/cubejs-client-core.js +++ b/packages/cubejs-client-core/dist/cubejs-client-core.js @@ -191,20 +191,34 @@ function () { var timeDimensions = (query.timeDimensions || []).filter(function (td) { return !!td.granularity; }); + var dimensions = query.dimensions || []; pivotConfig = pivotConfig || (timeDimensions.length ? { x: timeDimensions.map(function (td) { - return td.dimension; + return ResultSet.timeDimensionMember(td); }), - y: query.dimensions || [] + y: dimensions } : { - x: query.dimensions || [], + x: dimensions, y: [] }); - pivotConfig.x = pivotConfig.x || []; - pivotConfig.y = pivotConfig.y || []; + + var substituteTimeDimensionMembers = function substituteTimeDimensionMembers(axis) { + return axis.map(function (subDim) { + return timeDimensions.find(function (td) { + return td.dimension === subDim; + }) && !dimensions.find(function (d) { + return d === subDim; + }) ? ResultSet.timeDimensionMember(query.timeDimensions.find(function (td) { + return td.dimension === subDim; + })) : subDim; + }); + }; + + pivotConfig.x = substituteTimeDimensionMembers(pivotConfig.x || []); + pivotConfig.y = substituteTimeDimensionMembers(pivotConfig.y || []); var allIncludedDimensions = pivotConfig.x.concat(pivotConfig.y); var allDimensions = timeDimensions.map(function (td) { - return td.dimension; + return ResultSet.timeDimensionMember(td); }).concat(query.dimensions); pivotConfig.x = pivotConfig.x.concat(allDimensions.filter(function (d) { return allIncludedDimensions.indexOf(d) === -1; @@ -242,7 +256,7 @@ function () { if (!dateRange) { var dates = ramda.pipe(ramda.map(function (row) { - return row[timeDimension.dimension] && moment(row[timeDimension.dimension]); + return row[ResultSet.timeDimensionMember(timeDimension)] && moment(row[ResultSet.timeDimensionMember(timeDimension)]); }), ramda.filter(function (r) { return !!r; }))(this.loadResponse.data); @@ -286,7 +300,7 @@ function () { if (pivotConfig.fillMissingDates && pivotConfig.x.length === 1 && ramda.equals(pivotConfig.x, (this.loadResponse.query.timeDimensions || []).filter(function (td) { return !!td.granularity; }).map(function (td) { - return td.dimension; + return ResultSet.timeDimensionMember(td); }))) { var series = this.timeSeries(this.loadResponse.query.timeDimensions[0]); @@ -456,7 +470,7 @@ function () { }, { key: "tablePivot", value: function tablePivot(pivotConfig) { - var normalizedPivotConfig = this.normalizePivotConfig(pivotConfig); + var normalizedPivotConfig = this.normalizePivotConfig(pivotConfig || {}); var valueToObject = function valueToObject(valuesArray, measureValue) { return function (field, index) { @@ -590,6 +604,11 @@ function () { return this.loadResponse.data; } }], [{ + key: "timeDimensionMember", + value: function timeDimensionMember(td) { + return "".concat(td.dimension, ".").concat(td.granularity); + } + }, { key: "measureFromAxis", value: function measureFromAxis(axisValues) { return axisValues[axisValues.length - 1]; diff --git a/packages/cubejs-client-core/dist/cubejs-client-core.umd.js b/packages/cubejs-client-core/dist/cubejs-client-core.umd.js index 1d4d1dabbb0ed..345f6b99f7b44 100644 --- a/packages/cubejs-client-core/dist/cubejs-client-core.umd.js +++ b/packages/cubejs-client-core/dist/cubejs-client-core.umd.js @@ -675,7 +675,7 @@ // Set @@toStringTag to native iterators _setToStringTag(IteratorPrototype, TAG, true); // fix for some old engines - if (typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis); + if (!_library && typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis); } } // fix Array#{values, @@iterator}.name in V8 / FF @@ -684,7 +684,7 @@ $default = function values() { return $native.call(this); }; } // Define iterator - if (BUGGY || VALUES_BUG || !proto[ITERATOR]) { + if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { _hide(proto, ITERATOR, $default); } // Plug for library @@ -12746,20 +12746,34 @@ var timeDimensions = (query.timeDimensions || []).filter(function (td) { return !!td.granularity; }); + var dimensions = query.dimensions || []; pivotConfig = pivotConfig || (timeDimensions.length ? { x: timeDimensions.map(function (td) { - return td.dimension; + return ResultSet.timeDimensionMember(td); }), - y: query.dimensions || [] + y: dimensions } : { - x: query.dimensions || [], + x: dimensions, y: [] }); - pivotConfig.x = pivotConfig.x || []; - pivotConfig.y = pivotConfig.y || []; + + var substituteTimeDimensionMembers = function substituteTimeDimensionMembers(axis) { + return axis.map(function (subDim) { + return timeDimensions.find(function (td) { + return td.dimension === subDim; + }) && !dimensions.find(function (d) { + return d === subDim; + }) ? ResultSet.timeDimensionMember(query.timeDimensions.find(function (td) { + return td.dimension === subDim; + })) : subDim; + }); + }; + + pivotConfig.x = substituteTimeDimensionMembers(pivotConfig.x || []); + pivotConfig.y = substituteTimeDimensionMembers(pivotConfig.y || []); var allIncludedDimensions = pivotConfig.x.concat(pivotConfig.y); var allDimensions = timeDimensions.map(function (td) { - return td.dimension; + return ResultSet.timeDimensionMember(td); }).concat(query.dimensions); pivotConfig.x = pivotConfig.x.concat(allDimensions.filter(function (d) { return allIncludedDimensions.indexOf(d) === -1; @@ -12797,7 +12811,7 @@ if (!dateRange) { var dates = pipe(map(function (row) { - return row[timeDimension.dimension] && moment$1(row[timeDimension.dimension]); + return row[ResultSet.timeDimensionMember(timeDimension)] && moment$1(row[ResultSet.timeDimensionMember(timeDimension)]); }), filter(function (r) { return !!r; }))(this.loadResponse.data); @@ -12841,7 +12855,7 @@ if (pivotConfig.fillMissingDates && pivotConfig.x.length === 1 && equals(pivotConfig.x, (this.loadResponse.query.timeDimensions || []).filter(function (td) { return !!td.granularity; }).map(function (td) { - return td.dimension; + return ResultSet.timeDimensionMember(td); }))) { var series = this.timeSeries(this.loadResponse.query.timeDimensions[0]); @@ -13011,7 +13025,7 @@ }, { key: "tablePivot", value: function tablePivot(pivotConfig) { - var normalizedPivotConfig = this.normalizePivotConfig(pivotConfig); + var normalizedPivotConfig = this.normalizePivotConfig(pivotConfig || {}); var valueToObject = function valueToObject(valuesArray, measureValue) { return function (field, index) { @@ -13145,6 +13159,11 @@ return this.loadResponse.data; } }], [{ + key: "timeDimensionMember", + value: function timeDimensionMember(td) { + return "".concat(td.dimension, ".").concat(td.granularity); + } + }, { key: "measureFromAxis", value: function measureFromAxis(axisValues) { return axisValues[axisValues.length - 1]; diff --git a/packages/cubejs-client-core/src/ResultSet.js b/packages/cubejs-client-core/src/ResultSet.js index 2754489e990e3..af21380e6272e 100644 --- a/packages/cubejs-client-core/src/ResultSet.js +++ b/packages/cubejs-client-core/src/ResultSet.js @@ -99,20 +99,36 @@ class ResultSet { return axisValues.map(formatValue).join(delimiter || ', '); } + static timeDimensionMember(td) { + return `${td.dimension}.${td.granularity}`; + } + normalizePivotConfig(pivotConfig) { const { query } = this.loadResponse; const timeDimensions = (query.timeDimensions || []).filter(td => !!td.granularity); + const dimensions = query.dimensions || []; pivotConfig = pivotConfig || (timeDimensions.length ? { - x: timeDimensions.map(td => td.dimension), - y: query.dimensions || [] + x: timeDimensions.map(td => ResultSet.timeDimensionMember(td)), + y: dimensions } : { - x: query.dimensions || [], + x: dimensions, y: [] }); - pivotConfig.x = pivotConfig.x || []; - pivotConfig.y = pivotConfig.y || []; + + const substituteTimeDimensionMembers = axis => axis.map( + subDim => ( + timeDimensions.find(td => td.dimension === subDim) && + !dimensions.find(d => d === subDim) ? + ResultSet.timeDimensionMember(query.timeDimensions.find(td => td.dimension === subDim)) : + subDim + ) + ); + + pivotConfig.x = substituteTimeDimensionMembers(pivotConfig.x || []); + pivotConfig.y = substituteTimeDimensionMembers(pivotConfig.y || []); + const allIncludedDimensions = pivotConfig.x.concat(pivotConfig.y); - const allDimensions = timeDimensions.map(td => td.dimension).concat(query.dimensions); + const allDimensions = timeDimensions.map(td => ResultSet.timeDimensionMember(td)).concat(query.dimensions); pivotConfig.x = pivotConfig.x.concat(allDimensions.filter(d => allIncludedDimensions.indexOf(d) === -1)); if (!pivotConfig.x.concat(pivotConfig.y).find(d => d === 'measures')) { pivotConfig.y = pivotConfig.y.concat(['measures']); @@ -138,7 +154,10 @@ class ResultSet { let { dateRange } = timeDimension; if (!dateRange) { const dates = pipe( - map(row => row[timeDimension.dimension] && moment(row[timeDimension.dimension])), + map( + row => row[ResultSet.timeDimensionMember(timeDimension)] && + moment(row[ResultSet.timeDimensionMember(timeDimension)]) + ), filter(r => !!r) )(this.loadResponse.data); @@ -172,7 +191,9 @@ class ResultSet { pivotConfig.x.length === 1 && equals( pivotConfig.x, - (this.loadResponse.query.timeDimensions || []).filter(td => !!td.granularity).map(td => td.dimension) + (this.loadResponse.query.timeDimensions || []) + .filter(td => !!td.granularity) + .map(td => ResultSet.timeDimensionMember(td)) ) ) { const series = this.timeSeries(this.loadResponse.query.timeDimensions[0]); @@ -299,7 +320,7 @@ class ResultSet { * @returns {Array} of pivoted rows */ tablePivot(pivotConfig) { - const normalizedPivotConfig = this.normalizePivotConfig(pivotConfig); + const normalizedPivotConfig = this.normalizePivotConfig(pivotConfig || {}); const valueToObject = (valuesArray, measureValue) => ( (field, index) => ({ diff --git a/packages/cubejs-client-core/src/ResultSet.test.js b/packages/cubejs-client-core/src/ResultSet.test.js index dd2dd45422b2c..f2f3a0a56db80 100644 --- a/packages/cubejs-client-core/src/ResultSet.test.js +++ b/packages/cubejs-client-core/src/ResultSet.test.js @@ -1,3 +1,4 @@ +/* eslint-disable quote-props */ /* globals jest,describe,test,expect */ import ResultSet from './ResultSet'; @@ -86,10 +87,436 @@ describe('ResultSet', () => { }); expect(resultSet.normalizePivotConfig({ y: ['Foo.bar'] })).toEqual({ - x: ['Foo.createdAt'], + x: ['Foo.createdAt.day'], y: ['Foo.bar'], fillMissingDates: true }); }); + + test('time dimensions with granularity passed without', () => { + const resultSet = new ResultSet({ + query: { + dimensions: ['Foo.bar'], + timeDimensions: [{ + granularity: 'day', + dimension: 'Foo.createdAt' + }] + } + }); + + expect(resultSet.normalizePivotConfig({ x: ['Foo.createdAt'], y: ['Foo.bar'] })).toEqual({ + x: ['Foo.createdAt.day'], + y: ['Foo.bar'], + fillMissingDates: true + }); + }); + + test('double time dimensions without granularity', () => { + const resultSet = new ResultSet({ + "query": { + "measures": [], + "timeDimensions": [{ + "dimension": "Orders.createdAt", + "dateRange": ["2020-01-08T00:00:00.000", "2020-01-14T23:59:59.999"] + }], + "dimensions": ["Orders.createdAt"], + "filters": [], + "timezone": "UTC" + }, + }); + + expect(resultSet.normalizePivotConfig(resultSet.normalizePivotConfig({}))).toEqual({ + x: ['Orders.createdAt'], + y: [], + fillMissingDates: true + }); + }); + + test('double time dimensions with granularity', () => { + const resultSet = new ResultSet({ + "query": { + "measures": [], + "timeDimensions": [{ + "dimension": "Orders.createdAt", + "granularity": "day", + "dateRange": ["2020-01-08T00:00:00.000", "2020-01-14T23:59:59.999"] + }], + "dimensions": ["Orders.createdAt"], + "filters": [], + "timezone": "UTC" + }, + }); + + expect(resultSet.normalizePivotConfig(resultSet.normalizePivotConfig({}))).toEqual({ + x: ['Orders.createdAt.day', "Orders.createdAt"], + y: [], + fillMissingDates: true + }); + }); + }); + + describe('pivot', () => { + test('same dimension and time dimension', () => { + const resultSet = new ResultSet({ + "query": { + "measures": [], + "timeDimensions": [{ + "dimension": "Orders.createdAt", + "granularity": "day", + "dateRange": ["2020-01-08T00:00:00.000", "2020-01-14T23:59:59.999"] + }], + "dimensions": ["Orders.createdAt"], + "filters": [], + "timezone": "UTC" + }, + "data": [{ + "Orders.createdAt": "2020-01-08T17:04:43.000", + "Orders.createdAt.day": "2020-01-08T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-08T19:28:26.000", + "Orders.createdAt.day": "2020-01-08T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T00:13:01.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T00:25:32.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T00:43:11.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T03:04:00.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T04:30:10.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T10:25:04.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T19:47:19.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T19:48:04.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T21:46:24.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-09T23:49:37.000", + "Orders.createdAt.day": "2020-01-09T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-10T09:07:20.000", + "Orders.createdAt.day": "2020-01-10T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-10T13:50:05.000", + "Orders.createdAt.day": "2020-01-10T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-10T15:30:32.000", + "Orders.createdAt.day": "2020-01-10T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-10T15:32:52.000", + "Orders.createdAt.day": "2020-01-10T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-10T18:55:23.000", + "Orders.createdAt.day": "2020-01-10T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-11T01:13:17.000", + "Orders.createdAt.day": "2020-01-11T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-11T09:17:40.000", + "Orders.createdAt.day": "2020-01-11T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-11T13:23:03.000", + "Orders.createdAt.day": "2020-01-11T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-11T17:28:42.000", + "Orders.createdAt.day": "2020-01-11T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-11T22:34:32.000", + "Orders.createdAt.day": "2020-01-11T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-11T23:03:58.000", + "Orders.createdAt.day": "2020-01-11T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-12T03:46:25.000", + "Orders.createdAt.day": "2020-01-12T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-12T09:57:10.000", + "Orders.createdAt.day": "2020-01-12T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-12T12:28:22.000", + "Orders.createdAt.day": "2020-01-12T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-12T14:34:20.000", + "Orders.createdAt.day": "2020-01-12T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-12T18:45:15.000", + "Orders.createdAt.day": "2020-01-12T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-12T19:38:05.000", + "Orders.createdAt.day": "2020-01-12T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-12T21:43:51.000", + "Orders.createdAt.day": "2020-01-12T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-13T01:42:49.000", + "Orders.createdAt.day": "2020-01-13T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-13T03:19:22.000", + "Orders.createdAt.day": "2020-01-13T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-13T05:20:50.000", + "Orders.createdAt.day": "2020-01-13T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-13T05:46:35.000", + "Orders.createdAt.day": "2020-01-13T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-13T11:24:01.000", + "Orders.createdAt.day": "2020-01-13T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-13T12:13:42.000", + "Orders.createdAt.day": "2020-01-13T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-13T20:21:59.000", + "Orders.createdAt.day": "2020-01-13T00:00:00.000" + }, { + "Orders.createdAt": "2020-01-14T20:16:23.000", + "Orders.createdAt.day": "2020-01-14T00:00:00.000" + }], + "annotation": { + "measures": {}, + "dimensions": { + "Orders.createdAt": { + "title": "Orders Created at", + "shortTitle": "Created at", + "type": "time" + } + }, + "segments": {}, + "timeDimensions": { + "Orders.createdAt.day": { + "title": "Orders Created at", + "shortTitle": "Created at", + "type": "time" + } + } + } + }); + + expect(resultSet.tablePivot()).toEqual([ + { + "Orders.createdAt.day": "2020-01-08T00:00:00.000", + "Orders.createdAt": "2020-01-08T17:04:43.000" + }, + { + "Orders.createdAt.day": "2020-01-08T00:00:00.000", + "Orders.createdAt": "2020-01-08T19:28:26.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T00:13:01.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T00:25:32.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T00:43:11.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T03:04:00.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T04:30:10.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T10:25:04.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T19:47:19.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T19:48:04.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T21:46:24.000" + }, + { + "Orders.createdAt.day": "2020-01-09T00:00:00.000", + "Orders.createdAt": "2020-01-09T23:49:37.000" + }, + { + "Orders.createdAt.day": "2020-01-10T00:00:00.000", + "Orders.createdAt": "2020-01-10T09:07:20.000" + }, + { + "Orders.createdAt.day": "2020-01-10T00:00:00.000", + "Orders.createdAt": "2020-01-10T13:50:05.000" + }, + { + "Orders.createdAt.day": "2020-01-10T00:00:00.000", + "Orders.createdAt": "2020-01-10T15:30:32.000" + }, + { + "Orders.createdAt.day": "2020-01-10T00:00:00.000", + "Orders.createdAt": "2020-01-10T15:32:52.000" + }, + { + "Orders.createdAt.day": "2020-01-10T00:00:00.000", + "Orders.createdAt": "2020-01-10T18:55:23.000" + }, + { + "Orders.createdAt.day": "2020-01-11T00:00:00.000", + "Orders.createdAt": "2020-01-11T01:13:17.000" + }, + { + "Orders.createdAt.day": "2020-01-11T00:00:00.000", + "Orders.createdAt": "2020-01-11T09:17:40.000" + }, + { + "Orders.createdAt.day": "2020-01-11T00:00:00.000", + "Orders.createdAt": "2020-01-11T13:23:03.000" + }, + { + "Orders.createdAt.day": "2020-01-11T00:00:00.000", + "Orders.createdAt": "2020-01-11T17:28:42.000" + }, + { + "Orders.createdAt.day": "2020-01-11T00:00:00.000", + "Orders.createdAt": "2020-01-11T22:34:32.000" + }, + { + "Orders.createdAt.day": "2020-01-11T00:00:00.000", + "Orders.createdAt": "2020-01-11T23:03:58.000" + }, + { + "Orders.createdAt.day": "2020-01-12T00:00:00.000", + "Orders.createdAt": "2020-01-12T03:46:25.000" + }, + { + "Orders.createdAt.day": "2020-01-12T00:00:00.000", + "Orders.createdAt": "2020-01-12T09:57:10.000" + }, + { + "Orders.createdAt.day": "2020-01-12T00:00:00.000", + "Orders.createdAt": "2020-01-12T12:28:22.000" + }, + { + "Orders.createdAt.day": "2020-01-12T00:00:00.000", + "Orders.createdAt": "2020-01-12T14:34:20.000" + }, + { + "Orders.createdAt.day": "2020-01-12T00:00:00.000", + "Orders.createdAt": "2020-01-12T18:45:15.000" + }, + { + "Orders.createdAt.day": "2020-01-12T00:00:00.000", + "Orders.createdAt": "2020-01-12T19:38:05.000" + }, + { + "Orders.createdAt.day": "2020-01-12T00:00:00.000", + "Orders.createdAt": "2020-01-12T21:43:51.000" + }, + { + "Orders.createdAt.day": "2020-01-13T00:00:00.000", + "Orders.createdAt": "2020-01-13T01:42:49.000" + }, + { + "Orders.createdAt.day": "2020-01-13T00:00:00.000", + "Orders.createdAt": "2020-01-13T03:19:22.000" + }, + { + "Orders.createdAt.day": "2020-01-13T00:00:00.000", + "Orders.createdAt": "2020-01-13T05:20:50.000" + }, + { + "Orders.createdAt.day": "2020-01-13T00:00:00.000", + "Orders.createdAt": "2020-01-13T05:46:35.000" + }, + { + "Orders.createdAt.day": "2020-01-13T00:00:00.000", + "Orders.createdAt": "2020-01-13T11:24:01.000" + }, + { + "Orders.createdAt.day": "2020-01-13T00:00:00.000", + "Orders.createdAt": "2020-01-13T12:13:42.000" + }, + { + "Orders.createdAt.day": "2020-01-13T00:00:00.000", + "Orders.createdAt": "2020-01-13T20:21:59.000" + }, + { + "Orders.createdAt.day": "2020-01-14T00:00:00.000", + "Orders.createdAt": "2020-01-14T20:16:23.000" + }]); + }); + + test('same dimension and time dimension without granularity', () => { + const resultSet = new ResultSet({ + "query": { + "measures": [], + "timeDimensions": [{ + "dimension": "Orders.createdAt", + "dateRange": ["2020-01-08T00:00:00.000", "2020-01-14T23:59:59.999"] + }], + "dimensions": ["Orders.createdAt"], + "filters": [], + "timezone": "UTC" + }, + "data": [ + { "Orders.createdAt": "2020-01-08T17:04:43.000" }, + { "Orders.createdAt": "2020-01-08T19:28:26.000" }, + { "Orders.createdAt": "2020-01-09T00:13:01.000" }, + { "Orders.createdAt": "2020-01-09T00:25:32.000" }, + { "Orders.createdAt": "2020-01-09T00:43:11.000" }, + { "Orders.createdAt": "2020-01-09T03:04:00.000" }, + { "Orders.createdAt": "2020-01-09T04:30:10.000" }, + { "Orders.createdAt": "2020-01-09T10:25:04.000" }, + { "Orders.createdAt": "2020-01-09T19:47:19.000" }, + { "Orders.createdAt": "2020-01-09T19:48:04.000" }, + { "Orders.createdAt": "2020-01-09T21:46:24.000" }, + { "Orders.createdAt": "2020-01-09T23:49:37.000" }, + { "Orders.createdAt": "2020-01-10T09:07:20.000" }, + { "Orders.createdAt": "2020-01-10T13:50:05.000" } + ], + "annotation": { + "measures": {}, + "dimensions": { + "Orders.createdAt": { + "title": "Orders Created at", + "shortTitle": "Created at", + "type": "time" + } + }, + "segments": {}, + "timeDimensions": {} + } + }); + + expect(resultSet.tablePivot()).toEqual([ + { "Orders.createdAt": "2020-01-08T17:04:43.000" }, + { "Orders.createdAt": "2020-01-08T19:28:26.000" }, + { "Orders.createdAt": "2020-01-09T00:13:01.000" }, + { "Orders.createdAt": "2020-01-09T00:25:32.000" }, + { "Orders.createdAt": "2020-01-09T00:43:11.000" }, + { "Orders.createdAt": "2020-01-09T03:04:00.000" }, + { "Orders.createdAt": "2020-01-09T04:30:10.000" }, + { "Orders.createdAt": "2020-01-09T10:25:04.000" }, + { "Orders.createdAt": "2020-01-09T19:47:19.000" }, + { "Orders.createdAt": "2020-01-09T19:48:04.000" }, + { "Orders.createdAt": "2020-01-09T21:46:24.000" }, + { "Orders.createdAt": "2020-01-09T23:49:37.000" }, + { "Orders.createdAt": "2020-01-10T09:07:20.000" }, + { "Orders.createdAt": "2020-01-10T13:50:05.000" } + ]); + }); }); }); diff --git a/packages/cubejs-schema-compiler/adapter/BaseQuery.js b/packages/cubejs-schema-compiler/adapter/BaseQuery.js index aaf741f98826a..675c7cb01d103 100644 --- a/packages/cubejs-schema-compiler/adapter/BaseQuery.js +++ b/packages/cubejs-schema-compiler/adapter/BaseQuery.js @@ -116,7 +116,8 @@ class BaseQuery { this.measures.map(m => [m.unescapedAliasName(), m.measure]).concat( this.dimensions.map(m => [m.unescapedAliasName(), m.dimension]) ).concat( - this.timeDimensions.map(m => [m.unescapedAliasName(), m.dimension]) + this.timeDimensions.filter(m => !!m.granularity) + .map(m => [m.unescapedAliasName(), `${m.dimension}.${m.granularity}`]) ) ); }