Skip to content

Commit

Permalink
Kusto functions support (#2572)
Browse files Browse the repository at this point in the history
* Update SqlServerFunctionModelFactory.cs

* Update SqlServerRoutineModelFactory.cs

* fixes

* Update SqlServerFunctionModelFactory.cs

* fix

* Update SqlServerFunctionModelFactory.cs

* Update SqlServerRoutineModelFactory.cs

* Update SqlServerRoutineModelFactory.cs

* Update SqlServerRoutineModelFactory.cs

* fixes

* fix

* CR

* CR
  • Loading branch information
barnuri authored Oct 13, 2024
1 parent e359aec commit 9232a3d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ public SqlServerFunctionModelFactory()
ROUTINE_NAME,
CAST(CASE WHEN (DATA_TYPE != 'TABLE') THEN 1 ELSE 0 END AS bit) AS IS_SCALAR
FROM INFORMATION_SCHEMA.ROUTINES
LEFT JOIN sys.extended_properties AS [ep] on [ep].major_id = object_id(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)) AND [ep].minor_id = 0 AND [ep].class = 1 and [ep].name = N'microsoft_database_tools_support'
WHERE NULLIF(ROUTINE_NAME, '') IS NOT NULL
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)), 'IsMSShipped') = 0
AND [ep].major_id IS NULL
AND object_id(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)) NOT IN (SELECT [ep].[major_id]
FROM [sys].[extended_properties] AS [ep]
WHERE [ep].[minor_id] = 0
AND [ep].[class] = 1
AND [ep].[name] = N'microsoft_database_tools_support'
)
AND ROUTINE_TYPE = N'FUNCTION'
ORDER BY ROUTINE_NAME;";
}
Expand All @@ -44,11 +48,15 @@ protected override List<List<ModuleResultElement>> GetResultElementLists(SqlConn
var sql = $@"
SELECT
c.name,
COALESCE(type_name(c.system_type_id), type_name(c.user_type_id)) AS type_name,
COALESCE(ts.name, tu.name) AS type_name,
c.column_id AS column_ordinal,
c.is_nullable
FROM sys.columns c
WHERE object_id = OBJECT_ID('{module.Schema}.{module.Name}');";
inner join sys.types tu ON c.user_type_id = tu.user_type_id
inner join sys.objects AS o on o.object_id = c.object_id
inner JOIN sys.schemas AS s ON o.schema_id = s.schema_id
LEFT JOIN sys.types ts ON tu.system_type_id = ts.user_type_id
where o.name = '{module.Name}' and s.name = '{module.Schema}';";

#pragma warning disable CA2100 // Review SQL queries for security vulnerabilities
using var adapter = new SqlDataAdapter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ public SqlServerStoredProcedureModelFactory()
ROUTINE_NAME,
CAST(0 AS bit) AS IS_SCALAR
FROM INFORMATION_SCHEMA.ROUTINES
LEFT JOIN sys.extended_properties AS [ep] on [ep].major_id = object_id(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)) AND [ep].minor_id = 0 AND [ep].class = 1 and [ep].name = N'microsoft_database_tools_support'
WHERE NULLIF(ROUTINE_NAME, '') IS NOT NULL
AND OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)), 'IsMSShipped') = 0
AND [ep].major_id IS NULL
AND object_id(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)) NOT IN (SELECT [ep].[major_id]
FROM [sys].[extended_properties] AS [ep]
WHERE [ep].[minor_id] = 0
AND [ep].[class] = 1
AND [ep].[name] = N'microsoft_database_tools_support'
)
AND ROUTINE_TYPE = N'PROCEDURE'
ORDER BY ROUTINE_NAME;";
}
Expand Down
40 changes: 39 additions & 1 deletion src/Core/RevEng.Core.60/Routines/SqlServerRoutineModelFactory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient;
using RevEng.Core.Abstractions;
using RevEng.Core.Abstractions.Metadata;
using RevEng.Core.Routines.Extensions;
Expand Down Expand Up @@ -163,6 +163,14 @@ protected RoutineModel GetRoutines(string connectionString, ModuleModelFactoryOp
};
}

private static string GetVersion(SqlConnection connection)
{
using var command = connection.CreateCommand();
command.CommandText = "SELECT @@VERSION;";
var result = command.ExecuteScalar();
return result as string;
}

private static Dictionary<string, List<ModuleParameter>> GetParameters(SqlConnection connection)
{
using var dtResult = new DataTable();
Expand All @@ -189,6 +197,36 @@ from sys.parameters p
LEFT JOIN sys.table_types t ON t.user_type_id = p.user_type_id
ORDER BY p.object_id, p.parameter_id;";

if (GetVersion(connection) == "Microsoft SQL Kusto")
{
sql = $@"
SELECT
'Parameter' = p.name,
'Type' = COALESCE(ts.name, tu.name),
'Length' = CAST(p.max_length AS INT),
'Precision' = CASE
WHEN ts.name = 'uniqueidentifier' THEN p.precision
WHEN ts.name IN ('decimal', 'numeric') THEN p.precision
WHEN ts.name IN ('varchar', 'nvarchar') THEN p.max_length
ELSE NULL
END,
'Scale' = CAST(p.scale AS INT),
'Order' = CAST(p.parameter_id AS INT),
p.is_output AS output,
'TypeName' = QUOTENAME(s.name) + '.' + QUOTENAME(tu.name),
'TypeSchema' = tu.schema_id,
'TypeId' = p.user_type_id,
'RoutineName' = o.name,
'RoutineSchema' = s.name
from sys.parameters p
inner join sys.objects AS o on o.object_id = p.object_id
inner JOIN sys.schemas AS s ON o.schema_id = s.schema_id
inner join sys.types tu ON p.user_type_id = tu.user_type_id
LEFT JOIN sys.types ts ON tu.system_type_id = ts.user_type_id
ORDER BY p.object_id, p.parameter_id;
";
}

using var adapter = new SqlDataAdapter
{
SelectCommand = new SqlCommand(sql, connection),
Expand Down
28 changes: 10 additions & 18 deletions src/Core/RevEng.Core.80/PatchedSqlServerDatabaseModelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private static readonly Regex PartExtractor

private byte? _compatibilityLevel;
private EngineEdition? _engineEdition;
private string? _versionInformation;
private string? _version;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -134,7 +134,7 @@ public DatabaseModel Create(DbConnection connection, DatabaseModelFactoryOptions

_compatibilityLevel = GetCompatibilityLevel(connection);
_engineEdition = GetEngineEdition(connection);
_versionInformation = GetVersionInformation(connection);
_version = GetVersion(connection);

databaseModel.DatabaseName = connection.Database;
databaseModel.DefaultSchema = GetDefaultSchema(connection);
Expand Down Expand Up @@ -235,7 +235,7 @@ FROM sys.databases
return command.ExecuteScalar() as string;
}

static string? GetVersionInformation(DbConnection connection)
static string? GetVersion(DbConnection connection)
{
using var command = connection.CreateCommand();
command.CommandText = "SELECT @@VERSION;";
Expand Down Expand Up @@ -555,13 +555,17 @@ private void GetTables(
"""
FROM [sys].[tables] AS [t]
LEFT JOIN [sys].[extended_properties] AS [e] ON [e].[major_id] = [t].[object_id] AND [e].[minor_id] = 0 AND [e].[class] = 1 AND [e].[name] = 'MS_Description'
LEFT JOIN [sys].[extended_properties] AS [ep] ON [ep].[major_id] = [t].[object_id] AND [ep].[minor_id] = 0 AND [ep].[class] = 1 AND [ep].[name] = 'microsoft_database_tools_support'
""");

var tableFilterBuilder = new StringBuilder(
$"""
[t].[is_ms_shipped] = 0
AND [ep].[major_id] is null
AND [t].[object_id] NOT IN (SELECT [ep].[major_id]
FROM [sys].[extended_properties] AS [ep]
WHERE [ep].[minor_id] = 0
AND [ep].[class] = 1
AND [ep].[name] = N'microsoft_database_tools_support'
)
AND [t].[name] <> '{HistoryRepository.DefaultTableName}'
""");

Expand Down Expand Up @@ -743,7 +747,6 @@ private void GetColumns(
(
SELECT [t].[name], [t].[object_id], [t].[schema_id]
FROM [sys].[tables] t
LEFT JOIN [sys].[extended_properties] AS [ep] ON [ep].[major_id] = [t].[object_id] AND [ep].[minor_id] = 0 AND [ep].[class] = 1 AND [ep].[name] = 'microsoft_database_tools_support'
WHERE {tableFilter}
""");

Expand Down Expand Up @@ -1045,7 +1048,6 @@ FROM [sys].[indexes] AS [i]
JOIN [sys].[tables] AS [t] ON [i].[object_id] = [t].[object_id]
JOIN [sys].[index_columns] AS [ic] ON [i].[object_id] = [ic].[object_id] AND [i].[index_id] = [ic].[index_id]
JOIN [sys].[columns] AS [c] ON [ic].[object_id] = [c].[object_id] AND [ic].[column_id] = [c].[column_id]
LEFT JOIN [sys].[extended_properties] AS [ep] ON [ep].[major_id] = [t].[object_id] AND [ep].[minor_id] = 0 AND [ep].[class] = 1 AND [ep].[name] = 'microsoft_database_tools_support'
WHERE [i].[is_hypothetical] = 0
AND "
+ tableFilter;
Expand All @@ -1060,7 +1062,6 @@ FROM [sys].[indexes] i
JOIN [sys].[tables] AS [t] ON [i].[object_id] = [t].[object_id]
JOIN [sys].[index_columns] AS [ic] ON [i].[object_id] = [ic].[object_id] AND [i].[index_id] = [ic].[index_id]
JOIN [sys].[columns] AS [c] ON [ic].[object_id] = [c].[object_id] AND [ic].[column_id] = [c].[column_id]
LEFT JOIN [sys].[extended_properties] AS [ep] ON [ep].[major_id] = [t].[object_id] AND [ep].[minor_id] = 0 AND [ep].[class] = 1 AND [ep].[name] = 'microsoft_database_tools_support'
WHERE "
+ tableFilter;

Expand Down Expand Up @@ -1308,7 +1309,6 @@ FROM [sys].[foreign_keys] AS [f]
JOIN [sys].[columns] AS [col1] ON [col1].[column_id] = [fc].[parent_column_id] AND [col1].[object_id] = [t].[object_id]
JOIN [sys].[tables] AS [tab2] ON [tab2].[object_id] = [fc].[referenced_object_id]
JOIN [sys].[columns] AS [col2] ON [col2].[column_id] = [fc].[referenced_column_id] AND [col2].[object_id] = [tab2].[object_id]
LEFT JOIN [sys].[extended_properties] AS [ep] ON [ep].[major_id] = [t].[object_id] AND [ep].[minor_id] = 0 AND [ep].[class] = 1 AND [ep].[name] = 'microsoft_database_tools_support'
WHERE {tableFilter}
ORDER BY [table_schema], [table_name], [f].[name], [fc].[constraint_column_id];
""";
Expand Down Expand Up @@ -1491,7 +1491,6 @@ private void GetTriggers(DbConnection connection, IReadOnlyList<DatabaseTable> t
[tr].[name] AS [trigger_name]
FROM [sys].[triggers] AS [tr]
JOIN [sys].[tables] AS [t] ON [tr].[parent_id] = [t].[object_id]
LEFT JOIN [sys].[extended_properties] AS [ep] ON [ep].[major_id] = [t].[object_id] AND [ep].[minor_id] = 0 AND [ep].[class] = 1 AND [ep].[name] = 'microsoft_database_tools_support'
WHERE {tableFilter}
ORDER BY [table_schema], [table_name], [tr].[name];
""";
Expand Down Expand Up @@ -1536,14 +1535,7 @@ private bool SupportsTriggers()
=> IsFullFeaturedEngineEdition();

private bool IsFullFeaturedEngineEdition()
{
if (_versionInformation != null && _versionInformation.Contains("Kusto", StringComparison.Ordinal))
{
return false;
}

return _engineEdition is not EngineEdition.SqlDataWarehouse and not EngineEdition.SqlOnDemand and not EngineEdition.DynamicsTdsEndpoint;
}
=> _engineEdition is not EngineEdition.SqlDataWarehouse and not EngineEdition.SqlOnDemand and not EngineEdition.DynamicsTdsEndpoint && _version != "Microsoft SQL Kusto";

private static string DisplayName(string? schema, string name)
=> (!string.IsNullOrEmpty(schema) ? schema + "." : "") + name;
Expand Down

0 comments on commit 9232a3d

Please sign in to comment.