Use dataview base to get column type in formula dataviews
This commit is contained in:
parent
443c1100d7
commit
ad570ab6f2
@ -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)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
});
|
});
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user