Problem
On Darwin arm64, linking code that writes std::optional<uint64_t> to an IOutputStream fails with an undefined symbol:
ld64.lld: error: undefined symbol: void Out<std::__y1::optional<unsigned long long>>(IOutputStream&, std::__y1::optional<unsigned long long> const&)
This is currently reachable from ydb/library/yql/providers/pq/async_io/dq_pq_read_actor.cpp, which logs a std::optional<uint64_t> value.
Steps to reproduce
Tested on Apple Silicon at main commit 2de8cf3cfb50dcb0e87661142affb799042cfa98.
-
Add this focused case to the TestOutput suite in util/stream/output_ut.cpp:
Y_UNIT_TEST(TestOptionalUint64) {
UNIT_ASSERT_VALUES_EQUAL(TStringBuilder() << std::optional<std::uint64_t>{42}, "42");
UNIT_ASSERT_VALUES_EQUAL(TStringBuilder() << std::optional<std::uint64_t>{}, "(NULL)");
}
-
Build the unit-test binary:
./ya make --build relwithdebinfo util/stream/ut
The link fails with the undefined symbol shown above. The same missing symbol was also observed at the final link of ydb/core/kqp/ut/query through the existing PQ caller.
Root cause
util/stream/output.cpp explicitly instantiates optional output for ui64. On 64-bit Darwin, ui64 is unsigned long, while Clang defines uint64_t as unsigned long long, so these are distinct template specializations. The file already carries an analogous Darwin arm64 specialization for std::int64_t, but not for std::uint64_t.
Fix
Add DEF_OPTIONAL(std::uint64_t) next to the existing Darwin arm64 std::int64_t specialization and cover both present and empty optional values with a focused regression test.
Problem
On Darwin arm64, linking code that writes
std::optional<uint64_t>to anIOutputStreamfails with an undefined symbol:This is currently reachable from
ydb/library/yql/providers/pq/async_io/dq_pq_read_actor.cpp, which logs astd::optional<uint64_t>value.Steps to reproduce
Tested on Apple Silicon at
maincommit2de8cf3cfb50dcb0e87661142affb799042cfa98.Add this focused case to the
TestOutputsuite inutil/stream/output_ut.cpp:Build the unit-test binary:
The link fails with the undefined symbol shown above. The same missing symbol was also observed at the final link of
ydb/core/kqp/ut/querythrough the existing PQ caller.Root cause
util/stream/output.cppexplicitly instantiates optional output forui64. On 64-bit Darwin,ui64isunsigned long, while Clang definesuint64_tasunsigned long long, so these are distinct template specializations. The file already carries an analogous Darwin arm64 specialization forstd::int64_t, but not forstd::uint64_t.Fix
Add
DEF_OPTIONAL(std::uint64_t)next to the existing Darwin arm64std::int64_tspecialization and cover both present and empty optional values with a focused regression test.