Commit 17e99bb3 by Torkel Ödegaard

Merge branch 'master' of github.com:grafana/grafana

parents 34567bc4 7e0637aa
...@@ -177,7 +177,8 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> { ...@@ -177,7 +177,8 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
for (const panel of this.dashboard.panels) { for (const panel of this.dashboard.panels) {
const panelClasses = classNames({ panel: true, 'panel--fullscreen': panel.fullscreen }); const panelClasses = classNames({ panel: true, 'panel--fullscreen': panel.fullscreen });
panelElements.push( panelElements.push(
<div key={panel.id.toString()} className={panelClasses}> /** panel-id is set for html bookmarks */
<div key={panel.id.toString()} className={panelClasses} id={`panel-${panel.id.toString()}`}>
<DashboardPanel panel={panel} getPanelContainer={this.props.getPanelContainer} /> <DashboardPanel panel={panel} getPanelContainer={this.props.getPanelContainer} />
</div> </div>
); );
......
...@@ -44,15 +44,15 @@ export default class PostgresQuery { ...@@ -44,15 +44,15 @@ export default class PostgresQuery {
} }
quoteIdentifier(value) { quoteIdentifier(value) {
return '"' + value.replace(/"/g, '""') + '"'; return '"' + String(value).replace(/"/g, '""') + '"';
} }
quoteLiteral(value) { quoteLiteral(value) {
return "'" + value.replace(/'/g, "''") + "'"; return "'" + String(value).replace(/'/g, "''") + "'";
} }
escapeLiteral(value) { escapeLiteral(value) {
return value.replace(/'/g, "''"); return String(value).replace(/'/g, "''");
} }
hasTimeGroup() { hasTimeGroup() {
...@@ -187,7 +187,8 @@ export default class PostgresQuery { ...@@ -187,7 +187,8 @@ export default class PostgresQuery {
case 'increase': case 'increase':
curr = query; curr = query;
prev = 'lag(' + curr + ') OVER (' + over + ')'; prev = 'lag(' + curr + ') OVER (' + over + ')';
query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)'; query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev;
query += ' WHEN ' + prev + ' IS NULL THEN NULL ELSE ' + curr + ' END)';
break; break;
case 'rate': case 'rate':
let timeColumn = this.target.timeColumn; let timeColumn = this.target.timeColumn;
...@@ -197,7 +198,8 @@ export default class PostgresQuery { ...@@ -197,7 +198,8 @@ export default class PostgresQuery {
curr = query; curr = query;
prev = 'lag(' + curr + ') OVER (' + over + ')'; prev = 'lag(' + curr + ') OVER (' + over + ')';
query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)'; query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev;
query += ' WHEN ' + prev + ' IS NULL THEN NULL ELSE ' + curr + ' END)';
query += '/extract(epoch from ' + timeColumn + ' - lag(' + timeColumn + ') OVER (' + over + '))'; query += '/extract(epoch from ' + timeColumn + ' - lag(' + timeColumn + ') OVER (' + over + '))';
break; break;
default: default:
...@@ -279,6 +281,9 @@ export default class PostgresQuery { ...@@ -279,6 +281,9 @@ export default class PostgresQuery {
query += this.buildGroupClause(); query += this.buildGroupClause();
query += '\nORDER BY 1'; query += '\nORDER BY 1';
if (this.hasMetricColumn()) {
query += ',2';
}
return query; return query;
} }
......
...@@ -72,7 +72,9 @@ describe('PostgresQuery', () => { ...@@ -72,7 +72,9 @@ describe('PostgresQuery', () => {
{ type: 'window', params: ['increase'] }, { type: 'window', params: ['increase'] },
]; ];
expect(query.buildValueColumn(column)).toBe( expect(query.buildValueColumn(column)).toBe(
'(CASE WHEN v >= lag(v) OVER (ORDER BY time) THEN v - lag(v) OVER (ORDER BY time) ELSE v END) AS "a"' '(CASE WHEN v >= lag(v) OVER (ORDER BY time) ' +
'THEN v - lag(v) OVER (ORDER BY time) ' +
'WHEN lag(v) OVER (ORDER BY time) IS NULL THEN NULL ELSE v END) AS "a"'
); );
}); });
...@@ -96,7 +98,9 @@ describe('PostgresQuery', () => { ...@@ -96,7 +98,9 @@ describe('PostgresQuery', () => {
{ type: 'window', params: ['increase'] }, { type: 'window', params: ['increase'] },
]; ];
expect(query.buildValueColumn(column)).toBe( expect(query.buildValueColumn(column)).toBe(
'(CASE WHEN v >= lag(v) OVER (PARTITION BY host ORDER BY time) THEN v - lag(v) OVER (PARTITION BY host ORDER BY time) ELSE v END) AS "a"' '(CASE WHEN v >= lag(v) OVER (PARTITION BY host ORDER BY time) ' +
'THEN v - lag(v) OVER (PARTITION BY host ORDER BY time) ' +
'WHEN lag(v) OVER (PARTITION BY host ORDER BY time) IS NULL THEN NULL ELSE v END) AS "a"'
); );
column = [ column = [
{ type: 'column', params: ['v'] }, { type: 'column', params: ['v'] },
...@@ -106,7 +110,8 @@ describe('PostgresQuery', () => { ...@@ -106,7 +110,8 @@ describe('PostgresQuery', () => {
]; ];
expect(query.buildValueColumn(column)).toBe( expect(query.buildValueColumn(column)).toBe(
'(CASE WHEN max(v) >= lag(max(v)) OVER (PARTITION BY host ORDER BY time) ' + '(CASE WHEN max(v) >= lag(max(v)) OVER (PARTITION BY host ORDER BY time) ' +
'THEN max(v) - lag(max(v)) OVER (PARTITION BY host ORDER BY time) ELSE max(v) END) AS "a"' 'THEN max(v) - lag(max(v)) OVER (PARTITION BY host ORDER BY time) ' +
'WHEN lag(max(v)) OVER (PARTITION BY host ORDER BY time) IS NULL THEN NULL ELSE max(v) END) AS "a"'
); );
}); });
...@@ -149,7 +154,7 @@ describe('PostgresQuery', () => { ...@@ -149,7 +154,7 @@ describe('PostgresQuery', () => {
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 table\nORDER BY 1'; result = 'SELECT\n t AS "time",\n m AS metric,\n value\nFROM table\nORDER BY 1,2';
expect(query.buildQuery()).toBe(result); expect(query.buildQuery()).toBe(result);
}); });
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment