From 8ce8c1635fc5822faed1fbae67ee0f6671c225eb Mon Sep 17 00:00:00 2001 From: beejeebus Date: Thu, 30 Jan 2025 15:36:45 -0500 Subject: [PATCH] Escape database names in MSSQL datasource (#99754) Valid MSSQL database names can contain characters like `-`, which need to be escaped when used in queries. This PR wraps database names in `[]`, and fixes Grafana issue #58757. --- .../datasource/mssql/MSSqlMetaQuery.test.ts | 10 ++++++++++ .../plugins/datasource/mssql/MSSqlMetaQuery.ts | 2 +- .../plugins/datasource/mssql/sqlUtil.test.ts | 18 ++++++++++++++++++ public/app/plugins/datasource/mssql/sqlUtil.ts | 2 +- 4 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 public/app/plugins/datasource/mssql/MSSqlMetaQuery.test.ts create mode 100644 public/app/plugins/datasource/mssql/sqlUtil.test.ts diff --git a/public/app/plugins/datasource/mssql/MSSqlMetaQuery.test.ts b/public/app/plugins/datasource/mssql/MSSqlMetaQuery.test.ts new file mode 100644 index 00000000000..b479a7dc629 --- /dev/null +++ b/public/app/plugins/datasource/mssql/MSSqlMetaQuery.test.ts @@ -0,0 +1,10 @@ +import { getSchema } from './MSSqlMetaQuery'; + +describe('getSchema', () => { + const database = 'foo'; + const table = 'bar'; + const schema = getSchema(database, table); + it('should escapte database names', () => { + expect(schema).toContain(`USE [${database}]`); + }); +}); diff --git a/public/app/plugins/datasource/mssql/MSSqlMetaQuery.ts b/public/app/plugins/datasource/mssql/MSSqlMetaQuery.ts index 070be7252c8..fca04eae97a 100644 --- a/public/app/plugins/datasource/mssql/MSSqlMetaQuery.ts +++ b/public/app/plugins/datasource/mssql/MSSqlMetaQuery.ts @@ -10,7 +10,7 @@ export function getSchemaAndName(database?: string) { export function getSchema(database?: string, table?: string) { return ` - USE ${database} + USE [${database}] SELECT COLUMN_NAME as 'column',DATA_TYPE as 'type' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='${table}';`; } diff --git a/public/app/plugins/datasource/mssql/sqlUtil.test.ts b/public/app/plugins/datasource/mssql/sqlUtil.test.ts new file mode 100644 index 00000000000..807615a9d1c --- /dev/null +++ b/public/app/plugins/datasource/mssql/sqlUtil.test.ts @@ -0,0 +1,18 @@ +import { SQLQuery, QueryEditorExpressionType } from '@grafana/sql'; + +import { toRawSql } from './sqlUtil'; + +describe('toRawSql should escape database names', () => { + const query: SQLQuery = { + dataset: 'foo', + sql: { + columns: [{ name: 'a', alias: 'lol', type: QueryEditorExpressionType.Function }], + }, + refId: 'lolsob', + table: 'table', + }; + const queryString = toRawSql(query); + it('should escapte database names', () => { + expect(queryString).toContain(`FROM [${query.dataset}].${query.table}`); + }); +}); diff --git a/public/app/plugins/datasource/mssql/sqlUtil.ts b/public/app/plugins/datasource/mssql/sqlUtil.ts index ba7347e77ae..92b35a70411 100644 --- a/public/app/plugins/datasource/mssql/sqlUtil.ts +++ b/public/app/plugins/datasource/mssql/sqlUtil.ts @@ -89,7 +89,7 @@ export function toRawSql({ sql, dataset, table }: SQLQuery): string { rawQuery += createSelectClause(sql.columns, sql.limit); if (dataset && table) { - rawQuery += `FROM ${dataset}.${table} `; + rawQuery += `FROM [${dataset}].${table} `; } if (sql.whereString) {