Repository navigation
Releases
v0.4.3 — DuckDB 2.0 named-argument compatibility
Compatibility release. No behaviour changes on the v1.5 line; the same source tree now also builds and binds correctly on DuckDB 2.0.
What this fixes
urlpattern_init, url_build and url_modify take named arguments (url_build(protocol := 'https')). DuckDB 2.0 changed how such a function is declared and how it learns its argument names, and only the first half was a compile error.
- Declaration.
SimpleFunction::varargsis gone. 2.0 splits it into two parameter kinds:AddArgs(VAR_POSITIONAL,*args) andAddKwargs(VAR_KEYWORD,**kwargs). These functions take keyword arguments, so they now declareAddKwargsplusSetRequiresExpressionNames(true)— matching how DuckDB's ownunion_valueis declared. - Argument names. On v1.5 a named argument's name is an alias on the bound child (
GetAlias()). On 2.0 aliases are empty and names arrive viaBindFunctionInput::GetArgumentNames(). A bind body that kept readingGetAlias()would compile on 2.0 and then treat every argument as positional — silently wrong. Both sources are now resolved once into a single list, with positional arguments normalised to the empty string so the bind bodies read identically on both lines.
Verification
Both lines, one source tree, on a 36-core host:
DuckDB 2.0 b15358c371d |
v1.5 line b155d6f63ce |
|
|---|---|---|
| build | 0 errors | 0 errors |
| tests | 162 assertions, all passed | 162 assertions, all passed |
url_build(protocol := 'https', hostname := 'example.com', pathname := '/api') |
https://example.com/api |
identical |
url_modify('https://example.com/api', pathname := '/v2') |
https://example.com/v2 |
identical |
urlpattern_init(pathname := '/users/:id') |
init:A=/users/:id; |
identical |
b15358c371daf10dad799a43b6167f6ccdce84d8 is the community registry's current default DuckDB (duckdb/community-extensions#3079).
Negative control, because a clean build is not evidence here: declaring *args instead of **kwargs compiles with zero errors and then fails at load with *"A function signature can only have one 'args' parameter". The correctness claim above rests on the queries, not the build.
Closes #14. See #15 for the full discussion, including two C++ traps (GetAlias() returning Identifier on 2.0 in a non-template overload compiled on both lines, and two-phase lookup rejecting the name Identifier inside a discarded if constexpr branch).
v0.4.2 — v1.5.6 line marker (retroactive)
Marks the commit the community registry has been serving as urlpattern 0.4.2.
This tag is retroactive: the descriptor published version 0.4.2 from this commit,
but no v0.4.2 tag existed, so the v1.5-line release point was only findable as a
bare SHA. Created ahead of DuckDB 2.0.0 (2026-10-21), after which the registry's
ref field targets the v2.0 line and v1.5 builds move to the new variegata
field — which needs a findable commit for any v1.5.6 bugfix release.
No code change; this is the same tree the registry already serves.
v0.4.1 — DuckDB v1.5.x compatibility
Compatibility + CI update over 0.4.0:
- Use
BaseExpression::GetAlias()accessor for DuckDB main/v1.5.5 compatibility. - Bump duckdb + extension-ci-tools to v1.5-variegata; build stable leg against the v1.5.4 release tag; re-enable Windows.
- Regression coverage for the issue #5 fixes (percent-decode, init ';').
Fixes the missing community build for DuckDB v1.5.5 (the previous listing pinned a pre-compat commit). Test suite green (162 assertions).
v0.4.0 — Correctness & hardening (issue #5)
Correctness & hardening (issue #5)
- Query params are now percent-decoded.
ParseQueryStringpreviously returned raw substrings, sourl_search_params('...?q=hello%20world')['q']yieldedhello%20world. It now decodes%XXand+→space, matching WHATWG URLSearchParams. init:serialization no longer truncates on;. A component value containing;(e.g.search := 'a;b') was silently cut at the delimiter; the encoding is now escaped/length-safe.- Case-insensitivity self-test. The provider compensates for an inverted
set_case_sensitivein DuckDB's RE2 wrapper; a self-test now asserts the compensation so a future upstream fix can't silently invertignore_case. - Bounded pattern cache. The per-local-state pattern cache is now size-capped (LRU) so a query with many distinct large patterns can't grow memory unbounded.
urlpattern_extractNULL semantics. No-match / group-absent / empty-value are now distinguishable instead of all returning''.
(Regression tests confirming the percent-decode and init: ';' fixes have since landed on main and will roll into the next release.)
DuckDB v1.5.4
Built against DuckDB v1.5.4; ReDoS-immune by construction (patterns compile to RE2, linear-time). Stable builds green on all platforms.
Known follow-up
The duckdb-next-build leg (DuckDB main/v1.6) does not yet compile — BaseExpression::alias became a protected Identifier and needs GetAlias(). Tracked separately; does not affect this v1.5.4 release.
v0.3.1
Update for DuckDB v1.5 compatibility.
v0.3.0 - DuckDB v1.4.4 Support
What's New
- Updated to DuckDB v1.4.4
- Updated extension-ci-tools to v1.4.4
Supported Platforms
- Linux AMD64
- Linux ARM64
- Linux AMD64 (musl)
- macOS AMD64
- macOS ARM64
Installation
INSTALL urlpattern FROM community;
LOAD urlpattern;v0.1.0 - Initial Release
DuckDB URLPattern Extension v0.1.0
Initial release of the URLPattern extension for DuckDB, implementing the WHATWG URLPattern API.
Features
- Custom URLPATTERN type with validation and implicit casting from VARCHAR
- Pattern matching:
urlpattern_test(pattern, url)- test if a URL matches a pattern - Group extraction:
urlpattern_extract(pattern, url, group_name)- extract named groups - Full match results:
urlpattern_exec(pattern, url)- returns STRUCT with all match details - Pattern accessors:
urlpattern_pathname(),urlpattern_protocol(),urlpattern_hostname(),urlpattern_port(),urlpattern_search(),urlpattern_hash() - Pattern caching for improved performance on repeated patterns
Quick Start
-- Load the extension
LOAD urlpattern;
-- Test if URLs match a pattern
SELECT urlpattern_test('https://example.com/users/:id', 'https://example.com/users/123');
-- true
-- Extract named groups
SELECT urlpattern_extract('https://example.com/users/:id', 'https://example.com/users/123', 'id');
-- '123'
-- Get full match results
SELECT urlpattern_exec('/posts/:slug', '/posts/hello-world');
-- {matched: true, pathname: '/posts/hello-world', groups: {slug: 'hello-world'}, ...}Supported Platforms
| Platform | Status |
|---|---|
| Linux (amd64) | ✅ |
| Linux (arm64) | ✅ |
| Linux (musl) | ✅ |
| macOS (amd64) | ✅ |
| macOS (arm64) | ✅ |
| Windows | ❌ (MinGW compatibility issue) |
| WASM | ❌ (emscripten compiler issue) |
Installation
Download the appropriate extension for your platform from the release assets, or build from source.
Documentation
See the documentation for full API reference.