From 0931b9fdfbec5bbe4eb9520956ae9b2268dd121b Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Wed, 20 May 2026 21:07:41 +0200 Subject: [PATCH 1/6] polyfill: drop premature 'using meosType = MeosType' alias (from open PR #161) Cherry-picked from open PR #161 so this PR's CI compiles against the vcpkg-installed MEOS, which exposes 'meosType' (pre-consolidation) not 'MeosType'. When #161 reaches main, this commit collapses to a no-op on rebase. --- src/include/tydef.hpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/include/tydef.hpp b/src/include/tydef.hpp index b7b28109..b9860ca0 100644 --- a/src/include/tydef.hpp +++ b/src/include/tydef.hpp @@ -11,11 +11,27 @@ extern "C" { #include } -// Forward-compat alias for the meosType → MeosType rename (MobilityDB -// pr785-sync-script). Vcpkg's MEOS exposes `MeosType`; existing -// MobilityDuck code still uses `meosType`. This alias bridges the two -// without touching every reference site. -using meosType = MeosType; +// MEOS naming history: `meosType` is the **pre-consolidation** spelling +// and `MeosType` is the **post-consolidation** target (the rename is +// part of the upstream consolidation sweep, not yet reached by the +// vcpkg pin). The current pin +// (`vcpkg_ports/meos/portfile.cmake` REF f11b7443ee98…) is still +// pre-consolidation and exposes `meosType` — see +// meos/include/temporal/meos_catalog.h, where line 121 declares +// `} meosType;`. MobilityDuck's source consistently uses +// `meosType` (verified via `grep -rn '\bmeosType\b' src/`), which +// matches the pin, so no alias is needed today. +// +// An earlier version of this file added `using meosType = MeosType;` +// as a forward-looking bridge for the eventual consolidation bump. +// That alias references `MeosType`, which the current pin does NOT +// yet expose, so it broke the build: +// "'MeosType' does not name a type; did you mean 'meosType'?". +// +// When the MEOS pin is bumped past the consolidation point, restore +// a bridge here (`using meosType = MeosType;` becomes valid then) or +// sweep the source `meosType → MeosType` in one PR — whichever the +// project prefers at that time. namespace duckdb { From 22dbf62c3dfea71c9199235eaf69d9c482ce5669 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Wed, 20 May 2026 21:07:41 +0200 Subject: [PATCH 2/6] polyfill(ci): stage icu extension for amd64 docker tests (from open PR #136) Cherry-picked from open PR #136 so this PR's amd64 Linux test phase goes green before #136 lands. When #136 reaches main, this rebase collapses to a no-op. --- Makefile | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bc17d050..ab8cf2ee 100644 --- a/Makefile +++ b/Makefile @@ -11,9 +11,32 @@ include extension-ci-tools/makefiles/duckdb_extension.Makefile # both MEOS (meos_initialize_timezone) and DuckDB (DBConfig::SetOptionByName # "TimeZone") to Europe/Brussels. Tests pass on any OS timezone — the # extension is the single source of truth, no TZ env var needed. +# +# LoadInternal also calls ExtensionHelper::AutoLoadExtension(db, "icu") so +# the timezone option is honoured. Autoload looks for the extension on disk +# at $HOME/.duckdb/extensions///icu.duckdb_extension +# and falls back to a hub download. Inside the linux_amd64 test docker +# container that path is empty and there is no network egress, so the +# autoload fails. We copy the icu.duckdb_extension that was built locally +# as part of this extension's build (declared in extension_config.cmake) +# into the expected path before running the unittester. +DUCKDB_VERSION_TAG := v1.4.4 + +define stage_icu + @if [ -f ./build/$(1)/extension/icu/icu.duckdb_extension ]; then \ + platform=$$(uname -m | sed 's/x86_64/linux_amd64/;s/aarch64/linux_arm64/'); \ + target=$$HOME/.duckdb/extensions/$(DUCKDB_VERSION_TAG)/$$platform; \ + mkdir -p "$$target" && cp -f ./build/$(1)/extension/icu/icu.duckdb_extension "$$target/" && \ + echo "Staged icu.duckdb_extension at $$target/"; \ + fi +endef + test_release_internal: + $(call stage_icu,release) ./build/release/$(TEST_PATH) "$(PROJ_DIR)test/*" test_debug_internal: + $(call stage_icu,debug) ./build/debug/$(TEST_PATH) "$(PROJ_DIR)test/*" test_reldebug_internal: - ./build/reldebug/$(TEST_PATH) "$(PROJ_DIR)test/*" \ No newline at end of file + $(call stage_icu,reldebug) + ./build/reldebug/$(TEST_PATH) "$(PROJ_DIR)test/*" From 4949535969e67c4b703b44aa0f3ebfe149096ba3 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Wed, 20 May 2026 21:27:47 +0200 Subject: [PATCH 3/6] polyfill(macos/wasm): bigint_to_set_duckdb int64_t forwarder (from open PR #140) Cherry-picked from open PR #140 so this PR's osx_amd64 / osx_arm64 / wasm builds compile. On macOS LP64 and Wasm/emscripten, int64 (long) and int64_t (long long) are the same width but distinct types; clang rejects passing bigint_to_set where Set *(*)(int64_t) is expected. The cast is a no-op on Linux. When #140 reaches main, this rebase collapses to a no-op. --- src/temporal/set.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/temporal/set.cpp b/src/temporal/set.cpp index b803498a..1858e489 100644 --- a/src/temporal/set.cpp +++ b/src/temporal/set.cpp @@ -945,6 +945,14 @@ static inline Set *date_to_set_duckdb(DateADT d) { return date_to_set(ToMeosDate(duckdb::date_t(d))); } +// macOS LP64: int64 (long) and int64_t (long long) are the same width but +// distinct types, so clang rejects passing bigint_to_set where a +// Set *(*)(int64_t) is expected as a non-type template arg. The cast is a +// no-op on Linux. See SetUnionScalarFunction below. +static inline Set *bigint_to_set_duckdb(int64_t i) { + return bigint_to_set(static_cast(i)); +} + struct SetPtrState { Set *accumulated; }; @@ -1069,7 +1077,7 @@ void SetTypes::RegisterSetUnionAgg(ExtensionLoader &loader) { LogicalType::INTEGER, SetTypes::intset())); set_union_set.AddFunction( AggregateFunction::UnaryAggregateDestructor>( + SetUnionScalarFunction>( LogicalType::BIGINT, SetTypes::bigintset())); set_union_set.AddFunction( AggregateFunction::UnaryAggregateDestructor Date: Wed, 20 May 2026 23:12:10 +0200 Subject: [PATCH 4/6] fix(span_table_functions): explicit unique_ptr -> unique_ptr in Copy() GCC + DuckDB 1.4.4's unique_ptr does not implicitly convert derived->base, so 'return r;' in BinsBindData::Copy() fails to compile: error: could not convert 'r' from 'unique_ptr' to 'unique_ptr' Use duckdb's unique_ptr_cast helper (from duckdb/common/helper.hpp) to do the conversion explicitly, matching the canonical pattern used by DuckDB core (e.g. table_scan.hpp's TableScanBindData::Copy()). No behaviour change; the move is exactly what the implicit conversion would have done if the compiler accepted it. --- src/temporal/span_table_functions.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/temporal/span_table_functions.cpp b/src/temporal/span_table_functions.cpp index 92b3091e..df424346 100644 --- a/src/temporal/span_table_functions.cpp +++ b/src/temporal/span_table_functions.cpp @@ -44,7 +44,9 @@ struct BinsBindData : public FunctionData { r->blob = blob; r->vsize = vsize; r->vorigin = vorigin; - return r; + // DuckDB 1.4.4 disallows implicit derived->base unique_ptr conversion; + // explicit base-type construction from the moved-from derived pointer. + return unique_ptr_cast(std::move(r)); } bool Equals(const FunctionData &other_p) const override { auto &other = other_p.Cast(); From a23a5b25879bf05f5c66f0241f0c76a9296ff4a4 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Thu, 21 May 2026 12:08:58 +0200 Subject: [PATCH 5/6] fix(extension): skip MEOS timezone init when no zoneinfo on system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `meos_initialize_timezone("Europe/Brussels")` calls into MEOS's pgtz code which opens `/usr/share/zoneinfo` to load the timezone database. On minimal containers (Alpine/musl, edge-device runtimes) zoneinfo is not installed by default and the call surfaces: could not open directory "/usr/share/zoneinfo": No such file or directory …which then aborts the test runner downstream (see musl probe PR #172, linux_amd64_musl row). Guards the call with a portable `stat` check on the canonical zoneinfo directory; if not present, the extension loads against MEOS's default (UTC) instead of erroring at startup. This is the lightweight extension-side counterpart to the upstream extension-ci-tools fix (`apk add tzdata` in the linux_amd64_musl Dockerfile) — both unblock the musl probe. Either alone is sufficient; having both gives belt-and-suspenders coverage and lets the extension load on any tzdata-less host. Verified locally: build/release/extension/mobilityduck/mobilityduck.duckdb_extension links; on a host with `/usr/share/zoneinfo` present, behaviour is unchanged (Brussels TZ still set, asText output shows `+01` in winter dates). --- src/mobilityduck_extension.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/mobilityduck_extension.cpp b/src/mobilityduck_extension.cpp index 0eb7ebd4..f9b8f101 100644 --- a/src/mobilityduck_extension.cpp +++ b/src/mobilityduck_extension.cpp @@ -220,8 +220,17 @@ static void LoadInternal(ExtensionLoader &loader) { /* Set the MEOS timezone to Europe/Brussels so that all temporal-type * text I/O uses a consistent, named timezone on every platform. * Brussels is a non-UTC zone that surfaces bugs hidden by UTC (e.g. - * off-by-one-hour errors in timestamp handling). */ - meos_initialize_timezone("Europe/Brussels"); + * off-by-one-hour errors in timestamp handling). + * + * Skip the timezone init when no IANA timezone database is present + * on the system (Alpine/musl images, minimal containers, edge + * devices). Without `/usr/share/zoneinfo`, MEOS's pgtz code + * fails on `opendir`; skipping the timezone init lets the + * extension load against UTC instead of erroring at startup. */ + struct stat tz_st {}; + if (stat("/usr/share/zoneinfo", &tz_st) == 0 && (tz_st.st_mode & S_IFDIR)) { + meos_initialize_timezone("Europe/Brussels"); + } meos_initialize_error_handler(&MobilityduckMeosErrorHandler); }); From 4ce3492c93e73d4f6e3bc12e372c08ccd8e0c9ee Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Sat, 16 May 2026 11:04:41 +0200 Subject: [PATCH 6/6] Stage icu for the macOS osx_arm64 test path too The stage_icu helper mapped only the Linux uname values, so on the macOS arm64 test runner uname -m returned "arm64" and the icu extension was copied to .duckdb/extensions/v1.4.4/arm64 instead of .../osx_arm64, where DuckDB's autoload looks. The hub fallback is not reliably resolvable on that runner, so the osx_arm64 Test step failed to load the extension. Map the OS and architecture to the DuckDB platform string (linux_amd64, linux_arm64, osx_amd64, osx_arm64) so the locally built icu is staged at the path autoload expects on every tested platform; the Linux mapping is unchanged. Co-Authored-By: Claude Opus 4.7 --- Makefile | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index ab8cf2ee..a9485498 100644 --- a/Makefile +++ b/Makefile @@ -15,16 +15,23 @@ include extension-ci-tools/makefiles/duckdb_extension.Makefile # LoadInternal also calls ExtensionHelper::AutoLoadExtension(db, "icu") so # the timezone option is honoured. Autoload looks for the extension on disk # at $HOME/.duckdb/extensions///icu.duckdb_extension -# and falls back to a hub download. Inside the linux_amd64 test docker -# container that path is empty and there is no network egress, so the -# autoload fails. We copy the icu.duckdb_extension that was built locally -# as part of this extension's build (declared in extension_config.cmake) -# into the expected path before running the unittester. +# and falls back to a hub download. That fails both inside the linux_amd64 +# test docker container (empty path, no network egress) and on the macOS +# osx_arm64 test runner (hub icu not reliably resolvable). We copy the +# icu.duckdb_extension that was built locally as part of this extension's +# build (declared in extension_config.cmake) into the expected path, +# matched to the DuckDB platform string, before running the unittester. DUCKDB_VERSION_TAG := v1.4.4 define stage_icu @if [ -f ./build/$(1)/extension/icu/icu.duckdb_extension ]; then \ - platform=$$(uname -m | sed 's/x86_64/linux_amd64/;s/aarch64/linux_arm64/'); \ + case "$$(uname -s)-$$(uname -m)" in \ + Linux-x86_64) platform=linux_amd64 ;; \ + Linux-aarch64) platform=linux_arm64 ;; \ + Darwin-arm64) platform=osx_arm64 ;; \ + Darwin-x86_64) platform=osx_amd64 ;; \ + *) platform=$$(uname -m) ;; \ + esac; \ target=$$HOME/.duckdb/extensions/$(DUCKDB_VERSION_TAG)/$$platform; \ mkdir -p "$$target" && cp -f ./build/$(1)/extension/icu/icu.duckdb_extension "$$target/" && \ echo "Staged icu.duckdb_extension at $$target/"; \