remove tableschema from query builder ui

This commit is contained in:
Sven Klemm
2018-07-27 10:58:08 +02:00
parent b3ebc86093
commit 97f24733f5
5 changed files with 73 additions and 41 deletions

View File

@ -10,7 +10,6 @@ export class PostgresMetaQuery {
// query that returns first table found that has a timestamptz column and a float column // query that returns first table found that has a timestamptz column and a float column
let query = ` let query = `
SELECT SELECT
table_schema,
table_name, table_name,
( SELECT ( SELECT
column_name column_name
@ -32,7 +31,10 @@ SELECT
) AS value_column ) AS value_column
FROM information_schema.tables t FROM information_schema.tables t
WHERE WHERE
table_schema !~* '^_|^pg_|information_schema' AND table_schema IN (
SELECT CASE WHEN trim(unnest) = \'"$user"\' THEN user ELSE trim(unnest) END
FROM unnest(string_to_array(current_setting(\'search_path\'),\',\'))
) AND
EXISTS EXISTS
( SELECT 1 ( SELECT 1
FROM information_schema.columns c FROM information_schema.columns c
@ -53,23 +55,30 @@ LIMIT 1
return query; return query;
} }
buildSchemaQuery() {
let query = 'SELECT quote_ident(schema_name) FROM information_schema.schemata WHERE';
query += " schema_name !~* '^pg_|^_|information_schema' ORDER BY schema_name";
return query;
}
buildTableQuery() { buildTableQuery() {
let query = 'SELECT quote_ident(table_name) FROM information_schema.tables WHERE '; let query = `
query += 'table_schema = ' + this.quoteIdentAsLiteral(this.target.schema); SELECT quote_ident(table_name)
query += ' ORDER BY table_name'; FROM information_schema.tables
WHERE
table_schema IN (
SELECT CASE WHEN trim(unnest) = \'"$user"\' THEN user ELSE trim(unnest) END
FROM unnest(string_to_array(current_setting(\'search_path\'),\',\'))
)
ORDER BY table_name`;
return query; return query;
} }
buildColumnQuery(type?: string) { buildColumnQuery(type?: string) {
let query = 'SELECT quote_ident(column_name) FROM information_schema.columns WHERE '; let query = `
query += 'table_schema = ' + this.quoteIdentAsLiteral(this.target.schema); SELECT quote_ident(column_name)
FROM information_schema.columns
WHERE
table_schema IN (
SELECT CASE WHEN trim(unnest) = \'"$user"\' THEN user ELSE trim(unnest) END
FROM unnest(string_to_array(current_setting(\'search_path\'),\',\'))
LIMIT 1
)
`;
query += ' AND table_name = ' + this.quoteIdentAsLiteral(this.target.table); query += ' AND table_name = ' + this.quoteIdentAsLiteral(this.target.table);
switch (type) { switch (type) {
@ -100,15 +109,23 @@ LIMIT 1
buildValueQuery(column: string) { buildValueQuery(column: string) {
let query = 'SELECT DISTINCT quote_literal(' + column + ')'; let query = 'SELECT DISTINCT quote_literal(' + column + ')';
query += ' FROM ' + this.target.schema + '.' + this.target.table; query += ' FROM ' + this.target.table;
query += ' WHERE $__timeFilter(' + this.target.timeColumn + ')'; query += ' WHERE $__timeFilter(' + this.target.timeColumn + ')';
query += ' ORDER BY 1 LIMIT 100'; query += ' ORDER BY 1 LIMIT 100';
return query; return query;
} }
buildDatatypeQuery(column: string) { buildDatatypeQuery(column: string) {
let query = 'SELECT data_type FROM information_schema.columns WHERE '; let query = `
query += ' table_schema = ' + this.quoteIdentAsLiteral(this.target.schema); SELECT data_type
FROM information_schema.columns
WHERE
table_schema IN (
SELECT CASE WHEN trim(unnest) = \'"$user"\' THEN user ELSE trim(unnest) END
FROM unnest(string_to_array(current_setting(\'search_path\'),\',\'))
LIMIT 1
)
`;
query += ' AND table_name = ' + this.quoteIdentAsLiteral(this.target.table); query += ' AND table_name = ' + this.quoteIdentAsLiteral(this.target.table);
query += ' AND column_name = ' + this.quoteIdentAsLiteral(column); query += ' AND column_name = ' + this.quoteIdentAsLiteral(column);
return query; return query;

View File

@ -13,7 +13,6 @@
<div class="gf-form-inline"> <div class="gf-form-inline">
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label query-keyword width-6">FROM</label> <label class="gf-form-label query-keyword width-6">FROM</label>
<metric-segment segment="ctrl.schemaSegment" get-options="ctrl.getSchemaSegments()" on-change="ctrl.schemaChanged()"></metric-segment>
<metric-segment segment="ctrl.tableSegment" get-options="ctrl.getTableSegments()" on-change="ctrl.tableChanged()"></metric-segment> <metric-segment segment="ctrl.tableSegment" get-options="ctrl.getTableSegments()" on-change="ctrl.tableChanged()"></metric-segment>
<label class="gf-form-label query-keyword width-7">Time column</label> <label class="gf-form-label query-keyword width-7">Time column</label>

View File

@ -11,7 +11,6 @@ export default class PostgresQuery {
this.templateSrv = templateSrv; this.templateSrv = templateSrv;
this.scopedVars = scopedVars; this.scopedVars = scopedVars;
target.schema = target.schema || 'public';
target.format = target.format || 'time_series'; target.format = target.format || 'time_series';
target.timeColumn = target.timeColumn || 'time'; target.timeColumn = target.timeColumn || 'time';
target.metricColumn = target.metricColumn || 'none'; target.metricColumn = target.metricColumn || 'none';
@ -147,13 +146,15 @@ export default class PostgresQuery {
} }
if (special) { if (special) {
let over = ''; let overParts = [];
if (this.hasMetricColumn()) { if (this.hasMetricColumn()) {
over = 'PARTITION BY ' + this.target.metricColumn; overParts.push('PARTITION BY ' + this.target.metricColumn);
} }
if (!aggregate) { if (!aggregate) {
over += ' ORDER BY ' + this.target.timeColumn; overParts.push('ORDER BY ' + this.target.timeColumn);
} }
let over = overParts.join(' ');
switch (special.params[0]) { switch (special.params[0]) {
case 'increase': case 'increase':
query = query + ' - lag(' + query + ') OVER (' + over + ')'; query = query + ' - lag(' + query + ') OVER (' + over + ')';
@ -234,7 +235,7 @@ export default class PostgresQuery {
} }
query += this.buildValueColumns(); query += this.buildValueColumns();
query += '\nFROM ' + this.target.schema + '.' + this.target.table; query += '\nFROM ' + this.target.table;
query += this.buildWhereClause(); query += this.buildWhereClause();
query += this.buildGroupByClause(); query += this.buildGroupByClause();

View File

@ -28,7 +28,6 @@ export class PostgresQueryCtrl extends QueryCtrl {
lastQueryMeta: QueryMeta; lastQueryMeta: QueryMeta;
lastQueryError: string; lastQueryError: string;
showHelp: boolean; showHelp: boolean;
schemaSegment: any;
tableSegment: any; tableSegment: any;
whereAdd: any; whereAdd: any;
timeColumnSegment: any; timeColumnSegment: any;
@ -59,8 +58,6 @@ export class PostgresQueryCtrl extends QueryCtrl {
} }
} }
this.schemaSegment = uiSegmentSrv.newSegment(this.target.schema);
if (!this.target.table) { if (!this.target.table) {
this.tableSegment = uiSegmentSrv.newSegment({ value: 'select table', fake: true }); this.tableSegment = uiSegmentSrv.newSegment({ value: 'select table', fake: true });
} else { } else {
@ -119,18 +116,6 @@ export class PostgresQueryCtrl extends QueryCtrl {
button.value = plusButton.value; button.value = plusButton.value;
} }
getSchemaSegments() {
return this.datasource
.metricFindQuery(this.metaBuilder.buildSchemaQuery())
.then(this.transformToSegments({}))
.catch(this.handleQueryError.bind(this));
}
schemaChanged() {
this.target.schema = this.schemaSegment.value;
this.panelCtrl.refresh();
}
getTableSegments() { getTableSegments() {
return this.datasource return this.datasource
.metricFindQuery(this.metaBuilder.buildTableQuery()) .metricFindQuery(this.metaBuilder.buildTableQuery())

View File

@ -66,6 +66,37 @@ describe('PostgresQuery', function() {
expect(query.buildValueColumn(column)).toBe('v - lag(v) OVER (ORDER BY time) AS "a"'); expect(query.buildValueColumn(column)).toBe('v - lag(v) OVER (ORDER BY time) AS "a"');
}); });
describe('When generating value column SQL with metric column', function() {
let query = new PostgresQuery({}, templateSrv);
query.target.metricColumn = 'host';
let column = [{ type: 'column', params: ['value'] }];
expect(query.buildValueColumn(column)).toBe('value');
column = [{ type: 'column', params: ['value'] }, { type: 'alias', params: ['alias'] }];
expect(query.buildValueColumn(column)).toBe('value AS "alias"');
column = [
{ type: 'column', params: ['v'] },
{ type: 'alias', params: ['a'] },
{ type: 'aggregate', params: ['max'] },
];
expect(query.buildValueColumn(column)).toBe('max(v) AS "a"');
column = [
{ type: 'column', params: ['v'] },
{ type: 'alias', params: ['a'] },
{ type: 'special', params: ['increase'] },
];
expect(query.buildValueColumn(column)).toBe('v - lag(v) OVER (PARTITION BY host ORDER BY time) AS "a"');
column = [
{ type: 'column', params: ['v'] },
{ type: 'alias', params: ['a'] },
{ type: 'aggregate', params: ['max'] },
{ type: 'special', params: ['increase'] },
];
expect(query.buildValueColumn(column)).toBe(
'max(v ORDER BY time) - lag(max(v ORDER BY time)) OVER (PARTITION BY host) AS "a"'
);
});
describe('When generating WHERE clause', function() { describe('When generating WHERE clause', function() {
let query = new PostgresQuery({ where: [] }, templateSrv); let query = new PostgresQuery({ where: [] }, templateSrv);
@ -95,18 +126,17 @@ describe('PostgresQuery', function() {
describe('When generating complete statement', function() { describe('When generating complete statement', function() {
let target = { let target = {
timeColumn: 't', timeColumn: 't',
schema: 'public',
table: 'table', table: 'table',
select: [[{ type: 'column', params: ['value'] }]], select: [[{ type: 'column', params: ['value'] }]],
where: [], where: [],
}; };
let result = 'SELECT\n t AS "time",\n value\nFROM public.table\nORDER BY 1'; let result = 'SELECT\n t AS "time",\n value\nFROM table\nORDER BY 1';
let query = new PostgresQuery(target, templateSrv); let query = new PostgresQuery(target, templateSrv);
expect(query.buildQuery()).toBe(result); expect(query.buildQuery()).toBe(result);
query.target.metricColumn = 'm'; query.target.metricColumn = 'm';
result = 'SELECT\n t AS "time",\n m AS metric,\n value\nFROM public.table\nORDER BY 1'; result = 'SELECT\n t AS "time",\n m AS metric,\n value\nFROM table\nORDER BY 1';
expect(query.buildQuery()).toBe(result); expect(query.buildQuery()).toBe(result);
}); });
}); });