From 8ebee2ac40680e9ac5cfccbec0102aba0e9fa4a7 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sun, 11 Oct 2026 18:48:53 -0400 Subject: [PATCH] docs(historian): warn that QuestDB first()/last() ordering is implementation behaviour (#680 F1 review) --- .../QuestDbAggregateQueries.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb/QuestDbAggregateQueries.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb/QuestDbAggregateQueries.cs index e6380aab..7bff0c19 100644 --- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb/QuestDbAggregateQueries.cs +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb/QuestDbAggregateQueries.cs @@ -101,6 +101,12 @@ internal static class QuestDbAggregateQueries /// being written. One reference means one reader at one table version. A windowed (row_number()) /// single-scan form was also correct but ~2× slower; this one is not slower than the old query. /// + /// + /// ⚠️ first()/last() following timestamp order is QuestDB 10.0.1 IMPLEMENTATION behaviour (rows reach + /// the GROUP BY in row-id order, and the parallel merge keeps row id), not a documented guarantee. It was verified + /// on 20M rows with O3 inserts, single-threaded and parallel. Adding a JOIN, ORDER BY or UNION inside + /// Classified, or upgrading QuestDB, can silently break Start/End — re-verify first(ts) = min(ts). + /// /// /// Prefixed sample table name. /// The SQL text.