docs(historian): #680 lane B review — QuestDB data-range lookups are partition scans, both-direction gate, all-Bad Count 0x80000401, outage-last parity test, CLAUDE.md per-sample bullet

This commit is contained in:
Joseph Doherty
2026-10-11 16:39:39 -04:00
parent b8344bb151
commit b5e3e5108c
5 changed files with 58 additions and 11 deletions
@@ -491,6 +491,49 @@ public sealed class SdkAggregateParityTests
.ShouldBe([0u, HistorianInfoBits.HistorianPartial, 0u, 0u]);
}
/// <summary>#680 review: the data ends on an OUTAGE MARKER (+25) — the interval holding it is all-Bad.</summary>
private static readonly StoredSample[] OutageEndsData =
[
S(-5, HistorianValue.FromDouble(1), Good), S(3, HistorianValue.FromDouble(2), Good),
S(25, HistorianValue.Empty, BadNoCommunication),
];
[Theory]
[InlineData(0, 40, 10)]
[InlineData(40, 0, 10)]
public void An_outage_marker_as_the_last_sample_sets_no_end_of_data_Partial_on_its_Bad_interval(double from, double to,
double intervalS)
{
// Documented divergence (remarks): the SDK sets the end-of-data Partial bit on that interval's Bad result too; ours
// never puts Partial on a Bad result. Masked by clearing Partial on the SDK's Bad results only — every other bit,
// timestamp and value (and every non-Bad interval's Partial) is still compared.
var failures = new List<string>();
var sawSdkPartialOnBad = false;
foreach (var agg in PerSample)
{
var ours = Ours(agg, from, to, intervalS, OutageEndsData);
var sdk = Sdk(agg, from, to, intervalS, OutageEndsData);
sawSdkPartialOnBad |= sdk.Any(r => (r.StatusCode & 0x80000000u) != 0 && (r.StatusCode & 0x4u) != 0);
var masked = sdk.Select(r => (r.StatusCode & 0x80000000u) != 0 ? r with { StatusCode = r.StatusCode & ~0x4u } : r)
.ToList();
try
{
SdkAggregateOracle.ShouldMatch(ours, masked, $"{agg} OutageEndsData {from}→{to}/{intervalS}s",
compareCalculatedInterpolatedBits: false);
// The interval holding the marker ((20,30] / [20,30)) is Bad and carries no Partial.
var k = from < to ? 2 : 1;
((ours[k].StatusCode & 0x80000000u) != 0).ShouldBeTrue($"{agg}: the outage interval is Bad");
(ours[k].StatusCode & HistorianInfoBits.HistorianPartial).ShouldBe(0u, $"{agg}: no Partial on a Bad result");
}
catch (Exception ex)
{
failures.Add(ex.Message);
}
}
failures.ShouldBeEmpty(string.Join("\n", failures));
sawSdkPartialOnBad.ShouldBeTrue("the mask is not vacuous: the SDK does flag the Bad interval Partial");
}
/// <summary>The per-bucket statistics the backends' SQL computes, built in memory with <see cref="BucketPlan.IndexOf"/>.</summary>
internal static IEnumerable<BucketRow> InMemoryRows(BucketPlan plan, IEnumerable<StoredSample> samples, bool maximum = false)
{