Use dataview base to get column type in formula dataviews

This commit is contained in:
Daniel García Aubert 2017-06-15 18:04:35 +02:00
parent 443c1100d7
commit ad570ab6f2
3 changed files with 92 additions and 94 deletions

View File

@ -1,3 +1,6 @@
var dot = require('dot');
dot.templateSettings.strip = false;
function BaseDataview() {} function BaseDataview() {}
module.exports = BaseDataview; module.exports = BaseDataview;
@ -24,3 +27,34 @@ BaseDataview.prototype.getResult = function(psql, override, callback) {
BaseDataview.prototype.search = function(psql, userQuery, callback) { BaseDataview.prototype.search = function(psql, userQuery, callback) {
return callback(null, this.format({ rows: [] })); return callback(null, this.format({ rows: [] }));
}; };
var FLOAT_OIDS = {
700: true,
701: true
};
var columnTypeQueryTpl = dot.template(
'SELECT pg_typeof({{=it.column}})::oid FROM ({{=it.query}}) _cdb_column_type limit 1'
);
BaseDataview.prototype.getColumnType = function (psql, column, query, callback) {
var readOnlyTransaction = true;
var columnTypeQuery = columnTypeQueryTpl({
column: column, query: query
});
psql.query(columnTypeQuery, function(err, result) {
if (err) {
return callback(err);
}
var pgType = result.rows[0].pg_typeof;
callback(null, getPGTypeName(pgType));
}, readOnlyTransaction);
};
function getPGTypeName (pgType) {
return {
float: FLOAT_OIDS.hasOwnProperty(pgType)
};
}

View File

@ -5,10 +5,6 @@ var debug = require('debug')('windshaft:widget:formula');
var dot = require('dot'); var dot = require('dot');
dot.templateSettings.strip = false; dot.templateSettings.strip = false;
var columnTypeQueryTpl = dot.template(
'SELECT pg_typeof({{=it.column}})::oid FROM ({{=it.query}}) _cdb_histogram_column_type limit 1'
);
var formulaQueryTpl = dot.template([ var formulaQueryTpl = dot.template([
'SELECT', 'SELECT',
' {{=it._operation}}({{=it._column}}) AS result,', ' {{=it._operation}}({{=it._column}}) AS result,',
@ -34,11 +30,6 @@ var VALID_OPERATIONS = {
max: true max: true
}; };
var FLOAT_OIDS = {
700: true,
701: true
};
var TYPE = 'formula'; var TYPE = 'formula';
/** /**
@ -84,30 +75,20 @@ Formula.prototype.sql = function(psql, override, callback) {
override = {}; override = {};
} }
var _query = this.query;
var columnTypeQuery = columnTypeQueryTpl({
column: this.column, query: _query
});
if (this._isFloatColumn === null) { if (this._isFloatColumn === null) {
var readOnlyTransaction = true; this._isFloatColumn = false;
psql.query(columnTypeQuery, function(err, result) { this.getColumnType(psql, this.column, this.query, function (err, type) {
self._isFloatColumn = false; if (!err && !!type) {
if (!err && !!result.rows[0]) { self._isFloatColumn = type.float;
var pgType = result.rows[0].pg_typeof;
if (FLOAT_OIDS.hasOwnProperty(pgType)) {
self._isFloatColumn = true;
}
} }
self.sql(psql, override, callback); self.sql(psql, override, callback);
}, readOnlyTransaction); });
return null; return null;
} }
var formulaSql = formulaQueryTpl({ var formulaSql = formulaQueryTpl({
_isFloatColumn: this._isFloatColumn, _isFloatColumn: this._isFloatColumn,
_query: _query, _query: this.query,
_operation: this.operation, _operation: this.operation,
_column: this.column _column: this.column
}); });

View File

@ -5,58 +5,49 @@ var debug = require('debug')('windshaft:widget:formula:overview');
var dot = require('dot'); var dot = require('dot');
dot.templateSettings.strip = false; dot.templateSettings.strip = false;
var FLOAT_OIDS = {
700: true,
701: true
};
var columnTypeQueryTpl = dot.template(
'SELECT pg_typeof({{=it.column}})::oid FROM ({{=it.query}}) _cdb_histogram_column_type limit 1'
);
var formulaQueryTpls = { var formulaQueryTpls = {
'count': dot.template([ 'count': dot.template([
'SELECT', 'SELECT',
'sum(_feature_count) AS result,', 'sum(_feature_count) AS result,',
'(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nulls WHERE {{=it._column}} IS NULL) AS nulls_count', '(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nulls WHERE {{=it._column}} IS NULL) AS nulls_count',
'{{?it._isFloatColumn}},(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_infinities', '{{?it._isFloatColumn}},(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_infinities',
' WHERE {{=it._column}} = \'infinity\'::float OR {{=it._column}} = \'-infinity\'::float) AS infinities_count,', ' WHERE {{=it._column}} = \'infinity\'::float OR {{=it._column}} = \'-infinity\'::float) AS infinities_count,',
'(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nans', '(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nans',
' WHERE {{=it._column}} = \'NaN\'::float) AS nans_count{{?}}', ' WHERE {{=it._column}} = \'NaN\'::float) AS nans_count{{?}}',
'FROM ({{=it._query}}) _cdb_formula' 'FROM ({{=it._query}}) _cdb_formula'
].join('\n')), ].join('\n')),
'sum': dot.template([ 'sum': dot.template([
'SELECT', 'SELECT',
'sum({{=it._column}}*_feature_count) AS result,', 'sum({{=it._column}}*_feature_count) AS result,',
'(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nulls WHERE {{=it._column}} IS NULL) AS nulls_count', '(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nulls WHERE {{=it._column}} IS NULL) AS nulls_count',
'{{?it._isFloatColumn}},(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_infinities', '{{?it._isFloatColumn}},(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_infinities',
' WHERE {{=it._column}} = \'infinity\'::float OR {{=it._column}} = \'-infinity\'::float) AS infinities_count', ' WHERE {{=it._column}} = \'infinity\'::float OR {{=it._column}} = \'-infinity\'::float) AS infinities_count',
',(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nans', ',(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nans',
' WHERE {{=it._column}} = \'NaN\'::float) AS nans_count{{?}}', ' WHERE {{=it._column}} = \'NaN\'::float) AS nans_count{{?}}',
'FROM ({{=it._query}}) _cdb_formula', 'FROM ({{=it._query}}) _cdb_formula',
'{{?it._isFloatColumn}}WHERE', '{{?it._isFloatColumn}}WHERE',
' {{=it._column}} != \'infinity\'::float', ' {{=it._column}} != \'infinity\'::float',
'AND', 'AND',
' {{=it._column}} != \'-infinity\'::float', ' {{=it._column}} != \'-infinity\'::float',
'AND', 'AND',
' {{=it._column}} != \'NaN\'::float{{?}}' ' {{=it._column}} != \'NaN\'::float{{?}}'
].join('\n')), ].join('\n')),
'avg': dot.template([ 'avg': dot.template([
'SELECT', 'SELECT',
'sum({{=it._column}}*_feature_count)/sum(_feature_count) AS result,', 'sum({{=it._column}}*_feature_count)/sum(_feature_count) AS result,',
'(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nulls WHERE {{=it._column}} IS NULL) AS nulls_count', '(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nulls WHERE {{=it._column}} IS NULL) AS nulls_count',
'{{?it._isFloatColumn}},(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_infinities', '{{?it._isFloatColumn}},(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_infinities',
' WHERE {{=it._column}} = \'infinity\'::float OR {{=it._column}} = \'-infinity\'::float) AS infinities_count', ' WHERE {{=it._column}} = \'infinity\'::float OR {{=it._column}} = \'-infinity\'::float) AS infinities_count',
',(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nans', ',(SELECT count(1) FROM ({{=it._query}}) _cdb_formula_nans',
' WHERE {{=it._column}} = \'NaN\'::float) AS nans_count{{?}}', ' WHERE {{=it._column}} = \'NaN\'::float) AS nans_count{{?}}',
'FROM ({{=it._query}}) _cdb_formula', 'FROM ({{=it._query}}) _cdb_formula',
'{{?it._isFloatColumn}}WHERE', '{{?it._isFloatColumn}}WHERE',
' {{=it._column}} != \'infinity\'::float', ' {{=it._column}} != \'infinity\'::float',
'AND', 'AND',
' {{=it._column}} != \'-infinity\'::float', ' {{=it._column}} != \'-infinity\'::float',
'AND', 'AND',
' {{=it._column}} != \'NaN\'::float{{?}}' ' {{=it._column}} != \'NaN\'::float{{?}}'
].join('\n')), ].join('\n')),
}; };
function Formula(query, options, queryRewriter, queryRewriteData, params) { function Formula(query, options, queryRewriter, queryRewriteData, params) {
@ -71,38 +62,30 @@ Formula.prototype.constructor = Formula;
module.exports = Formula; module.exports = Formula;
Formula.prototype.sql = function(psql, override, callback) { Formula.prototype.sql = function (psql, override, callback) {
var self = this; var self = this;
var formulaQueryTpl = formulaQueryTpls[this.operation]; var formulaQueryTpl = formulaQueryTpls[this.operation];
if ( formulaQueryTpl ) { if (formulaQueryTpl) {
// supported formula for use with overviews // supported formula for use with overviews
var columnTypeQuery = columnTypeQueryTpl({
column: this.column, query: this.query
});
if (this._isFloatColumn === null) { if (this._isFloatColumn === null) {
var readOnlyTransaction = true; this._isFloatColumn = false;
psql.query(columnTypeQuery, function(err, result) { this.getColumnType(psql, this.column, this.query, function (err, type) {
self._isFloatColumn = false; if (!err && !!type) {
if (!err && !!result.rows[0]) { self._isFloatColumn = type.float;
var pgType = result.rows[0].pg_typeof;
if (FLOAT_OIDS.hasOwnProperty(pgType)) {
self._isFloatColumn = true;
}
} }
self.sql(psql, override, callback); self.sql(psql, override, callback);
}, readOnlyTransaction); });
return null; return null;
} }
var formulaSql = formulaQueryTpl({ var formulaSql = formulaQueryTpl({
_isFloatColumn: this._isFloatColumn, _isFloatColumn: this._isFloatColumn,
_query: this.rewrittenQuery(this.query), _query: this.rewrittenQuery(this.query),
_operation: this.operation, _operation: this.operation,
_column: this.column _column: this.column
}); });
callback = callback || override; callback = callback || override;
debug(formulaSql); debug(formulaSql);