Commit e4672906 by Torkel Ödegaard Committed by GitHub

SqlDataSources: Fixes the Show Generated SQL button in query editors (#31236)

* SqlDataSources: Fixes the Show Generated SQL button in query editors

* No need to protect against duplicate events now that the event emitter is isolated for each editor
parent 06e6bcf0
......@@ -126,14 +126,16 @@ export class QueryEditorRow extends PureComponent<Props, State> {
const { data, query } = this.props;
if (data !== prevProps.data) {
this.setState({ data: filterPanelDataToQuery(data, query.refId) });
const dataFilteredByRefId = filterPanelDataToQuery(data, query.refId);
this.setState({ data: dataFilteredByRefId });
if (this.angularScope) {
this.angularScope.range = getTimeSrv().timeRange();
}
if (this.angularQueryEditor) {
notifyAngularQueryEditorsOfData(this.angularScope!, data, this.angularQueryEditor);
if (this.angularQueryEditor && dataFilteredByRefId) {
notifyAngularQueryEditorsOfData(this.angularScope!, dataFilteredByRefId, this.angularQueryEditor);
}
}
......@@ -353,17 +355,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
}
}
// To avoid sending duplicate events for each row we have this global cached object here
// So we can check if we already emitted this legacy data event
let globalLastPanelDataCache: PanelData | null = null;
function notifyAngularQueryEditorsOfData(scope: AngularQueryComponentScope, data: PanelData, editor: AngularComponent) {
if (data === globalLastPanelDataCache) {
return;
}
globalLastPanelDataCache = data;
if (data.state === LoadingState.Done) {
const legacy = data.series.map((v) => toLegacyResponseData(v));
scope.events.emit(PanelEvents.dataReceived, legacy);
......
......@@ -20,12 +20,13 @@
<icon name="'angle-right'" ng-hide="ctrl.showHelp" style="margin-top: 3px;"></icon>
</label>
</div>
<div class="gf-form">
<label class="gf-form-label query-keyword" ng-click="ctrl.showQueryInspector()">
<div class="gf-form" ng-show="ctrl.lastQueryMeta">
<label class="gf-form-label query-keyword pointer" ng-click="ctrl.showLastQuerySQL = !ctrl.showLastQuerySQL">
Generated SQL
<icon name="'angle-right'" style="margin-top: 3px;"></icon>
<icon name="'angle-down'" ng-show="ctrl.showLastQuerySQL" style="margin-top: 3px;"></icon>
<icon name="'angle-right'" ng-hide="ctrl.showLastQuerySQL" style="margin-top: 3px;"></icon>
</label>
</div>
</div>
<div class="gf-form gf-form--grow">
<div class="gf-form-label gf-form-label--grow"></div>
</div>
......@@ -78,6 +79,10 @@ Or build your own conditionals using these macros which just return the values:
</div>
<div class="gf-form" ng-show="ctrl.showLastQuerySQL">
<pre class="gf-form-pre">{{ctrl.lastQueryMeta.executedQueryString}}</pre>
</div>
<div class="gf-form" ng-show="ctrl.lastQueryError">
<pre class="gf-form-pre alert alert-error">{{ctrl.lastQueryError}}</pre>
</div>
......
import _ from 'lodash';
import { QueryCtrl } from 'app/plugins/sdk';
import { auto } from 'angular';
import { PanelEvents } from '@grafana/data';
import { getLocationSrv } from '@grafana/runtime';
import { PanelEvents, QueryResultMeta } from '@grafana/data';
export interface MssqlQuery {
refId: string;
......@@ -11,10 +10,6 @@ export interface MssqlQuery {
rawSql: string;
}
export interface QueryMeta {
sql: string;
}
const defaultQuery = `SELECT
$__timeEpoch(<time_column>),
<value column> as value,
......@@ -31,7 +26,8 @@ export class MssqlQueryCtrl extends QueryCtrl {
formats: any[];
target: MssqlQuery;
lastQueryError: string | null;
lastQueryMeta?: QueryResultMeta;
lastQueryError?: string;
showHelp: boolean;
/** @ngInject */
......@@ -59,15 +55,9 @@ export class MssqlQueryCtrl extends QueryCtrl {
this.panelCtrl.events.on(PanelEvents.dataError, this.onDataError.bind(this), $scope);
}
showQueryInspector() {
getLocationSrv().update({
query: { inspect: this.panel.id, inspectTab: 'query' },
partial: true,
});
}
onDataReceived(dataList: any) {
this.lastQueryError = null;
this.lastQueryError = undefined;
this.lastQueryMeta = dataList[0]?.meta;
}
onDataError(err: any) {
......
......@@ -120,10 +120,11 @@
<icon name="'angle-right'" ng-hide="ctrl.showHelp" style="margin-top: 3px;"></icon>
</label>
</div>
<div class="gf-form">
<label class="gf-form-label query-keyword pointer" ng-click="ctrl.showQueryInspector()">
<div class="gf-form" ng-show="ctrl.lastQueryMeta">
<label class="gf-form-label query-keyword pointer" ng-click="ctrl.showLastQuerySQL = !ctrl.showLastQuerySQL">
Generated SQL
<icon name="'angle-right'" style="margin-top: 3px;"></icon>
<icon name="'angle-down'" ng-show="ctrl.showLastQuerySQL" style="margin-top: 3px;"></icon>
<icon name="'angle-right'" ng-hide="ctrl.showLastQuerySQL" style="margin-top: 3px;"></icon>
</label>
</div>
<div class="gf-form gf-form--grow">
......@@ -178,6 +179,10 @@ Or build your own conditionals using these macros which just return the values:
</div>
<div class="gf-form" ng-show="ctrl.showLastQuerySQL">
<pre class="gf-form-pre">{{ctrl.lastQueryMeta.executedQueryString}}</pre>
</div>
<div class="gf-form" ng-show="ctrl.lastQueryError">
<pre class="gf-form-pre alert alert-error">{{ctrl.lastQueryError}}</pre>
</div>
......
......@@ -7,13 +7,9 @@ import MysqlQuery from './mysql_query';
import sqlPart from './sql_part';
import { auto } from 'angular';
import { CoreEvents } from 'app/types';
import { PanelEvents } from '@grafana/data';
import { PanelEvents, QueryResultMeta } from '@grafana/data';
import { VariableWithMultiSupport } from 'app/features/variables/types';
import { getLocationSrv, TemplateSrv } from '@grafana/runtime';
export interface QueryMeta {
sql: string;
}
import { TemplateSrv } from '@grafana/runtime';
const defaultQuery = `SELECT
UNIX_TIMESTAMP(<time_column>) as time_sec,
......@@ -28,11 +24,12 @@ export class MysqlQueryCtrl extends QueryCtrl {
static templateUrl = 'partials/query.editor.html';
formats: any[];
lastQueryError: string | null;
lastQueryError?: string;
showHelp: boolean;
queryModel: MysqlQuery;
metaBuilder: MysqlMetaQuery;
lastQueryMeta?: QueryResultMeta;
tableSegment: any;
whereAdd: any;
timeColumnSegment: any;
......@@ -108,13 +105,6 @@ export class MysqlQueryCtrl extends QueryCtrl {
this.panelCtrl.events.on(PanelEvents.dataError, this.onDataError.bind(this), $scope);
}
showQueryInspector() {
getLocationSrv().update({
query: { inspect: this.panel.id, inspectTab: 'query' },
partial: true,
});
}
updateRawSqlAndRefresh() {
if (!this.target.rawQuery) {
this.target.rawSql = this.queryModel.buildQuery();
......@@ -278,7 +268,8 @@ export class MysqlQueryCtrl extends QueryCtrl {
}
onDataReceived(dataList: any) {
this.lastQueryError = null;
this.lastQueryError = undefined;
this.lastQueryMeta = dataList[0]?.meta;
}
onDataError(err: any) {
......
......@@ -120,10 +120,11 @@
<icon name="'angle-right'" ng-hide="ctrl.showHelp" style="margin-top: 3px;"></icon>
</label>
</div>
<div class="gf-form">
<label class="gf-form-label query-keyword pointer" ng-click="ctrl.showQueryInspector()">
<div class="gf-form" ng-show="ctrl.lastQueryMeta">
<label class="gf-form-label query-keyword pointer" ng-click="ctrl.showLastQuerySQL = !ctrl.showLastQuerySQL">
Generated SQL
<icon name="'angle-right'" style="margin-top: 3px;"></icon>
<icon name="'angle-down'" ng-show="ctrl.showLastQuerySQL" style="margin-top: 3px;"></icon>
<icon name="'angle-right'" ng-hide="ctrl.showLastQuerySQL" style="margin-top: 3px;"></icon>
</label>
</div>
<div class="gf-form gf-form--grow">
......@@ -179,6 +180,10 @@ Or build your own conditionals using these macros which just return the values:
</div>
<div class="gf-form" ng-show="ctrl.showLastQuerySQL">
<pre class="gf-form-pre">{{ctrl.lastQueryMeta.executedQueryString}}</pre>
</div>
<div class="gf-form" ng-show="ctrl.lastQueryError">
<pre class="gf-form-pre alert alert-error">{{ctrl.lastQueryError}}</pre>
</div>
......
......@@ -7,13 +7,9 @@ import PostgresQuery from './postgres_query';
import sqlPart from './sql_part';
import { auto } from 'angular';
import { CoreEvents } from 'app/types';
import { PanelEvents } from '@grafana/data';
import { PanelEvents, QueryResultMeta } from '@grafana/data';
import { VariableWithMultiSupport } from 'app/features/variables/types';
import { getLocationSrv, TemplateSrv } from '@grafana/runtime';
export interface QueryMeta {
sql: string;
}
import { TemplateSrv } from '@grafana/runtime';
const defaultQuery = `SELECT
$__time(time_column),
......@@ -30,7 +26,8 @@ export class PostgresQueryCtrl extends QueryCtrl {
formats: any[];
queryModel: PostgresQuery;
metaBuilder: PostgresMetaQuery;
lastQueryError: string | null;
lastQueryMeta?: QueryResultMeta;
lastQueryError?: string;
showHelp: boolean;
tableSegment: any;
whereAdd: any;
......@@ -106,13 +103,6 @@ export class PostgresQueryCtrl extends QueryCtrl {
this.panelCtrl.events.on(PanelEvents.dataError, this.onDataError.bind(this), $scope);
}
showQueryInspector() {
getLocationSrv().update({
query: { inspect: this.panel.id, inspectTab: 'query' },
partial: true,
});
}
updateRawSqlAndRefresh() {
if (!this.target.rawQuery) {
this.target.rawSql = this.queryModel.buildQuery();
......@@ -311,7 +301,8 @@ export class PostgresQueryCtrl extends QueryCtrl {
}
onDataReceived(dataList: any) {
this.lastQueryError = null;
this.lastQueryError = undefined;
this.lastQueryMeta = dataList[0]?.meta;
}
onDataError(err: any) {
......
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