SQL: Add macro support in select case (#88514)
* Feat: timeGroup macro handling in VQB * Add tests * Add functions to SQL ds * Fix lint errors * Add feature toggle * Add rendering based on object * Fix lint * Fix CI failures * Fix tests * Address review comments * Add docs * Fix JSX runtime warnings * Remove docs part that mentions suggest more macros * Update docs/sources/shared/datasources/sql-query-builder-macros.md Co-authored-by: Jack Baldry <jack.baldry@grafana.com> * Add smoke test for this feature * lint * Add supported macros to influx * Add setupTests.ts to include in tsconfig.json * Import jest-dom instead of setupTests.ts --------- Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
This commit is contained in:
co-authored by
Jack Baldry
parent
aacc83be5c
commit
85c696c4ad
@@ -21,14 +21,14 @@ export const tablesResponse = {
|
||||
},
|
||||
};
|
||||
|
||||
export const fieldsResponse = {
|
||||
export const fieldsResponse = (refId: string) => ({
|
||||
results: {
|
||||
fields: {
|
||||
[refId]: {
|
||||
status: 200,
|
||||
frames: [
|
||||
{
|
||||
schema: {
|
||||
refId: 'fields',
|
||||
refId,
|
||||
meta: {
|
||||
executedQueryString:
|
||||
"SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'DataMaker' AND table_name = 'RandomIntsWithTimes' ORDER BY column_name",
|
||||
@@ -48,7 +48,7 @@ export const fieldsResponse = {
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const datasetResponse = {
|
||||
results: {
|
||||
|
||||
@@ -1,29 +1,10 @@
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { expect, test } from '@grafana/plugin-e2e';
|
||||
|
||||
import {
|
||||
tablesResponse,
|
||||
fieldsResponse,
|
||||
datasetResponse,
|
||||
normalTableName,
|
||||
tableNameWithSpecialCharacter,
|
||||
} from './mocks/mysql.mocks';
|
||||
import { normalTableName, tableNameWithSpecialCharacter } from './mocks/mysql.mocks';
|
||||
import { mockDataSourceRequest } from './utils';
|
||||
|
||||
test.beforeEach(async ({ context, selectors, explorePage }) => {
|
||||
await explorePage.datasource.set('gdev-mysql');
|
||||
await context.route(selectors.apis.DataSource.queryPattern, async (route, request) => {
|
||||
switch (request.postDataJSON().queries[0].refId) {
|
||||
case 'tables':
|
||||
return route.fulfill({ json: tablesResponse, status: 200 });
|
||||
case 'fields':
|
||||
return route.fulfill({ json: fieldsResponse, status: 200 });
|
||||
case 'datasets':
|
||||
return route.fulfill({ json: datasetResponse, status: 200 });
|
||||
default:
|
||||
return route.continue();
|
||||
}
|
||||
});
|
||||
});
|
||||
test.beforeEach(mockDataSourceRequest);
|
||||
|
||||
test('code editor autocomplete should handle table name escaping/quoting', async ({ explorePage, selectors, page }) => {
|
||||
await page.getByLabel('Code').check();
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { PlaywrightTestArgs } from '@playwright/test';
|
||||
|
||||
import { PluginFixture } from '@grafana/plugin-e2e';
|
||||
|
||||
import { datasetResponse, fieldsResponse, tablesResponse } from './mocks/mysql.mocks';
|
||||
|
||||
export async function mockDataSourceRequest({ context, explorePage, selectors }: PlaywrightTestArgs & PluginFixture) {
|
||||
await explorePage.datasource.set('gdev-mysql');
|
||||
await context.route(selectors.apis.DataSource.queryPattern, async (route, request) => {
|
||||
const refId = request.postDataJSON().queries[0].refId;
|
||||
if (/fields-.*/g.test(refId)) {
|
||||
return route.fulfill({ json: fieldsResponse(refId), status: 200 });
|
||||
}
|
||||
switch (refId) {
|
||||
case 'tables':
|
||||
return route.fulfill({ json: tablesResponse, status: 200 });
|
||||
case 'datasets':
|
||||
return route.fulfill({ json: datasetResponse, status: 200 });
|
||||
default:
|
||||
return route.continue();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { test, expect } from '@grafana/plugin-e2e';
|
||||
|
||||
import { normalTableName } from './mocks/mysql.mocks';
|
||||
import { mockDataSourceRequest } from './utils';
|
||||
|
||||
test.beforeEach(mockDataSourceRequest);
|
||||
|
||||
test.use({ featureToggles: { sqlQuerybuilderFunctionParameters: true } });
|
||||
|
||||
test('visual query builder should handle macros', async ({ explorePage, page }) => {
|
||||
await explorePage.getByGrafanaSelector(selectors.components.SQLQueryEditor.headerTableSelector).click();
|
||||
await page.getByText(normalTableName, { exact: true }).click();
|
||||
|
||||
// Open Data operations
|
||||
await explorePage.getByGrafanaSelector(selectors.components.SQLQueryEditor.selectAggregation).click();
|
||||
const select = page.getByLabel('Select options menu');
|
||||
await select.locator(page.getByText('$__timeGroupAlias')).click();
|
||||
|
||||
// Open column selector
|
||||
await explorePage.getByGrafanaSelector(selectors.components.SQLQueryEditor.selectFunctionParameter('Column')).click();
|
||||
await select.locator(page.getByText('createdAt')).click();
|
||||
|
||||
// Open Interval selector
|
||||
await explorePage
|
||||
.getByGrafanaSelector(selectors.components.SQLQueryEditor.selectFunctionParameter('Interval'))
|
||||
.click();
|
||||
await select.locator(page.getByText('$__interval')).click();
|
||||
|
||||
await page.getByRole('button', { name: 'Add column' }).click();
|
||||
|
||||
await explorePage.getByGrafanaSelector(selectors.components.SQLQueryEditor.selectAggregation).nth(1).click();
|
||||
await select.locator(page.getByText('AVG')).click();
|
||||
|
||||
await explorePage
|
||||
.getByGrafanaSelector(selectors.components.SQLQueryEditor.selectFunctionParameter('Column'))
|
||||
.nth(1)
|
||||
.click();
|
||||
await select.locator(page.getByText('bigint')).click();
|
||||
|
||||
// Validate the query
|
||||
await expect(
|
||||
explorePage.getByGrafanaSelector(selectors.components.CodeEditor.container).getByRole('textbox')
|
||||
).toHaveValue(
|
||||
`SELECT\n $__timeGroupAlias(createdAt, $__interval),\n AVG(\`bigint\`)\nFROM\n DataMaker.normalTable\nLIMIT\n 50`
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user