ORC-2213: [C++] Add option to read timestamps with writer timezone

### What changes were proposed in this pull request?

Add a RowReaderOptions flag that lets timestamp readers use the writer timezone recorded in each stripe footer instead of the configured reader timezone. This preserves the stored timestamp value for callers that need to avoid ORC timestamp timezone conversion.

### Why are the changes needed?

In old days, ORC only supports orc::TIMESTAMP type. The semantics of orc::TIMESTAMP is equivalent to TIMESTAMP_NTZ but with a complex writer and reader timezone adjustment.  So it is difficult to support both TIMESTAMP_NTZ and TIMESTAMP_LTZ types using a single orc::TIMESTAMP. In later versions, orc::TIMESTAMP_INSTANT has been added to support TIMESTAMP_LTZ type. However, users may not know the difference under the hood and still use legacy systems to write both TIMESTAMP_LTZ and TIMESTAMP_NTZ semantics to the old orc::TIMESTAMP type. When users use orc::TIMESTAMP as TIMESTAMP_LTZ values, we should set reader timezone to the writer timezone to avoid value conversion. However, users may not know the writer timezone in advance and ORC files may have different writer timezone (considering files are produced by teams in different time zones.) We need an approach to enforce reader to use writer timezone via explicit configuration.

### How was this patch tested?

Added a new test case.

### Was this patch authored or co-authored using generative AI tooling?

Generated-by: Codex GPT-5.6 Sol

Closes #2699 from wgtmac/ORC-2213.

Authored-by: Gang Wu <ustcwg@gmail.com>
Signed-off-by: Gang Wu <ustcwg@gmail.com>
5 files changed
tree: 25723cbef3398e601e16d8ce607e06d33cc79200
  1. .github/
  2. .idea/
  3. c++/
  4. cmake_modules/
  5. conan/
  6. dev/
  7. docker/
  8. examples/
  9. java/
  10. site/
  11. subprojects/
  12. tools/
  13. .asf.yaml
  14. .clang-format
  15. .clang-tidy
  16. .gitignore
  17. .markdownlint.yaml
  18. .markdownlintignore
  19. .nojekyll
  20. AGENTS.md
  21. CLAUDE.md
  22. CMakeLists.txt
  23. LICENSE
  24. meson.build
  25. meson.options
  26. NOTICE
  27. README.md
  28. SECURITY.md
README.md

Apache ORC

ORC is a self-describing type-aware columnar file format designed for Hadoop workloads. It is optimized for large streaming reads, but with integrated support for finding required rows quickly. Storing data in a columnar format lets the reader read, decompress, and process only the values that are required for the current query. Because ORC files are type-aware, the writer chooses the most appropriate encoding for the type and builds an internal index as the file is written. Predicate pushdown uses those indexes to determine which stripes in a file need to be read for a particular query and the row indexes can narrow the search to a particular set of 10,000 rows. ORC supports the complete set of types in Hive, including the complex types: structs, lists, maps, and unions.

ORC File Library

This project includes both a Java library and a C++ library for reading and writing the Optimized Row Columnar (ORC) file format. The C++ and Java libraries are completely independent of each other and will each read all versions of ORC files.

Releases:

The current build status:

BranchBuild Status
mainmain build status
branch-2.3branch-2.3 build status
branch-2.2branch-2.2 build status
branch-2.1branch-2.1 build status
branch-2.0branch-2.0 build status
branch-1.9branch-1.9 build status

Bug tracking: Apache Jira

The subdirectories are:

  • c++ - the c++ reader and writer
  • cmake_modules - the cmake modules
  • docker - docker scripts to build and test on various linuxes
  • examples - various ORC example files that are used to test compatibility
  • java - the java reader and writer
  • site - the website and documentation
  • tools - the c++ tools for reading and inspecting ORC files

Building

  • Install java 17 or higher
  • Install maven 3.9.9 or higher
  • Install cmake 3.25.0 or higher
  • Install meson 1.3.0 or higher (Optional)

To build a release version with debug information:

% mkdir build
% cd build
% cmake ..
% make package
% make test-out

To build a debug version:

% mkdir build
% cd build
% cmake .. -DCMAKE_BUILD_TYPE=DEBUG
% make package
% make test-out

To build a release version without debug information:

% mkdir build
% cd build
% cmake .. -DCMAKE_BUILD_TYPE=RELEASE
% make package
% make test-out

To build only the Java library:

% cd java
% ./mvnw package

To build only the C++ library:

% mkdir build
% cd build
% cmake .. -DBUILD_JAVA=OFF
% make package
% make test-out

To build the C++ library with AVX512 enabled:

export ORC_USER_SIMD_LEVEL=AVX512
% mkdir build
% cd build
% cmake .. -DBUILD_JAVA=OFF -DBUILD_ENABLE_AVX512=ON
% make package
% make test-out

Cmake option BUILD_ENABLE_AVX512 can be set to “ON” or (default value)“OFF” at the compile time. At compile time, it defines the SIMD level(AVX512) to be compiled into the binaries.

Environment variable ORC_USER_SIMD_LEVEL can be set to “AVX512” or (default value)“NONE” at the run time. At run time, it defines the SIMD level to dispatch the code which can apply SIMD optimization.

Note that if ORC_USER_SIMD_LEVEL is set to “NONE” at run time, AVX512 will not take effect at run time even if BUILD_ENABLE_AVX512 is set to “ON” at compile time.

Building with Meson

While CMake is the official build system for orc, there is unofficial support for using Meson to build select parts of the project. To build a debug version of the library and test it using Meson, from the project root you can run:

meson setup build
meson compile -C build
meson test -C build

By default, Meson will build unoptimized libraries with debug symbols. By contrast, the CMake build system generates release libraries by default. If you would like to create release libraries ala CMake, you should set the buildtype option. You must either remove the existing build directory before changing that setting, or alternatively pass the --reconfigure flag:

meson setup build -Dbuildtype=release --reconfigure
meson compile -C build
meson test -C build

Meson supports running your test suite through valgrind out of the box:

meson test -C build --wrap=valgrind

If you'd like to enable sanitizers, you can leverage the -Db_sanitize= option. For example, to enable both ASAN and UBSAN, you can run:

meson setup build -Dbuildtype=debug -Db_sanitize=address,undefined --reconfigure
meson compile -C build
meson test

Meson takes care of detecting all dependencies on your system, and downloading missing ones as required through its Wrap system. The dependencies for the project are all stored in the subprojects directory in individual wrap files. The majority of these are system generated files created by running:

meson wrap install <depencency_name>

From the project root. If you are developing orc and need to add a new dependency in the future, be sure to check Meson's WrapDB to check if a pre-configured wrap entry exists. If not, you may still manually configure the dependency as outlined in the aforementioned Wrap system documentation.