From fcbf5ffcc5d542d4318129a1192b0e23bdcfa545 Mon Sep 17 00:00:00 2001 From: Raul Marin Date: Wed, 29 Nov 2017 13:07:59 +0100 Subject: [PATCH] Move sql helper functions to query-utils.js --- .../dataview/histograms/numeric-histogram.js | 42 ++++++------------- lib/cartodb/utils/query-utils.js | 31 ++++++++++++++ 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/lib/cartodb/models/dataview/histograms/numeric-histogram.js b/lib/cartodb/models/dataview/histograms/numeric-histogram.js index 0396e2f8..a2d5662d 100644 --- a/lib/cartodb/models/dataview/histograms/numeric-histogram.js +++ b/lib/cartodb/models/dataview/histograms/numeric-histogram.js @@ -1,30 +1,13 @@ const BaseHistogram = require('./base-histogram'); const debug = require('debug')('windshaft:dataview:numeric-histogram'); - -/** Cast the column column to epoch */ -const columnCastTpl = ctx => `date_part('epoch', ${ctx.column})`; - -/** If the column type is float, ignore any non numeric result (infinity / NaN) */ -const handleFloatColum = ctx => `${!ctx.isFloatColumn ? `${ctx.column}` : - `nullif(nullif(nullif(${ctx.column}, 'infinity'::float), '-infinity'::float), 'NaN'::float)` -}`; - -/** Count only infinity (positive and negative) appearances */ -const countInfinites = ctx => `${!ctx.isFloatColumn ? `0` : - `sum(CASE WHEN (${ctx.column} = 'infinity'::float OR ${ctx.column} = '-infinity'::float) THEN 1 ELSE 0 END)` -}`; - -/** Count only NaNs appearances*/ -const countNaNs = ctx => `${!ctx.isFloatColumn ? `0` : - `sum(CASE WHEN (${ctx.column} = 'NaN'::float) THEN 1 ELSE 0 END)` -}`; +const utils = require('../../../utils/query-utils'); /** Query to get min and max values from the query */ const irqQueryTpl = ctx => ` __cdb_filtered_source AS ( SELECT * FROM (${ctx.query}) __cdb_filtered_source_query - WHERE ${handleFloatColum(ctx)} IS NOT NULL + WHERE ${utils.handleFloatColumn(ctx)} IS NOT NULL ), __cdb_basics AS ( SELECT @@ -85,7 +68,7 @@ module.exports = class NumericHistogram extends BaseHistogram { _buildQuery (psql, override, callback) { const histogramSql = this._buildQueryTpl({ - column: this._columnType === 'date' ? columnCastTpl({ column: this.column }) : this.column, + column: this._columnType === 'date' ? utils.columnCastTpl({ column: this.column }) : this.column, isFloatColumn: this._columnType === 'float', query: this.query, start: this._getBinStart(override), @@ -137,17 +120,18 @@ ${extra_queries} SELECT (${ctx.end} - ${ctx.start}) / ${ctx.bins}::float AS bin_width, ${ctx.bins} as bins_number, - sum(CASE WHEN (${ctx.column} IS NULL) THEN 1 ELSE 0 END) AS nulls_count, - ${countInfinites(ctx)} AS infinities_count, - ${countNaNs(ctx)} AS nans_count, - min(${handleFloatColum(ctx)}) AS min, - max(${handleFloatColum(ctx)}) AS max, - avg(${handleFloatColum(ctx)}) AS avg, - sum(CASE WHEN (${handleFloatColum(ctx)} is not NULL) THEN 1 ELSE 0 END) as freq, + ${utils.countNULLs(ctx)} AS nulls_count, + ${utils.countInfinites(ctx)} AS infinities_count, + ${utils.countNaNs(ctx)} AS nans_count, + min(${utils.handleFloatColumn(ctx)}) AS min, + max(${utils.handleFloatColumn(ctx)}) AS max, + avg(${utils.handleFloatColumn(ctx)}) AS avg, + sum(CASE WHEN (${utils.handleFloatColumn(ctx)} is not NULL) THEN 1 ELSE 0 END) as freq, CASE WHEN ${ctx.start} = ${ctx.end} THEN 0 - ELSE GREATEST(1, LEAST(${ctx.bins}, - WIDTH_BUCKET(${handleFloatColum(ctx)}, ${ctx.start}, ${ctx.end}, ${ctx.bins}))) - 1 + ELSE GREATEST(1, LEAST( + ${ctx.bins}, + WIDTH_BUCKET(${utils.handleFloatColumn(ctx)}, ${ctx.start}, ${ctx.end}, ${ctx.bins}))) - 1 END AS bin FROM ( diff --git a/lib/cartodb/utils/query-utils.js b/lib/cartodb/utils/query-utils.js index 47d730f4..8b0c81ba 100644 --- a/lib/cartodb/utils/query-utils.js +++ b/lib/cartodb/utils/query-utils.js @@ -24,3 +24,34 @@ module.exports.extractTableNames = function extractTableNames(query) { module.exports.getQueryRowCount = function getQueryRowEstimation(query) { return 'select CDB_EstimateRowCount(\'' + query + '\') as rows'; }; + +/** Cast the column to epoch */ +module.exports.columnCastTpl = function columnCastTpl(ctx) { + return `date_part('epoch', ${ctx.column})`; +}; + +/** If the column type is float, ignore any non numeric result (infinity / NaN) */ +module.exports.handleFloatColumn = function handleFloatColumn(ctx) { + return `${!ctx.isFloatColumn ? `${ctx.column}` : + `nullif(nullif(nullif(${ctx.column}, 'infinity'::float), '-infinity'::float), 'NaN'::float)` + }`; +}; + +/** Count NULL appearances */ +module.exports.countNULLs= function countNULLs(ctx) { + return `sum(CASE WHEN (${ctx.column} IS NULL) THEN 1 ELSE 0 END)`; +}; + +/** Count only infinity (positive and negative) appearances */ +module.exports.countInfinites = function countInfinites(ctx) { + return `${!ctx.isFloatColumn ? `0` : + `sum(CASE WHEN (${ctx.column} = 'infinity'::float OR ${ctx.column} = '-infinity'::float) THEN 1 ELSE 0 END)` + }`; +}; + +/** Count only NaNs appearances*/ +module.exports.countNaNs = function countNaNs(ctx) { + return `${!ctx.isFloatColumn ? `0` : + `sum(CASE WHEN (${ctx.column} = 'NaN'::float) THEN 1 ELSE 0 END)` + }`; +}; \ No newline at end of file