From bd46566f6bd76c309ba40aaa19fc981c7a976c97 Mon Sep 17 00:00:00 2001 From: Erik Darling <2136037+erikdarlingdata@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:14:15 -0500 Subject: [PATCH] Fix Int16 cast in long-running query alerts, fix DuckDB migration ordering - NocHealth: session_id is smallint in DMVs, use Convert.ToInt32 instead of reader.GetInt32 to avoid "Unable to cast System.Int16 to System.Int32" - DuckDbInitializer: run CREATE TABLE before ALTER TABLE migrations so migrations don't fail against nonexistent tables after archive-and-reset Co-Authored-By: Claude Opus 4.6 --- Dashboard/Services/DatabaseService.NocHealth.cs | 2 +- Lite/Database/DuckDbInitializer.cs | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Dashboard/Services/DatabaseService.NocHealth.cs b/Dashboard/Services/DatabaseService.NocHealth.cs index c1f59887..7a98b656 100644 --- a/Dashboard/Services/DatabaseService.NocHealth.cs +++ b/Dashboard/Services/DatabaseService.NocHealth.cs @@ -641,7 +641,7 @@ ORDER BY r.total_elapsed_time DESC { results.Add(new LongRunningQueryInfo { - SessionId = reader.GetInt32(0), + SessionId = Convert.ToInt32(reader.GetValue(0)), DatabaseName = reader.IsDBNull(1) ? "" : reader.GetString(1), QueryText = reader.IsDBNull(2) ? "" : reader.GetString(2), ProgramName = reader.IsDBNull(3) ? "" : reader.GetString(3), diff --git a/Lite/Database/DuckDbInitializer.cs b/Lite/Database/DuckDbInitializer.cs index 57121939..74d60f30 100644 --- a/Lite/Database/DuckDbInitializer.cs +++ b/Lite/Database/DuckDbInitializer.cs @@ -141,13 +141,9 @@ await ExecuteNonQueryAsync(connection, var existingVersion = await GetSchemaVersionAsync(connection); - if (existingVersion < CurrentSchemaVersion) - { - _logger?.LogInformation("Schema upgrade needed: v{Old} -> v{New}", existingVersion, CurrentSchemaVersion); - await RunMigrationsAsync(connection, existingVersion); - await SetSchemaVersionAsync(connection, CurrentSchemaVersion); - } - + /* Create tables first (IF NOT EXISTS) so migrations can ALTER them safely. + After an archive-and-reset the database is empty — running ALTER TABLE + before CREATE TABLE would fail on nonexistent tables. */ foreach (var tableStatement in Schema.GetAllTableStatements()) { await ExecuteNonQueryAsync(connection, tableStatement); @@ -158,6 +154,13 @@ await ExecuteNonQueryAsync(connection, await ExecuteNonQueryAsync(connection, indexStatement); } + if (existingVersion < CurrentSchemaVersion) + { + _logger?.LogInformation("Schema upgrade needed: v{Old} -> v{New}", existingVersion, CurrentSchemaVersion); + await RunMigrationsAsync(connection, existingVersion); + await SetSchemaVersionAsync(connection, CurrentSchemaVersion); + } + _logger?.LogInformation("Database initialization complete. Schema version: {Version}", CurrentSchemaVersion); }