Task: Write floating point values to the database without rounding

Table of Contents

This page documents a task in the Model the ORE report configuration as entities story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

A double written through sqlgen reads back as the same double, so no value the system stores is silently rounded.

2. Status

Field Value
State DONE
Parent story Model the ORE report configuration as entities
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-03

3. Acceptance

  • A double such as 1e-12 or 0.0123456789 written through a generated repository reads back unchanged, proven by a test.
  • The fix is a patch on the sqlgen overlay port at its pinned commit, with the upstream code named so it can be offered upstream.
  • The curve configuration database round trip passes once this lands.

4. Plan

Found by the curve configuration database round trip: a yield curve tolerance of 1e-12 was written to the database and read back as 0.

The cause is upstream. sqlgen's Parser<T>::write in include/sqlgen/parsing/Parser_default.hpp turns every value with no reflection method and no enum type into text with std::to_string. For a float or a double that is printf("%f"): six decimal places, so 1e-12 is written as 0.000000 and 0.0123456789 as 0.012346. The read side, std::stod, is exact; only the write loses digits. The latest upstream commit that touches the file, 816ca6adec, still does this.

The fix is a patch on the overlay port, which pins sqlgen at 47e5711: floats are written with std::to_chars, the shortest text that reads back as the same value. The port version is bumped so a cached build of the old port is not reused.

Proof: a repository test writes three doubles through a generated repository and reads them back. Run against the unpatched port it fails all three cases; with the patch it passes them.

5. Measurements

Every number this task claims about a tree, with the command that produced it and the commit it was measured at. A number without both is not a measurement, because a clean-up record describes a tree and trunk moves under a branch: a consumer count, a gate's component count and a suite's size all change with no code changing, and the reader of a bare number cannot tell which tree it came from. Where the raw output matters, put it in an evidence/ file beside the task and name that file in the Command column.

What Value Command Commit
Double fields in generated repository entities 29 fields in 20 entities: trading 13, refdata 4, dq 1, reporting 1, synthetic 1 =grep -rlE "std::optional<double>\ double [a-z_]+;" projects/*/core/include/*/repository/*_entity.hpp= 4b5499c45d
Values read back before the patch 1e-12 as 0.0; 0.0123456789 as 0.012346; 123456789.123456789 as 123456789.123457 compass test run -- -R ores.refdata.core.tests, cases in repository_floating_point_precision_tests.cpp 4b5499c45d

6. Notes

7. Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
     

8. PRs

PR Title
#2540 [build] Write floating point values to the database without rounding

9. Review

# Comment summary File Decision Notes
1 Scientific notation in numeric or text columns; nan and inf patch No change PostgreSQL reads 1e-12 into double precision, real and numeric; nan and inf were written the same way before.
2 Floating to_chars needs a recent standard library patch No change The macOS build uses Xcode 16 on macos-14; Apple's libc++ provides floating to_chars from macOS 13.3. The scheduled macOS build confirms it.
3 Add float, negative and zero cases repository_floating_point_precision_tests.cpp Decline No entity holds a float; sign and zero do not depend on the digit count the defect was about.
4 Offer the fix upstream portfile.cmake Deferred to the operator Opening an issue on getml/sqlgen is an outward action; proposed to the operator.
5 Existing rows keep their rounded values PR No change Stated in the PR's limitations; release notes are built from the PR.

10. Result

  • The sqlgen overlay port carries fix-floating-point-precision.patch, which writes floats with std::to_chars instead of std::to_string. The port version is bumped to 1 so a cached build is not reused.
  • repository_floating_point_precision_tests.cpp writes 1e-12, 0.0123456789 and 123456789.123456789 through a generated repository. It failed all three against the unpatched port and passes all three with the patch.
  • Build clean after a reconfigure; ctest 89/89 with services up.
  • The same defect exists in upstream sqlgen at 816ca6adec; the patch is written against the upstream file so it can be offered there.

Emacs 29.3 (Org mode 9.6.15)