feat: cast numeric literals to decimal type (#805) ## What Add casting of numeric literals (`int`, `long`, `float`, `double`) to a decimal target type in `Literal::CastTo`, so a numeric value can be used as a default for a decimal column. Previously `CastFromInt` / `CastFromLong` / `CastFromFloat` / `CastFromDouble` had no `kDecimal` case and fell through to `NotSupported`, so a default like `Literal::Int(12)` or `Literal::Double(9.99)` for a `decimal(9, 2)` column was rejected. Java allows these (`IntegerLiteral.to`, `DoubleLiteral.to`, etc. scale the value to the target scale), so this brings the C++ literal cast layer to parity for numeric sources. ## How - **Integer → decimal**: `CastIntegerToDecimal` treats the integer as scale 0 and rescales it to the target scale via `RescaleHalfUp` (exact when increasing scale, HALF_UP when decreasing it), then verifies the result fits the target precision (`FitsInPrecision`). Example: `12` → `decimal(9,2)` yields unscaled `1200` (`12.00`). - **Float/double → decimal**: `CastRealToDecimal` parses the value's shortest round-tripping decimal representation (matching Java's `BigDecimal.valueOf(double)` via `Double.toString`) into an integer coefficient and exponent-derived scale without expanding scientific notation, then rounds to the target scale with **HALF_UP** rounding (round half away from zero, as Java does — `2.5` → `3`, `-2.5` → `-3`) and checks precision. Non-finite values are rejected. - Both paths reject an out-of-range decimal scale before indexing the powers-of-ten table (`DecimalType` does not bound its scale on construction, so `decimal(9, 40)` would otherwise read past the table). ## Scope Follow-up split out from the v3 default-value work (see the `CastDefaultToType` discussion on #793). It only extends the shared `Literal::CastTo` layer for numeric sources. ## Testing `LiteralTest.IntegerCastToDecimal` (int/long scaling, out-of-precision rejection, out-of-range scale rejection) and `LiteralTest.RealCastToDecimal` (float/double scaling, HALF_UP rounding incl. negative, round-down, out-of-precision and non-finite rejection, scientific-notation overflow rejection and negative-scale acceptance), all verified fail-without / pass-with. Full `expression_test` passes (495 tests).
C++ implementation of Apache Iceberg™.
Required:
Optional:
git clone https://github.com/apache/iceberg-cpp.git cd iceberg-cpp cmake -S . -B build -G Ninja cmake --build build ctest --test-dir build --output-on-failure
cmake -S . -B build -G Ninja -DCMAKE_INSTALL_PREFIX=/path/to/install -DICEBERG_BUILD_STATIC=ON -DICEBERG_BUILD_SHARED=ON cmake --build build ctest --test-dir build --output-on-failure cmake --install build
To run a specific test suite:
ctest --test-dir build -R schema_test --output-on-failure
cmake -S . -B build -G Ninja -DCMAKE_INSTALL_PREFIX=/path/to/install -DICEBERG_BUILD_BUNDLE=ON cmake --build build ctest --test-dir build --output-on-failure cmake --install build
cmake -S . -B build -G Ninja -DCMAKE_INSTALL_PREFIX=/path/to/install -DCMAKE_PREFIX_PATH=/path/to/arrow -DICEBERG_BUILD_BUNDLE=ON cmake --build build ctest --test-dir build --output-on-failure cmake --install build
| Option | Default | Description |
|---|---|---|
ICEBERG_BUILD_STATIC | ON | Build static library |
ICEBERG_BUILD_SHARED | OFF | Build shared library |
ICEBERG_BUILD_TESTS | ON | Build tests |
ICEBERG_BUILD_BUNDLE | ON | Build the battery-included library |
ICEBERG_BUILD_REST | ON | Build REST catalog client |
ICEBERG_BUILD_REST_INTEGRATION_TESTS | OFF | Build REST catalog integration tests |
ICEBERG_BUILD_HIVE | OFF | Build Hive (HMS) catalog client |
ICEBERG_BUILD_SQL_CATALOG | OFF | Build SQL catalog client |
ICEBERG_SQL_SQLITE | OFF | Build the SQLite connector for the SQL catalog |
ICEBERG_SQL_POSTGRESQL | OFF | Build the PostgreSQL connector for the SQL catalog |
ICEBERG_SQL_MYSQL | OFF | Build the MySQL connector for the SQL catalog |
ICEBERG_ENABLE_ASAN | OFF | Enable Address Sanitizer |
ICEBERG_ENABLE_UBSAN | OFF | Enable Undefined Behavior Sanitizer |
meson setup builddir meson compile -C builddir meson test -C builddir --timeout-multiplier 0
Meson provides built-in equivalents for several CMake options:
--default-library=<shared|static|both> instead of ICEBERG_BUILD_STATIC / ICEBERG_BUILD_SHARED-Db_sanitize=address,undefined instead of ICEBERG_ENABLE_ASAN / ICEBERG_ENABLE_UBSAN--libdir, --bindir, --includedir for install directoriesMeson-specific options (configured via -D<option>=<value>):
| Option | Default | Description |
|---|---|---|
rest | enabled | Build REST catalog client |
rest_integration_test | disabled | Build integration test for REST catalog |
tests | enabled | Build tests |
After installing the core libraries, you can build the examples:
cd example cmake -S . -B build -G Ninja -DCMAKE_PREFIX_PATH=/path/to/install cmake --build build
If you are using provided Apache Arrow, include /path/to/arrow in CMAKE_PREFIX_PATH:
cmake -S . -B build -G Ninja -DCMAKE_PREFIX_PATH="/path/to/install;/path/to/arrow"
If you experience network issues when downloading dependencies, you can customize the download URLs using environment variables:
ICEBERG_ARROW_URL: Apache Arrow tarball URLICEBERG_AVRO_URL: Apache Avro tarball URLICEBERG_AVRO_GIT_URL: Apache Avro git repository URLICEBERG_NANOARROW_URL: Nanoarrow tarball URLICEBERG_CROARING_URL: CRoaring tarball URLICEBERG_UTF8PROC_URL: utf8proc tarball URLICEBERG_NLOHMANN_JSON_URL: nlohmann-json tarball URLICEBERG_SPDLOG_URL: spdlog tarball URLICEBERG_CPR_URL: cpr tarball URLExample:
export ICEBERG_ARROW_URL="https://your-mirror.com/apache-arrow-22.0.0.tar.gz" cmake -S . -B build
Apache Iceberg is an active open-source project, governed under the Apache Software Foundation (ASF). Iceberg-cpp is open to people who want to contribute to it. Here are some ways to get involved:
The Apache Iceberg community is built on the principles described in the Apache Way and all who engage with the community are expected to be respectful, open, come with the best interests of the community in mind, and abide by the Apache Foundation Code of Conduct.
In addition, contributors using AI-assisted tools must follow the documented guidelines for AI-assisted contributions available on the Iceberg website: https://iceberg.apache.org/contribute/#guidelines-for-ai-assisted-contributions.
Install the python package pre-commit and run once pre-commit install.
pip install pre-commit pre-commit install
This will setup a git pre-commit-hook that is executed on each commit and will report the linting problems. To run all hooks on all files use pre-commit run -a.
We provide Dev Container configuration file templates.
To use a Dev Container as your development environment, follow the steps below, then select Dev Containers: Reopen in Container from VS Code's Command Palette.
cd .devcontainer cp Dockerfile.template Dockerfile cp devcontainer.json.template devcontainer.json
If you make improvements that could benefit all developers, please update the template files and submit a pull request.
Licensed under the Apache License, Version 2.0