mirror of
https://github.com/grafana/grafana.git
synced 2026-08-11 13:44:59 -05:00
MSSQL: Support tables from all schemas (#53099)
This commit is contained in:
@@ -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}';`;
|
||||
}
|
||||
|
||||
@@ -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<string[]> {
|
||||
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<SQLSelectableValue[]> {
|
||||
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 [];
|
||||
}
|
||||
|
||||
@@ -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<ColumnDefinition[]>>;
|
||||
getTables: React.MutableRefObject<(d?: string) => Promise<TableDefinition[]>>;
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user