From 37521976438771a7c1eba5d4834c4e7aafdc5a81 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Thu, 20 Oct 2022 08:30:10 +0200 Subject: [PATCH] MSSQL: Support tables from all schemas (#53099) (#57287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 09ab1564807040a7c6df8a45cb0663824f870f6d) Co-authored-by: Zoltán Bedi --- .../datasource/mssql/MSSqlMetaQuery.ts | 12 ++++++---- .../plugins/datasource/mssql/datasource.ts | 23 ++++++++++++------- .../datasource/mssql/sqlCompletionProvider.ts | 13 +++-------- .../app/plugins/datasource/mssql/sqlUtil.ts | 4 +--- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/public/app/plugins/datasource/mssql/MSSqlMetaQuery.ts b/public/app/plugins/datasource/mssql/MSSqlMetaQuery.ts index e39c304c26f..3da2f46a71f 100644 --- a/public/app/plugins/datasource/mssql/MSSqlMetaQuery.ts +++ b/public/app/plugins/datasource/mssql/MSSqlMetaQuery.ts @@ -3,13 +3,15 @@ export function showDatabases() { return `SELECT name FROM sys.databases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb');`; } -export function showTables(dataset?: string) { - return `SELECT TABLE_NAME as name - FROM [${dataset}].INFORMATION_SCHEMA.TABLES +export function getSchemaAndName(database?: string) { + return `SELECT TABLE_SCHEMA + '.' + TABLE_NAME as schemaAndName + FROM [${database}].INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'`; } -export function getSchema(table?: string) { - return `SELECT COLUMN_NAME as 'column',DATA_TYPE as 'type' +export function getSchema(database?: string, table?: string) { + return ` + 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/datasource.ts b/public/app/plugins/datasource/mssql/datasource.ts index 12a99ebd5c3..be16c126c02 100644 --- a/public/app/plugins/datasource/mssql/datasource.ts +++ b/public/app/plugins/datasource/mssql/datasource.ts @@ -10,11 +10,11 @@ import { SQLSelectableValue, } from 'app/features/plugins/sql/types'; -import { getSchema, showDatabases, showTables } from './MSSqlMetaQuery'; +import { getSchema, showDatabases, getSchemaAndName } from './MSSqlMetaQuery'; import { MSSqlQueryModel } from './MSSqlQueryModel'; import { MSSqlResponseParser } from './response_parser'; import { fetchColumns, fetchTables, getSqlCompletionProvider } from './sqlCompletionProvider'; -import { getIcon, getRAQBType, SCHEMA_NAME, toRawSql } from './sqlUtil'; +import { getIcon, getRAQBType, toRawSql } from './sqlUtil'; import { MssqlOptions } from './types'; export class MssqlDatasource extends SqlDatasource { @@ -37,12 +37,19 @@ export class MssqlDatasource extends SqlDatasource { } async fetchTables(dataset?: string): Promise { - const tables = await this.runSql<{ name: string[] }>(showTables(dataset), { refId: 'tables' }); - return tables.fields.name.values.toArray().flat(); + // We get back the table name with the schema as well. like dbo.table + const tables = await this.runSql<{ schemaAndName: string[] }>(getSchemaAndName(dataset), { refId: 'tables' }); + return tables.fields.schemaAndName.values.toArray().flat(); } async fetchFields(query: SQLQuery): Promise { - const schema = await this.runSql<{ column: string; type: string }>(getSchema(query.table), { refId: 'columns' }); + if (!query.table) { + return []; + } + const [_, table] = query.table.split('.'); + const schema = await this.runSql<{ column: string; type: string }>(getSchema(query.dataset, table), { + refId: 'columns', + }); const result: SQLSelectableValue[] = []; for (let i = 0; i < schema.length; i++) { const column = schema.fields.column.values.get(i); @@ -71,7 +78,7 @@ export class MssqlDatasource extends SqlDatasource { tables: (dataset?: string) => this.fetchTables(dataset), getSqlCompletionProvider: () => this.getSqlCompletionProvider(this.db), fields: async (query: SQLQuery) => { - if (!query?.dataset && !query?.table) { + if (!query?.dataset || !query?.table) { return []; } return this.fetchFields(query); @@ -84,7 +91,7 @@ export class MssqlDatasource extends SqlDatasource { lookup: async (path?: string) => { if (!path) { const datasets = await this.fetchDatasets(); - return datasets.map((d) => ({ name: d, completion: `${d}.${SCHEMA_NAME}.` })); + return datasets.map((d) => ({ name: d, completion: d })); } else { const parts = path.split('.').filter((s: string) => s); if (parts.length > 2) { @@ -92,7 +99,7 @@ export class MssqlDatasource extends SqlDatasource { } if (parts.length === 1) { const tables = await this.fetchTables(parts[0]); - return tables.map((t) => ({ name: t, completion: `${t}` })); + return tables.map((t) => ({ name: t, completion: t })); } else { return []; } diff --git a/public/app/plugins/datasource/mssql/sqlCompletionProvider.ts b/public/app/plugins/datasource/mssql/sqlCompletionProvider.ts index d3c7e0556a5..5b2ab94a0d8 100644 --- a/public/app/plugins/datasource/mssql/sqlCompletionProvider.ts +++ b/public/app/plugins/datasource/mssql/sqlCompletionProvider.ts @@ -13,8 +13,6 @@ import { TokenType, } from 'app/features/plugins/sql/types'; -import { SCHEMA_NAME } from './sqlUtil'; - interface CompletionProviderGetterArgs { getColumns: React.MutableRefObject<(t: SQLQuery) => Promise>; getTables: React.MutableRefObject<(d?: string) => Promise>; @@ -37,15 +35,14 @@ export const getSqlCompletionProvider: (args: CompletionProviderGetterArgs) => L processedToken = processedToken.next; } - const tableName = tablePath.split('.').pop(); - - return tableName || tablePath; + return tablePath; }, }, columns: { resolve: async (t: string) => { - return await getColumns.current({ table: t, refId: 'A' }); + const [database, schema, tableName] = t.split('.'); + return await getColumns.current({ table: `${schema}.${tableName}`, dataset: database, refId: 'A' }); }, }, supportedFunctions: () => AGGREGATE_FNS, @@ -111,10 +108,6 @@ export function getDatabaseName(token: LinkedToken) { database = processedToken.value + database; } - if (database.includes(SCHEMA_NAME)) { - database = database.replace(SCHEMA_NAME, ''); - } - database = database.trim(); return database; diff --git a/public/app/plugins/datasource/mssql/sqlUtil.ts b/public/app/plugins/datasource/mssql/sqlUtil.ts index 2aa41cb3213..62328e12e19 100644 --- a/public/app/plugins/datasource/mssql/sqlUtil.ts +++ b/public/app/plugins/datasource/mssql/sqlUtil.ts @@ -79,8 +79,6 @@ export function getRAQBType(type: string): RAQBFieldTypes { } } -export const SCHEMA_NAME = 'dbo'; - export function toRawSql({ sql, dataset, table }: SQLQuery): string { let rawQuery = ''; @@ -92,7 +90,7 @@ export function toRawSql({ sql, dataset, table }: SQLQuery): string { rawQuery += createSelectClause(sql.columns, sql.limit); if (dataset && table) { - rawQuery += `FROM ${dataset}.${SCHEMA_NAME}.${table} `; + rawQuery += `FROM ${dataset}.${table} `; } if (sql.whereString) {