--- warning: DO NOT CHANGE THIS MANUALLY, THIS IS GENERATED BY https://github.com/duckdb/community-extensions repository, check README there title: urlpattern excerpt: | DuckDB Community Extensions WHATWG URLPattern API for matching and extracting components from URLs using pattern syntax extension: name: urlpattern description: WHATWG URLPattern API for matching and extracting components from URLs using pattern syntax version: 0.4.3 language: C++ build: cmake license: MIT excluded_platforms: "wasm_mvp;wasm_eh;wasm_threads;windows_amd64;windows_amd64_mingw" vcpkg_commit: "68a1c387f660632f2f65cdb7e8cd093a08840e5d" maintainers: - teaguesterling repo: github: teaguesterling/duckdb_urlpattern # THE THREE KEYS NOW MEAN DIFFERENT THINGS THAN THEY DID WHEN THIS DESCRIPTOR WAS # LAST TOUCHED. #3079 (merged 2026-10-15) changed build.yml's default duckdb_version # from the v1.5.6 tag to a pinned DuckDB commit, so per scripts/build.py:42-54: # # ref -> the DEFAULT build, i.e. the DuckDB 2.0 line today # variegata -> the DuckDB v1.5.6 build. NOTE: this path has no skip branch, so # without this key a v1.5.6 build silently falls back to `ref`. # andium -> the DuckDB v1.4.5 track (left where it was; v0.4.x targets v1.5+) # # ref = v0.4.3, which fixes the v2.0 build. variegata = v0.4.2 DELIBERATELY: see below. ref: 0e14b580454ea92ff0120bdbac9ab836c407bd1b variegata: 0b7dae3e564ffdaeb90f36407c8ab97e56d1175b ref_next: 0e14b580454ea92ff0120bdbac9ab836c407bd1b andium: bc9864b9fad37bffe15f7499fc5b9021e970eaf8 # # WHAT v0.4.3 FIXES. urlpattern_init, url_build and url_modify take NAMED arguments # (`url_build(protocol := 'https')`). DuckDB 2.0 changed both how such a function is # declared and how it learns its argument names, and only the first was a compile error: # * SimpleFunction::varargs is gone. 2.0 splits it into AddArgs (VAR_POSITIONAL, # "*args") and AddKwargs (VAR_KEYWORD, "**kwargs"). These functions take keyword # arguments, so they declare AddKwargs plus SetRequiresExpressionNames(true) -- # the same way DuckDB's own union_value is declared. Declaring *args instead # COMPILES CLEANLY and then fails at load ("A function signature can only have # one '*args' parameter"), so this could not be verified by building alone. # * Argument NAMES moved off aliases. On v1.5 a named argument's name is an alias on # the bound child (GetAlias()); on 2.0 aliases are empty and names come from # BindFunctionInput::GetArgumentNames(). Code that kept reading GetAlias() compiles # on 2.0 and then treats every argument as positional -- silently wrong. # CORRECTION to this descriptor's previous comment, which claimed 2.0 moved varargs # "behind Get/SetVarArgs": SetVarArgs NEVER LANDED. Probing for it silently selected # the v1.5 branch, which is why the build failed at duckdb_compat.hpp:221 rather than # taking a v2.0 path. # # WHY variegata < ref (the clickhouse_scanner pattern, not finetype's). v0.4.3 builds # and passes on BOTH lines -- 0 errors and 162 assertions each, verified against # b15358c371daf10dad799a43b6167f6ccdce84d8 (this registry's default) and against the # repo's v1.5 pin b155d6f63ce. But the repo's v1.5 pin is v1.5.4-154, NOT the v1.5.6 # tag that this key builds, so there is no direct v1.5.6 evidence for v0.4.3. v0.4.2 is # the released v1.5.6 line marker and is the commit this descriptor's `ref` named until # now, i.e. exactly what v1.5.6 users already run (0b7dae3e, the raw commit for # refs/tags/v0.4.2 -- NOT the annotated tag object dd0e7367, which the registry # cannot resolve). Since v0.4.3 # changes nothing user-visible on v1.5, pinning variegata here costs them nothing and # asserts only what was measured. Advance variegata once a v1.5.6 build is confirmed. # # ref_next == ref so test_against_latest builds this release rather than skipping the # prerelease leg ("Skipping prerelease validation" passes green having verified nothing). docs: hello_world: | -- Test if a URL matches a pattern SELECT urlpattern_test('https://example.com/users/:id', 'https://example.com/users/123'); -- true -- Extract a named group from a URL SELECT urlpattern_extract('https://example.com/users/:id', 'https://example.com/users/123', 'id'); -- '123' -- Get full match results with all components SELECT urlpattern_exec('/posts/:slug', '/posts/hello-world'); -- {matched: true, pathname: '/posts/hello-world', groups: {slug: 'hello-world'}, ...} -- Use the URLPATTERN type for validated patterns SELECT urlpattern_test(urlpattern('/api/:version/*'), '/api/v2/users/list'); -- true extended_description: | The URLPattern extension implements the [WHATWG URLPattern API](https://urlpattern.spec.whatwg.org/) for DuckDB, enabling powerful URL matching, extraction, parsing, and construction. ## Features - **Custom URLPATTERN type** with validation and implicit casting from VARCHAR - **Pattern matching** with named groups (`:name`), wildcards (`*`), and regex groups - **URL parsing** into components (protocol, host, path, query, hash) - **URL building** and modification from components - **Query parameter extraction** as MAP or individual values - **Pattern caching** for improved performance (~320k matches/sec) ## Key Functions | Function | Description | |----------|-------------| | `urlpattern_test(pattern, url)` | Test if URL matches pattern | | `urlpattern_extract(pattern, url, group)` | Extract a named group | | `urlpattern_exec(pattern, url)` | Get full match results as STRUCT | | `url_parse(url)` | Parse URL into struct with all components | | `url_build(...)` | Build URL from named components | | `url_modify(url, ...)` | Modify existing URL components | | `url_search_params(url)` | Get query parameters as MAP | ## Pattern Syntax URLPattern uses a syntax similar to Express.js routes: - `:name` - Named parameter (matches any segment) - `*` - Wildcard (matches everything) - `/path/:id` - Path-only patterns match any protocol/host For full documentation, see [duckdb-urlpattern.readthedocs.io](https://duckdb-urlpattern.readthedocs.io/). extension_star_count: 9 extension_star_count_pretty: 9 extension_download_count: 1157 extension_download_count_pretty: 1.2k image: '/images/community_extensions/social_preview/preview_community_extension_urlpattern.png' layout: community_extension_doc --- ### Compatibility Matrix This table covers all DuckDB releases that have not reached [end-of-life](https://duckdb.org/release_calendar), including LTS releases, and shows the 2 most recent patch releases of each. Older patch releases are not listed, but the extension may be available for them as well.
| Platform | 1.4.4 | 1.4.5 | 1.5.5 | 1.5.6 | 2.0.0 | | :--- | :---: | :---: | :---: | :---: | :---: | | Linux AMD64 | ✅ | ❌ | ✅ | ✅ | ✅ | | Linux ARM64 | ✅ | ❌ | ✅ | ✅ | ✅ | | macOS AMD64 | ✅ | ❌ | ✅ | ✅ | ✅ | | macOS ARM64 | ✅ | ❌ | ✅ | ✅ | ✅ | | Windows AMD64 | ❌ | ❌ | ❌ | ❌ | ❌ | | Windows ARM64 | ❌ | ❌ | ❌ | ❌ | ❌ | | WebAssembly | ❌ | ❌ | ❌ | ❌ | ❌ | ### Installing and Loading ```sql INSTALL {{ page.extension.name }} FROM community; LOAD {{ page.extension.name }}; ``` {% if page.docs.hello_world %} ### Example ```sql {{ page.docs.hello_world }}``` {% endif %} {% if page.docs.extended_description %} ### About {{ page.extension.name }} {{ page.docs.extended_description }} {% endif %} ### Added Functions | function_name | function_type | description | comment | examples | |---------------------|---------------|-----------------------------------------------------------------------------------------|---------|---------------------------------------------------------------------------------| | url_build | scalar | Build a URL string from named component parameters. | NULL | [url_build(protocol := 'https', hostname := 'example.com', pathname := '/api')] | | url_hash | scalar | Get the hash/fragment component of a URL. | NULL | [url_hash('https://example.com#section')] | | url_host | scalar | Get the host (hostname and port) component of a URL. | NULL | [url_host('https://example.com:8080')] | | url_hostname | scalar | Get the hostname component of a URL. | NULL | [url_hostname('https://example.com:8080')] | | url_href | scalar | Get the normalized full href of a URL. | NULL | [url_href('https://example.com/path')] | | url_modify | scalar | Modify components of an existing URL string. | NULL | [url_modify('https://example.com/api', pathname := '/v2')] | | url_origin | scalar | Get the origin (scheme + host) of a URL. | NULL | [url_origin('https://example.com/path')] | | url_parse | scalar | Parse a URL string into a STRUCT of its components. | NULL | [url_parse('https://user:pass@example.com:8080/path?q=1#hash')] | | url_password | scalar | Get the password component of a URL. | NULL | [url_password('https://user:pass@example.com')] | | url_pathname | scalar | Get the pathname component of a URL. | NULL | [url_pathname('https://example.com/api/v1')] | | url_port | scalar | Get the port component of a URL. | NULL | [url_port('https://example.com:8080')] | | url_protocol | scalar | Get the protocol component of a URL. | NULL | [url_protocol('https://example.com')] | | url_resolve | scalar | Resolve a relative URL against a base URL. | NULL | [url_resolve('https://example.com/dir/', '../other')] | | url_search | scalar | Get the query string component of a URL. | NULL | [url_search('https://example.com?q=1')] | | url_search_param | scalar | Extract the value of a specific query parameter from a URL. | NULL | [url_search_param('https://example.com?a=1&b=2', 'a')] | | url_search_params | scalar | Extract all query search parameters from a URL as a MAP. | NULL | [url_search_params('https://example.com?a=1&b=2')] | | url_username | scalar | Get the username component of a URL. | NULL | [url_username('https://user:pass@example.com')] | | url_valid | scalar | Check if a URL string is valid. | NULL | [url_valid('https://example.com')] | | urlpattern | scalar | Construct a URLPATTERN from a pattern string. | NULL | [urlpattern('/users/:id')] | | urlpattern_exec | scalar | Execute pattern matching on a URL and return matched components and groups as a STRUCT. | NULL | [urlpattern_exec(urlpattern('/users/:id'), '/users/123')] | | urlpattern_extract | scalar | Extract matched component value from a URL using URLPattern. | NULL | [urlpattern_extract(urlpattern('/users/:id'), '/users/123', 'id')] | | urlpattern_hash | scalar | Get the hash/fragment pattern of a URLPattern. | NULL | [urlpattern_hash(urlpattern('https://example.com/*#*'))] | | urlpattern_hostname | scalar | Get the hostname pattern of a URLPattern. | NULL | [urlpattern_hostname(urlpattern('https://example.com/*'))] | | urlpattern_init | scalar | Initialize a URLPATTERN with named component patterns. | NULL | [urlpattern_init(pathname := '/users/:id')] | | urlpattern_pathname | scalar | Get the pathname pattern of a URLPattern. | NULL | [urlpattern_pathname(urlpattern('/users/:id'))] | | urlpattern_port | scalar | Get the port pattern of a URLPattern. | NULL | [urlpattern_port(urlpattern('https://example.com:8080/*'))] | | urlpattern_protocol | scalar | Get the protocol pattern of a URLPattern. | NULL | [urlpattern_protocol(urlpattern('https://example.com/*'))] | | urlpattern_search | scalar | Get the search/query pattern of a URLPattern. | NULL | [urlpattern_search(urlpattern('https://example.com/*?q=*'))] | | urlpattern_test | scalar | Test if a URL matches a URLPattern. | NULL | [urlpattern_test(urlpattern('/users/:id'), '/users/123')] | ### Overloaded Functions This extension does not add any function overloads. ### Added Types | type_name | type_size | logical_type | type_category | internal | |------------|----------:|--------------|---------------|----------| | URLPATTERN | 16 | VARCHAR | STRING | true | ### Added Settings | name | description | input_type | scope | aliases | typed_value | |----------------|---------------------------------------------------------|------------|--------|---------|-------------| | temp_directory | Set the directory to which temporary files are written. | VARCHAR | GLOBAL | [] | post.db.tmp |