We're building a custom historian module for timescaledb on the 8.3 Historian SDK (gateway 8.3.3) and got a bug report that NULL values in history read back as 0.0. After digging in, it turns out this isn't specific to our module.
What we tested:
-
Stored three good float points (1.5, 2.5, 3.5) with
system.historian.storeDataPoints, then inserted two rows with NULL values directly in the database: one with good quality (192) and one with the bad quality code we observed Ignition itself produce for a failing tag (-2147483136). Queried the range withsystem.historian.queryRawPoints. Result: 1.5, 0.0, 2.5, 0.0, 3.5. The qualities come back unchanged (192 for the good NULL, -2147483136 for the bad one), but both NULLs turned into 0.0. The good quality NULL is now indistinguishable from a real measured zero. -
Our module keeps the value as null the whole way: we check
ResultSet.wasNull()and hand the null toDataPointFactory.createAtomicPoint, which internally routes tocreateNullPoint. So the 0.0 appears later, when the platform assembles the query result dataset. As far as we can tell no historian implementation can return a NULL through that layer. -
For comparison we looked at the stock SQL Historian (historian-sql 1.3.3). In
PartitionDataLoader.getValueFromRSthe numeric columns are read withrs.getLong/rs.getDoublewithout awasNull()check, so there a NULL already becomes 0/0.0 at the JDBC level.
Questions:
- Is the null to 0.0 coercion in query result assembly intended? If so, what is
createNullPointmeant for? - Is there a recommended way for a historian to return "no value at this timestamp" so clients see a gap instead of a fabricated zero?
- Should the missing
wasNull()checks in the stock SQL Historian be filed as a bug through support?
Setup: Ignition 8.3.3 in Docker, queries via a WebDev endpoint calling system.historian.queryRawPoints, per-point qualities read with getQualityAt.