Support timezone aggregation

This commit is contained in:
Daniel García Aubert 2017-06-02 18:37:49 +02:00
parent c1fac13d6b
commit 8bc38a375a
2 changed files with 47 additions and 15 deletions

View File

@ -103,8 +103,10 @@ var dateBasicsQueryTpl = dot.template([
' max(date_part(\'epoch\', {{=it._column}})) AS max_val,',
' min(date_part(\'epoch\', {{=it._column}})) AS min_val,',
' avg(date_part(\'epoch\', {{=it._column}})) AS avg_val,',
' min(date_trunc(\'{{=it._aggregation}}\', {{=it._column}})) AS start_date,',
' max({{=it._column}}) AS end_date,',
' min(date_trunc(',
' \'{{=it._aggregation}}\', {{=it._column}} AT TIME ZONE \'{{=it._timezone}}\'',
' )) AS start_date,',
' max({{=it._column}} AT TIME ZONE \'{{=it._timezone}}\') AS end_date,',
' count(1) AS total_rows',
' FROM ({{=it._query}}) _cdb_basics',
')'
@ -116,8 +118,11 @@ var dateOverrideBasicsQueryTpl = dot.template([
' max({{=it._end}}) AS max_val,',
' min({{=it._start}}) AS min_val,',
' avg(date_part(\'epoch\', {{=it._column}})) AS avg_val,',
' min(date_trunc(\'{{=it._aggregation}}\', TO_TIMESTAMP({{=it._start}})::timestamp)) AS start_date,',
' max(TO_TIMESTAMP({{=it._end}})::timestamp) AS end_date,',
' min(date_trunc(',
' \'{{=it._aggregation}}\',',
' TO_TIMESTAMP({{=it._start}})::timestamp AT TIME ZONE \'{{=it._timezone}}\'',
' )) AS start_date,',
' max(TO_TIMESTAMP({{=it._end}})::timestamp AT TIME ZONE \'{{=it._timezone}}\') AS end_date,',
' count(1) AS total_rows',
' FROM ({{=it._query}}) _cdb_basics',
')'
@ -145,9 +150,16 @@ var dateHistogramQueryTpl = dot.template([
' nulls_count,',
' CASE WHEN min_val = max_val',
' THEN 0',
' ELSE GREATEST(1, LEAST(WIDTH_BUCKET({{=it._column}}, bins_array), bins_number)) - 1',
' ELSE GREATEST(1, LEAST(',
' WIDTH_BUCKET({{=it._column}} AT TIME ZONE \'{{=it._timezone}}\', bins_array),',
' bins_number',
' )) - 1',
' END AS bin,',
' date_part(\'epoch\', start_date)::numeric AS bin_start,',
' date_part(\'epoch\', start_date)::numeric AS bins_start,',
' min(date_part(',
' \'epoch\', ',
' date_trunc(\'{{=it._aggregation}}\', d AT TIME ZONE \'{{=it._timezone}}\'',
' ) AT TIME ZONE \'{{=it._timezone}}\'))::numeric AS timestamp,',
' min(date_part(\'epoch\', {{=it._column}}))::numeric AS min,',
' max(date_part(\'epoch\', {{=it._column}}))::numeric AS max,',
' avg(date_part(\'epoch\', {{=it._column}}))::numeric AS avg,',
@ -302,6 +314,7 @@ Histogram.prototype._buildDateHistogramQuery = function (override, callback) {
var _column = this.column;
var _query = this.query;
var _aggregation = override && override.aggregation ? override.aggregation : this.aggregation;
var _timezone = override && override.timezone ? override.timezone : this.timezone;
var dateBasicsQuery;
@ -311,13 +324,15 @@ Histogram.prototype._buildDateHistogramQuery = function (override, callback) {
_column: _column,
_aggregation: _aggregation,
_start: getBinStart(override),
_end: getBinEnd(override)
_end: getBinEnd(override),
_timezone: getTimezone(_timezone)
});
} else {
dateBasicsQuery = dateBasicsQueryTpl({
_query: _query,
_column: _column,
_aggregation: _aggregation
_aggregation: _aggregation,
_timezone: getTimezone(_timezone)
});
}
@ -334,7 +349,9 @@ Histogram.prototype._buildDateHistogramQuery = function (override, callback) {
var dateHistogramQuery = dateHistogramQueryTpl({
_query: _query,
_column: _column
_column: _column,
_aggregation: _aggregation,
_timezone: getTimezone(_timezone)
});
var histogramSql = [
@ -371,7 +388,7 @@ Histogram.prototype.format = function(result, override) {
binsStart = override.hasOwnProperty('start') ? getBinStart(override) : firstRow.min;
buckets = result.rows.map(function(row) {
return _.omit(row, 'bins_number', 'bin_width', 'nulls_count', 'avg_val');
return _.omit(row, 'bins_number', 'bin_width', 'nulls_count', 'avg_val', 'bins_start');
});
}
@ -414,6 +431,20 @@ function getWidth(override) {
return width;
}
function getTimezone(timezone) {
if (!timezone) {
return '0';
}
var timezoneInHours = Math.ceil(timezone / 3600);
if (timezoneInHours >= 0) {
return '+' + timezoneInHours;
} else {
return '' + timezoneInHours;
}
}
Histogram.prototype.getType = function() {
return TYPE;
};

View File

@ -130,7 +130,8 @@ describe('histogram-dataview for date column type', function() {
type: 'histogram',
options: {
column: 'd',
aggregation: 'month'
aggregation: 'month',
timezone: -7200
}
}
},
@ -195,7 +196,7 @@ describe('histogram-dataview for date column type', function() {
assert.ok(!err, err);
assert.equal(dataview.type, 'histogram');
assert.ok(dataview.bin_width > 0, 'Unexpected bin width: ' + dataview.bin_width);
assert.equal(dataview.bins.length, 5);
assert.equal(dataview.bins.length, 6);
dataview.bins.forEach(function(bin) {
assert.ok(bin.min <= bin.max, 'bin min < bin max: ' + JSON.stringify(bin));
});
@ -204,9 +205,9 @@ describe('histogram-dataview for date column type', function() {
});
});
it.skip('should aggregate respecting timezone', function (done) {
it('should aggregate respecting timezone', function (done) {
var params = {
timezone: -7200 // GMT -2h
timezone: 7200 // GMT +2h
};
this.testClient = new TestClient(mapConfig, 1234);
@ -214,7 +215,7 @@ describe('histogram-dataview for date column type', function() {
assert.ok(!err, err);
assert.equal(dataview.type, 'histogram');
assert.ok(dataview.bin_width > 0, 'Unexpected bin width: ' + dataview.bin_width);
assert.equal(dataview.bins.length, 5);
assert.equal(dataview.bins.length, 15);
dataview.bins.forEach(function(bin) {
assert.ok(bin.min <= bin.max, 'bin min < bin max: ' + JSON.stringify(bin));
});