From b745fab190f904af9b538105ac6ac83dba18bedc Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Fri, 13 Jul 2018 22:29:10 +0200 Subject: [PATCH] add tests for query generation --- .../datasource/postgres/postgres_query.ts | 28 ++--- .../plugins/datasource/postgres/query_ctrl.ts | 2 +- .../postgres/specs/postgres_query.jest.ts | 100 ++++++++++++++++++ 3 files changed, 115 insertions(+), 15 deletions(-) create mode 100644 public/app/plugins/datasource/postgres/specs/postgres_query.jest.ts diff --git a/public/app/plugins/datasource/postgres/postgres_query.ts b/public/app/plugins/datasource/postgres/postgres_query.ts index 1cac6835ca1..babd7c9d6ec 100644 --- a/public/app/plugins/datasource/postgres/postgres_query.ts +++ b/public/app/plugins/datasource/postgres/postgres_query.ts @@ -204,17 +204,15 @@ export default class PostgresQuery { query = target.timeColumn + ' AS "time"'; } - return '\n ' + query; + return query; } buildMetricColumn(target) { - let query = ''; - - if (this.target.metricColumn !== 'None') { - query += ',\n ' + this.target.metricColumn + ' AS metric'; + if (target.metricColumn !== 'None') { + return target.metricColumn + ' AS metric'; } - return query; + return ''; } buildValueColumns(target) { @@ -289,21 +287,21 @@ export default class PostgresQuery { let query = ''; let groupBySection = ''; - for (let i = 0; i < this.groupByParts.length; i++) { - let part = this.groupByParts[i]; + for (let i = 0; i < target.groupBy.length; i++) { + let part = target.groupBy[i]; if (i > 0) { groupBySection += ', '; } - if (part.def.type === 'time') { + if (part.type === 'time') { groupBySection += '1'; } else { - groupBySection += part.render(''); + groupBySection += part.params[0]; } } if (groupBySection.length) { query = '\nGROUP BY ' + groupBySection; - if (this.target.metricColumn !== 'None') { + if (target.metricColumn !== 'None') { query += ',2'; } } @@ -311,10 +309,12 @@ export default class PostgresQuery { } buildQuery(target) { - let query = 'SELECT '; + let query = 'SELECT'; - query += this.buildTimeColumn(target); - query += this.buildMetricColumn(target); + query += '\n ' + this.buildTimeColumn(target); + if (target.metricColumn !== 'None') { + query += '\n ' + this.buildMetricColumn(target); + } query += this.buildValueColumns(target); query += '\nFROM ' + target.schema + '.' + target.table; diff --git a/public/app/plugins/datasource/postgres/query_ctrl.ts b/public/app/plugins/datasource/postgres/query_ctrl.ts index b9037d6c3f0..e10fe25e4ad 100644 --- a/public/app/plugins/datasource/postgres/query_ctrl.ts +++ b/public/app/plugins/datasource/postgres/query_ctrl.ts @@ -299,7 +299,7 @@ export class PostgresQueryCtrl extends QueryCtrl { getWhereOptions() { var options = []; options.push(this.uiSegmentSrv.newSegment({ type: 'macro', value: '$__timeFilter' })); - options.push(this.uiSegmentSrv.newSegment({ type: 'macro', value: '$__unixEpochFilter' })); + // options.push(this.uiSegmentSrv.newSegment({ type: 'macro', value: '$__unixEpochFilter' })); options.push(this.uiSegmentSrv.newSegment({ type: 'expression', value: 'Expression' })); return this.$q.when(options); } diff --git a/public/app/plugins/datasource/postgres/specs/postgres_query.jest.ts b/public/app/plugins/datasource/postgres/specs/postgres_query.jest.ts new file mode 100644 index 00000000000..fc05441f985 --- /dev/null +++ b/public/app/plugins/datasource/postgres/specs/postgres_query.jest.ts @@ -0,0 +1,100 @@ +import PostgresQuery from '../postgres_query'; + +describe('PostgresQuery', function() { + describe('When initializing', function() { + it('should not be in SQL mode', function() { + let query = new PostgresQuery({}, templateSrv); + expect(query.target.rawQuery).toBe(false); + }); + it('should be in SQL mode for pre query builder queries', function() { + let query = new PostgresQuery({ rawSql: 'SELECT 1' }, templateSrv); + expect(query.target.rawQuery).toBe(true); + }); + }); + + describe('When generating time column SQL', function() { + let query = new PostgresQuery({}, templateSrv); + + expect(query.buildTimeColumn({ timeColumn: 'time' })).toBe('time AS "time"'); + expect(query.buildTimeColumn({ timeColumn: '"time"' })).toBe('"time" AS "time"'); + }); + + describe('When generating time column SQL with group by time', function() { + let query = new PostgresQuery( + { timeColumn: 'time', groupBy: [{ type: 'time', params: ['5m', 'none'] }] }, + templateSrv + ); + expect(query.buildTimeColumn(query.target)).toBe('$__timeGroup(time,5m)'); + + query = new PostgresQuery({ timeColumn: 'time', groupBy: [{ type: 'time', params: ['5m', 'NULL'] }] }, templateSrv); + expect(query.buildTimeColumn(query.target)).toBe('$__timeGroup(time,5m,NULL)'); + }); + + describe('When generating metric column SQL', function() { + let query = new PostgresQuery({}, templateSrv); + + expect(query.buildMetricColumn({ metricColumn: 'host' })).toBe('host AS metric'); + expect(query.buildMetricColumn({ metricColumn: '"host"' })).toBe('"host" AS metric'); + }); + + describe('When generating value column SQL', function() { + let query = new PostgresQuery({}, templateSrv); + + let column = [{ type: 'column', params: ['value'] }]; + expect(query.buildValueColumn(query.target, column)).toBe('value'); + column = [{ type: 'column', params: ['value'] }, { type: 'alias', params: ['alias'] }]; + expect(query.buildValueColumn(query.target, column)).toBe('value AS "alias"'); + column = [ + { type: 'column', params: ['v'] }, + { type: 'alias', params: ['a'] }, + { type: 'aggregate', params: ['max'] }, + ]; + expect(query.buildValueColumn(query.target, column)).toBe('max(v) AS "a"'); + column = [ + { type: 'column', params: ['v'] }, + { type: 'alias', params: ['a'] }, + { type: 'special', params: ['increase'] }, + ]; + expect(query.buildValueColumn(query.target, column)).toBe('v - lag(v) OVER () AS "a"'); + }); + + describe('When generating WHERE clause', function() { + let query = new PostgresQuery({ where: [] }, templateSrv); + let target; + + expect(query.buildWhereClause(query.target)).toBe(''); + target = { where: [{ type: 'macro', name: '$__timeFilter' }], timeColumn: 't' }; + expect(query.buildWhereClause(target)).toBe('\nWHERE\n $__timeFilter(t)'); + target = { where: [{ type: 'expression', params: ['v', '=', '1'] }], timeColumn: 't' }; + expect(query.buildWhereClause(target)).toBe('\nWHERE\n v = 1'); + target = { + where: [{ type: 'macro', name: '$__timeFilter' }, { type: 'expression', params: ['v', '=', '1'] }], + timeColumn: 't', + }; + expect(query.buildWhereClause(target)).toBe('\nWHERE\n $__timeFilter(t) AND\n v = 1'); + }); + + describe('When generating GROUP BY clause', function() { + let query = new PostgresQuery({ groupBy: [] }, templateSrv); + let target; + + expect(query.buildGroupByClause(query.target)).toBe(''); + target = { groupBy: [{ type: 'time', params: ['5m'] }], metricColumn: 'None' }; + expect(query.buildGroupByClause(target)).toBe('\nGROUP BY 1'); + target = { groupBy: [{ type: 'time', params: ['5m'] }], metricColumn: 'm' }; + expect(query.buildGroupByClause(target)).toBe('\nGROUP BY 1,2'); + }); + + describe('When generating complete statement', function() { + let target = { + timeColumn: 't', + schema: 'public', + table: 'table', + select: [[{ type: 'column', params: ['value'] }]], + }; + let result = 'SELECT\n t AS "time",\n value\nFROM public.table\nORDER BY 1'; + let query = new PostgresQuery(target, templateSrv); + + expect(query.buildQuery(query.target)).toBe(result); + }); +});