mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
InfluxDB SQL: Provide raw query preview for query history (#75030)
* log the sql query * render the raw sql * Update rawQuery * unit tests
This commit is contained in:
@@ -50,6 +50,7 @@ func Query(ctx context.Context, dsInfo *models.DatasourceInfo, req backend.Query
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Info(fmt.Sprintf("InfluxDB executing SQL: %s", qm.RawSQL))
|
||||||
info, err := r.client.Execute(ctx, qm.RawSQL)
|
info, err := r.client.Execute(ctx, qm.RawSQL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tRes.Responses[q.RefID] = backend.ErrDataResponse(backend.StatusInternal, fmt.Sprintf("flightsql: %s", err))
|
tRes.Responses[q.RefID] = backend.ErrDataResponse(backend.StatusInternal, fmt.Sprintf("flightsql: %s", err))
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_sr
|
|||||||
import { AnnotationEditor } from './components/editor/annotation/AnnotationEditor';
|
import { AnnotationEditor } from './components/editor/annotation/AnnotationEditor';
|
||||||
import { FluxQueryEditor } from './components/editor/query/flux/FluxQueryEditor';
|
import { FluxQueryEditor } from './components/editor/query/flux/FluxQueryEditor';
|
||||||
import { BROWSER_MODE_DISABLED_MESSAGE } from './constants';
|
import { BROWSER_MODE_DISABLED_MESSAGE } from './constants';
|
||||||
|
import { toRawSql } from './fsql/sqlUtil';
|
||||||
import InfluxQueryModel from './influx_query_model';
|
import InfluxQueryModel from './influx_query_model';
|
||||||
import InfluxSeries from './influx_series';
|
import InfluxSeries from './influx_series';
|
||||||
import { buildMetadataQuery } from './influxql_query_builder';
|
import { buildMetadataQuery } from './influxql_query_builder';
|
||||||
@@ -185,10 +186,16 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
|
|||||||
}
|
}
|
||||||
|
|
||||||
getQueryDisplayText(query: InfluxQuery) {
|
getQueryDisplayText(query: InfluxQuery) {
|
||||||
if (this.version === InfluxVersion.Flux) {
|
switch (this.version) {
|
||||||
return query.query;
|
case InfluxVersion.Flux:
|
||||||
|
return query.query;
|
||||||
|
case InfluxVersion.SQL:
|
||||||
|
return toRawSql(query);
|
||||||
|
case InfluxVersion.InfluxQL:
|
||||||
|
return new InfluxQueryModel(query).render(false);
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
return new InfluxQueryModel(query).render(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
32
public/app/plugins/datasource/influxdb/fsql/sqlUtil.test.ts
Normal file
32
public/app/plugins/datasource/influxdb/fsql/sqlUtil.test.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { SQLQuery } from 'app/features/plugins/sql/types';
|
||||||
|
|
||||||
|
import { QueryEditorExpressionType } from '../../../../features/plugins/sql/expressions';
|
||||||
|
|
||||||
|
import { toRawSql } from './sqlUtil';
|
||||||
|
|
||||||
|
describe('toRawSql', () => {
|
||||||
|
it('should render sql properly', () => {
|
||||||
|
const expected = 'SELECT host FROM iox.value1 LIMIT 50';
|
||||||
|
const testQuery: SQLQuery = {
|
||||||
|
refId: 'A',
|
||||||
|
sql: {
|
||||||
|
limit: 50,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
parameters: [
|
||||||
|
{
|
||||||
|
name: 'host',
|
||||||
|
type: QueryEditorExpressionType.FunctionParameter,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
type: QueryEditorExpressionType.Function,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
dataset: 'iox',
|
||||||
|
table: 'value1',
|
||||||
|
};
|
||||||
|
const result = toRawSql(testQuery);
|
||||||
|
expect(result).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
45
public/app/plugins/datasource/influxdb/fsql/sqlUtil.ts
Normal file
45
public/app/plugins/datasource/influxdb/fsql/sqlUtil.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
|
import { SQLQuery } from 'app/features/plugins/sql/types';
|
||||||
|
import { createSelectClause, haveColumns } from 'app/features/plugins/sql/utils/sql.utils';
|
||||||
|
|
||||||
|
export function toRawSql({ sql, dataset, table }: SQLQuery): string {
|
||||||
|
let rawQuery = '';
|
||||||
|
|
||||||
|
// Return early with empty string if there is no sql column
|
||||||
|
if (!sql || !haveColumns(sql.columns)) {
|
||||||
|
return rawQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
rawQuery += createSelectClause(sql.columns);
|
||||||
|
|
||||||
|
if (dataset && table) {
|
||||||
|
rawQuery += `FROM ${dataset}.${table} `;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sql.whereString) {
|
||||||
|
rawQuery += `WHERE ${sql.whereString} `;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sql.groupBy?.[0]?.property.name) {
|
||||||
|
const groupBy = sql.groupBy.map((g) => g.property.name).filter((g) => !isEmpty(g));
|
||||||
|
rawQuery += `GROUP BY ${groupBy.join(', ')} `;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sql.orderBy?.property.name) {
|
||||||
|
rawQuery += `ORDER BY ${sql.orderBy.property.name} `;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sql.orderBy?.property.name && sql.orderByDirection) {
|
||||||
|
rawQuery += `${sql.orderByDirection} `;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Although LIMIT 0 doesn't make sense, it is still possible to have LIMIT 0
|
||||||
|
if (isLimit(sql.limit)) {
|
||||||
|
rawQuery += `LIMIT ${sql.limit}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isLimit = (limit: number | undefined): boolean => limit !== undefined && limit >= 0;
|
||||||
Reference in New Issue
Block a user