Chore: Remove `sqlQuerybuilderFunctionParameters` feature toggle (#100809)

* chore: remove `sqlQuerybuilderFunctionParameters` ff

* Update packages/grafana-sql/src/components/visual-query-builder/SelectRow.tsx

Co-authored-by: ismail simsek <ismailsimsek09@gmail.com>

---------

Co-authored-by: ismail simsek <ismailsimsek09@gmail.com>
pull/100972/head
Zoltán Bedi 4 months ago committed by GitHub
parent a24fd1b722
commit 5a7916133e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md
  2. 2
      docs/sources/shared/datasources/sql-query-builder-macros.md
  3. 2
      e2e/plugin-e2e/mysql/visual-query-builder.spec.ts
  4. 1
      packages/grafana-data/src/types/featureToggles.gen.ts
  5. 10
      packages/grafana-sql/src/components/visual-query-builder/SelectRow.test.tsx
  6. 61
      packages/grafana-sql/src/components/visual-query-builder/SelectRow.tsx
  7. 7
      pkg/services/featuremgmt/registry.go
  8. 1
      pkg/services/featuremgmt/toggles_gen.csv
  9. 4
      pkg/services/featuremgmt/toggles_gen.go
  10. 3
      pkg/services/featuremgmt/toggles_gen.json
  11. 20
      public/app/plugins/datasource/grafana-postgresql-datasource/datasource.ts
  12. 56
      public/app/plugins/datasource/influxdb/fsql/datasource.flightsql.ts
  13. 18
      public/app/plugins/datasource/mssql/datasource.ts
  14. 20
      public/app/plugins/datasource/mysql/MySqlDatasource.ts

@ -197,7 +197,6 @@ Experimental features might be changed or removed without prior notice.
| `alertingListViewV2` | Enables the new alert list view design |
| `dashboardRestore` | Enables deleted dashboard restore feature |
| `alertingCentralAlertHistory` | Enables the new central alert history. |
| `sqlQuerybuilderFunctionParameters` | Enables SQL query builder function parameters |
| `failWrongDSUID` | Throws an error if a datasource has an invalid UIDs |
| `dataplaneAggregator` | Enable grafana dataplane aggregator |
| `lokiSendDashboardPanelNames` | Send dashboard and panel names to Loki when querying |

@ -10,8 +10,6 @@ labels:
You can enable macros support in the select clause to create time-series queries.
{{< docs/experimental product="Macros support in visual query builder" featureFlag="`sqlQuerybuilderFunctionParameters`" >}}
Use the **Data operations** drop-down to select a macro like `$__timeGroup` or `$__timeGroupAlias`.
Select a time column from the **Column** drop-down and a time interval from the **Interval** drop-down to create a time-series query.

@ -6,8 +6,6 @@ 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();

@ -180,7 +180,6 @@ export interface FeatureToggles {
preserveDashboardStateWhenNavigating?: boolean;
alertingCentralAlertHistory?: boolean;
pluginProxyPreserveTrailingSlash?: boolean;
sqlQuerybuilderFunctionParameters?: boolean;
azureMonitorPrometheusExemplars?: boolean;
pinNavItems?: boolean;
authZGRPCServer?: boolean;

@ -10,16 +10,6 @@ import { buildMockDB } from '../SqlComponents.testHelpers';
import { SelectRow } from './SelectRow';
// Mock featureToggle sqlQuerybuilderFunctionParameters
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
config: {
featureToggles: {
sqlQuerybuilderFunctionParameters: true,
},
},
}));
describe('SelectRow', () => {
const query = Object.freeze<SQLQuery>({
refId: 'A',

@ -5,7 +5,6 @@ import { useCallback } from 'react';
import { SelectableValue, toOption } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { EditorField } from '@grafana/plugin-ui';
import { config } from '@grafana/runtime';
import { Button, Select, Stack, useStyles2 } from '@grafana/ui';
import { QueryEditorExpressionType, QueryEditorFunctionExpression } from '../../expressions';
@ -13,7 +12,6 @@ import { DB, QueryFormat, SQLExpression, SQLQuery } from '../../types';
import { createFunctionField } from '../../utils/sql.utils';
import { useSqlChange } from '../../utils/useSqlChange';
import { SelectColumn } from './SelectColumn';
import { SelectFunctionParameters } from './SelectFunctionParameters';
interface SelectRowProps {
@ -35,27 +33,6 @@ export function SelectRow({ query, onQueryChange, db, columns }: SelectRowProps)
timeSeriesAliasOpts.push({ label: 'value', value: 'value' });
}
const onColumnChange = useCallback(
(item: QueryEditorFunctionExpression, index: number) => (column?: string) => {
let modifiedItem = { ...item };
if (!item.parameters?.length) {
modifiedItem.parameters = [{ type: QueryEditorExpressionType.FunctionParameter, name: column } as const];
} else {
modifiedItem.parameters = item.parameters.map((p) =>
p.type === QueryEditorExpressionType.FunctionParameter ? { ...p, name: column } : p
);
}
const newSql: SQLExpression = {
...query.sql,
columns: query.sql?.columns?.map((c, i) => (i === index ? modifiedItem : c)),
};
onSqlChange(newSql);
},
[onSqlChange, query.sql]
);
const onAggregationChange = useCallback(
(item: QueryEditorFunctionExpression, index: number) => (aggregation: SelectableValue<string>) => {
const newItem = {
@ -134,18 +111,7 @@ export function SelectRow({ query, onQueryChange, db, columns }: SelectRowProps)
{query.sql?.columns?.map((item, index) => (
<div key={index}>
<Stack gap={2} alignItems="end">
{!config.featureToggles.sqlQuerybuilderFunctionParameters && (
<SelectColumn
columns={columns}
onParameterChange={(v) => onColumnChange(item, index)(v)}
value={getColumnValue(item)}
/>
)}
<EditorField
label={config.featureToggles.sqlQuerybuilderFunctionParameters ? 'Data operations' : 'Aggregation'}
optional
width={25}
>
<EditorField label="Data operations" optional width={25}>
<Select
value={item.name ? toOption(item.name) : null}
inputId={`select-aggregation-${index}-${uniqueId()}`}
@ -157,15 +123,14 @@ export function SelectRow({ query, onQueryChange, db, columns }: SelectRowProps)
onChange={onAggregationChange(item, index)}
/>
</EditorField>
{config.featureToggles.sqlQuerybuilderFunctionParameters && (
<SelectFunctionParameters
currentColumnIndex={index}
columns={columns}
onSqlChange={onSqlChange}
query={query}
db={db}
/>
)}
<SelectFunctionParameters
currentColumnIndex={index}
columns={columns}
onSqlChange={onSqlChange}
query={query}
db={db}
/>
<EditorField label="Alias" optional width={15}>
<Select
@ -213,11 +178,3 @@ const getStyles = () => {
}),
};
};
function getColumnValue({ parameters }: QueryEditorFunctionExpression): SelectableValue<string> | null {
const column = parameters?.find((p) => p.type === QueryEditorExpressionType.FunctionParameter);
if (column?.name) {
return toOption(column.name);
}
return null;
}

@ -1233,13 +1233,6 @@ var (
Owner: grafanaPluginsPlatformSquad,
Expression: "false", // disabled by default
},
{
Name: "sqlQuerybuilderFunctionParameters",
Description: "Enables SQL query builder function parameters",
Stage: FeatureStageExperimental,
Owner: grafanaOSSBigTent,
FrontendOnly: true,
},
{
Name: "azureMonitorPrometheusExemplars",
Description: "Allows configuration of Azure Monitor as a data source that can provide Prometheus exemplars",

@ -161,7 +161,6 @@ alertingDisableSendAlertsExternal,experimental,@grafana/alerting-squad,false,fal
preserveDashboardStateWhenNavigating,experimental,@grafana/dashboards-squad,false,false,false
alertingCentralAlertHistory,experimental,@grafana/alerting-squad,false,false,true
pluginProxyPreserveTrailingSlash,GA,@grafana/plugins-platform-backend,false,false,false
sqlQuerybuilderFunctionParameters,experimental,@grafana/oss-big-tent,false,false,true
azureMonitorPrometheusExemplars,preview,@grafana/partner-datasources,false,false,false
pinNavItems,GA,@grafana/grafana-frontend-platform,false,false,false
authZGRPCServer,experimental,@grafana/identity-access-team,false,false,false

1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
161 preserveDashboardStateWhenNavigating experimental @grafana/dashboards-squad false false false
162 alertingCentralAlertHistory experimental @grafana/alerting-squad false false true
163 pluginProxyPreserveTrailingSlash GA @grafana/plugins-platform-backend false false false
sqlQuerybuilderFunctionParameters experimental @grafana/oss-big-tent false false true
164 azureMonitorPrometheusExemplars preview @grafana/partner-datasources false false false
165 pinNavItems GA @grafana/grafana-frontend-platform false false false
166 authZGRPCServer experimental @grafana/identity-access-team false false false

@ -655,10 +655,6 @@ const (
// Preserve plugin proxy trailing slash.
FlagPluginProxyPreserveTrailingSlash = "pluginProxyPreserveTrailingSlash"
// FlagSqlQuerybuilderFunctionParameters
// Enables SQL query builder function parameters
FlagSqlQuerybuilderFunctionParameters = "sqlQuerybuilderFunctionParameters"
// FlagAzureMonitorPrometheusExemplars
// Allows configuration of Azure Monitor as a data source that can provide Prometheus exemplars
FlagAzureMonitorPrometheusExemplars = "azureMonitorPrometheusExemplars"

@ -3730,7 +3730,8 @@
"metadata": {
"name": "sqlQuerybuilderFunctionParameters",
"resourceVersion": "1718487716739",
"creationTimestamp": "2024-11-04T16:13:35Z"
"creationTimestamp": "2024-11-04T16:13:35Z",
"deletionTimestamp": "2025-01-31T10:58:09Z"
},
"spec": {
"description": "Enables SQL query builder function parameters",

@ -2,7 +2,7 @@ import { v4 as uuidv4 } from 'uuid';
import { DataSourceInstanceSettings, ScopedVars } from '@grafana/data';
import { LanguageDefinition } from '@grafana/plugin-ui';
import { TemplateSrv, config } from '@grafana/runtime';
import { TemplateSrv } from '@grafana/runtime';
import {
COMMON_FNS,
DB,
@ -94,17 +94,13 @@ export class PostgresDatasource extends SqlDatasource {
}
getFunctions = (): ReturnType<DB['functions']> => {
if (config.featureToggles.sqlQuerybuilderFunctionParameters) {
const columnParam: FuncParameter = {
name: 'Column',
required: true,
options: (query) => this.fetchFields(query),
};
return [...MACRO_FUNCTIONS(columnParam), ...COMMON_FNS.map((fn) => ({ ...fn, parameters: [columnParam] }))];
} else {
return COMMON_FNS;
}
const columnParam: FuncParameter = {
name: 'Column',
required: true,
options: (query) => this.fetchFields(query),
};
return [...MACRO_FUNCTIONS(columnParam), ...COMMON_FNS.map((fn) => ({ ...fn, parameters: [columnParam] }))];
};
getDB(): DB {

@ -2,7 +2,7 @@ import { v4 as uuidv4 } from 'uuid';
import { DataSourceInstanceSettings, TimeRange } from '@grafana/data';
import { CompletionItemKind, LanguageDefinition, TableIdentifier } from '@grafana/plugin-ui';
import { TemplateSrv, config, getTemplateSrv } from '@grafana/runtime';
import { TemplateSrv, getTemplateSrv } from '@grafana/runtime';
import { COMMON_FNS, DB, FuncParameter, SQLQuery, SqlDatasource, formatSQL } from '@grafana/sql';
import { mapFieldsToTypes } from './fields';
@ -106,36 +106,32 @@ export class FlightSQLDatasource extends SqlDatasource {
getFunctions = (): ReturnType<DB['functions']> => {
const fns = [...COMMON_FNS, { name: 'VARIANCE' }, { name: 'STDDEV' }];
if (config.featureToggles.sqlQuerybuilderFunctionParameters) {
const columnParam: FuncParameter = {
name: 'Column',
required: true,
options: (query) => this.fetchFields(query),
};
const intervalParam: FuncParameter = {
name: 'Interval',
required: true,
options: () => {
return Promise.resolve([{ label: '$__interval', value: '$__interval' }]);
},
};
const columnParam: FuncParameter = {
name: 'Column',
required: true,
options: (query) => this.fetchFields(query),
};
const intervalParam: FuncParameter = {
name: 'Interval',
required: true,
options: () => {
return Promise.resolve([{ label: '$__interval', value: '$__interval' }]);
},
};
return [
...fns.map((fn) => ({ ...fn, parameters: [columnParam] })),
{
name: '$__timeGroup',
description: 'Time grouping function',
parameters: [columnParam, intervalParam],
},
{
name: '$__timeGroupAlias',
description: 'Time grouping function with time as alias',
parameters: [columnParam, intervalParam],
},
];
} else {
return fns;
}
return [
...fns.map((fn) => ({ ...fn, parameters: [columnParam] })),
{
name: '$__timeGroup',
description: 'Time grouping function',
parameters: [columnParam, intervalParam],
},
{
name: '$__timeGroupAlias',
description: 'Time grouping function with time as alias',
parameters: [columnParam, intervalParam],
},
];
};
getDB(): DB {

@ -2,7 +2,7 @@ import { v4 as uuidv4 } from 'uuid';
import { DataSourceInstanceSettings, ScopedVars } from '@grafana/data';
import { LanguageDefinition } from '@grafana/plugin-ui';
import { TemplateSrv, config } from '@grafana/runtime';
import { TemplateSrv } from '@grafana/runtime';
import {
COMMON_FNS,
DB,
@ -75,17 +75,13 @@ export class MssqlDatasource extends SqlDatasource {
}
getFunctions = (): ReturnType<DB['functions']> => {
if (config.featureToggles.sqlQuerybuilderFunctionParameters) {
const columnParam: FuncParameter = {
name: 'Column',
required: true,
options: (query) => this.fetchFields(query),
};
const columnParam: FuncParameter = {
name: 'Column',
required: true,
options: (query) => this.fetchFields(query),
};
return [...MACRO_FUNCTIONS(columnParam), ...COMMON_FNS.map((fn) => ({ ...fn, parameters: [columnParam] }))];
} else {
return COMMON_FNS;
}
return [...MACRO_FUNCTIONS(columnParam), ...COMMON_FNS.map((fn) => ({ ...fn, parameters: [columnParam] }))];
};
getDB(): DB {

@ -2,7 +2,6 @@ import { v4 as uuidv4 } from 'uuid';
import { DataSourceInstanceSettings, TimeRange } from '@grafana/data';
import { CompletionItemKind, LanguageDefinition, TableIdentifier } from '@grafana/plugin-ui';
import { config } from '@grafana/runtime';
import { COMMON_FNS, DB, FuncParameter, MACRO_FUNCTIONS, SQLQuery, SqlDatasource, formatSQL } from '@grafana/sql';
import { mapFieldsToTypes } from './fields';
@ -89,17 +88,14 @@ export class MySqlDatasource extends SqlDatasource {
getFunctions = (): ReturnType<DB['functions']> => {
const fns = [...COMMON_FNS, { name: 'VARIANCE' }, { name: 'STDDEV' }];
if (config.featureToggles.sqlQuerybuilderFunctionParameters) {
const columnParam: FuncParameter = {
name: 'Column',
required: true,
options: (query) => this.fetchFields(query),
};
return [...MACRO_FUNCTIONS(columnParam), ...fns.map((fn) => ({ ...fn, parameters: [columnParam] }))];
} else {
return fns;
}
const columnParam: FuncParameter = {
name: 'Column',
required: true,
options: (query) => this.fetchFields(query),
};
return [...MACRO_FUNCTIONS(columnParam), ...fns.map((fn) => ({ ...fn, parameters: [columnParam] }))];
};
getDB(): DB {

Loading…
Cancel
Save