Skip to content

Commit f9c6b34

Browse files
committed
CHANGELOG, docs
1 parent c0a8bfe commit f9c6b34

12 files changed

Lines changed: 57 additions & 650 deletions

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ All notable changes to this project will be documented in this file. It uses the
3636
`&&` (`hasAny`).
3737
* Array slice syntax (`arr[L:U]`, `arr[:U]`, `arr[L:]`) now pushes down
3838
as `arraySlice()`.
39+
* Added pushdown for [pg_re2] extension functions to their ClickHouse
40+
equivalents (e.g., `re2match``match`, `re2extractall``extractAll`).
3941

4042
### ⬆️ Dependency Updates
4143

@@ -52,6 +54,8 @@ All notable changes to this project will be documented in this file. It uses the
5254
`string_to_array(3-arg)` now evaluate locally instead of being pushed to
5355
ClickHouse where they would fail.
5456

57+
[pg_re2]: https://github.com/ClickHouse/pg_re2
58+
"pg_re2: ClickHouse-compatible regex functions using RE2"
5559
[v0.1.11]: https://github.com/ClickHouse/pg_clickhouse/compare/v0.1.10...v0.1.11
5660

5761
## [v0.1.10] — 2026-04-06

META.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
"requires": {
1818
"PostgreSQL": "13.0.0"
1919
}
20+
},
21+
"recommends": {
22+
"re2": "0.1.0"
2023
}
2124
},
2225
"provides": {

doc/pg_clickhouse.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,32 @@ any of these functions cannot be pushed down they will raise an exception.
10881088

10891089
* [dictGet](https://clickhouse.com/docs/sql-reference/functions/ext-dict-functions#dictget-dictgetordefault-dictgetornull)
10901090

1091+
### Extension Pushdown
1092+
1093+
pg_clickhouse recognizes functions from select core and third-party extensions,
1094+
pushing them down to their ClickHouse equivalents.
1095+
1096+
#### [pg_re2]
1097+
1098+
All [pg_re2] functions push down 1:1 to ClickHouse:
1099+
1100+
* `re2match` → [match](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#match)
1101+
* `re2extract` → [extract](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#extract)
1102+
* `re2extractall` → [extractAll](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#extractAll)
1103+
* `re2regexpextract` → [regexpExtract](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#regexpExtract)
1104+
* `re2extractgroups` → [extractGroups](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#extractGroups)
1105+
* `re2replaceregexpone` → [replaceRegexpOne](https://clickhouse.com/docs/sql-reference/functions/string-replace-functions#replaceRegexpOne)
1106+
* `re2replaceregexpall` → [replaceRegexpAll](https://clickhouse.com/docs/sql-reference/functions/string-replace-functions#replaceRegexpAll)
1107+
* `re2countmatches` → [countMatches](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#countMatches)
1108+
* `re2countmatchescaseinsensitive` → [countMatchesCaseInsensitive](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#countMatchesCaseInsensitive)
1109+
* `re2multimatchany` → [multiMatchAny](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#multiMatchAny)
1110+
* `re2multimatchanyindex` → [multiMatchAnyIndex](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#multiMatchAnyIndex)
1111+
* `re2multimatchallindices` → [multiMatchAllIndices](https://clickhouse.com/docs/sql-reference/functions/string-search-functions#multiMatchAllIndices)
1112+
1113+
#### [intarray]
1114+
1115+
* `idx` → [indexOf](https://clickhouse.com/docs/sql-reference/functions/array-functions#indexOf)
1116+
10911117
### Pushdown Casts
10921118

10931119
pg_clickhouse pushes down casts such as `CAST(x AS bigint)` for compatible
@@ -1323,3 +1349,7 @@ Copyright (c) 2025-2026, ClickHouse.
13231349
[Postgres flags]: https://www.postgresql.org/docs/18/functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE
13241350
"PostgreSQL Docs: ARE Embedded-Option Letters"
13251351
[RE2 Regular Expressions]: https://github.com/google/re2/wiki/Syntax "RE2 Syntax"
1352+
[pg_re2]: https://github.com/ClickHouse/pg_re2
1353+
"pg_re2: ClickHouse-compatible regex functions using RE2"
1354+
[intarray]: https://www.postgresql.org/docs/current/intarray.html
1355+
"PostgreSQL Docs: intarray"

test/expected/re2_functions.out

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
SELECT EXISTS(SELECT 1 FROM pg_available_extensions WHERE name = 're2') AS have_re2 \gset
2+
\if :have_re2
13
CREATE SERVER re2_svr FOREIGN DATA WRAPPER clickhouse_fdw OPTIONS(dbname 're2_test');
24
CREATE USER MAPPING FOR CURRENT_USER SERVER re2_svr;
35
SELECT clickhouse_raw_query('DROP DATABASE IF EXISTS re2_test');
@@ -144,3 +146,6 @@ SELECT clickhouse_raw_query('DROP DATABASE re2_test');
144146

145147
DROP SERVER re2_svr CASCADE;
146148
NOTICE: drop cascades to foreign table t1
149+
\else
150+
\echo 'SKIP: re2 extension not available'
151+
\endif

test/expected/re2_functions_1.out

Lines changed: 6 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,42 @@
1+
SELECT EXISTS(SELECT 1 FROM pg_available_extensions WHERE name = 're2') AS have_re2 \gset
2+
\if :have_re2
13
CREATE SERVER re2_svr FOREIGN DATA WRAPPER clickhouse_fdw OPTIONS(dbname 're2_test');
24
CREATE USER MAPPING FOR CURRENT_USER SERVER re2_svr;
35
SELECT clickhouse_raw_query('DROP DATABASE IF EXISTS re2_test');
4-
clickhouse_raw_query
5-
----------------------
6-
7-
(1 row)
8-
96
SELECT clickhouse_raw_query('CREATE DATABASE re2_test');
10-
clickhouse_raw_query
11-
----------------------
12-
13-
(1 row)
14-
157
SELECT clickhouse_raw_query($$
168
CREATE TABLE re2_test.t1 (
179
id Int32,
1810
val String
1911
) ENGINE = MergeTree ORDER BY id
2012
$$);
21-
clickhouse_raw_query
22-
----------------------
23-
24-
(1 row)
25-
2613
SELECT clickhouse_raw_query($$
2714
INSERT INTO re2_test.t1 VALUES
2815
(1, 'POSIX uses BRE and ERE'),
2916
(2, 're2 uses finite automata'),
3017
(3, 'PCRE supports backtracking')
3118
$$);
32-
clickhouse_raw_query
33-
----------------------
34-
35-
(1 row)
36-
3719
CREATE SCHEMA re2_test;
3820
IMPORT FOREIGN SCHEMA re2_test FROM SERVER re2_svr INTO re2_test;
3921
SET search_path = re2_test, public;
4022
CREATE EXTENSION re2;
41-
ERROR: extension "re2" is not available
42-
HINT: The extension must first be installed on the system where PostgreSQL is running.
4323
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2match(val, 're2');
44-
ERROR: function re2match(text, unknown) does not exist
45-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2match(v...
46-
^
47-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
4824
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2extract(val, '(re2)') = 're2';
49-
ERROR: function re2extract(text, unknown) does not exist
50-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2extract...
51-
^
52-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
5325
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2extractall(val, '[A-Z]+') = ARRAY['POSIX','BRE','ERE'];
54-
ERROR: function re2extractall(text, unknown) does not exist
55-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2extract...
56-
^
57-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
5826
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2regexpextract(val, '(re2)', 1) = 're2';
59-
ERROR: function re2regexpextract(text, unknown, integer) does not exist
60-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2regexpe...
61-
^
62-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
6327
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2extractgroups(val, '(POSIX) uses (BRE)') = ARRAY['POSIX','BRE'];
64-
ERROR: function re2extractgroups(text, unknown) does not exist
65-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2extract...
66-
^
67-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
6828
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2replaceregexpone(val, 'POSIX', 're2') = 're2 uses BRE and ERE';
69-
ERROR: function re2replaceregexpone(text, unknown, unknown) does not exist
70-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2replace...
71-
^
72-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
7329
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2replaceregexpall(val, ' ', '-') = 're2-uses-finite-automata';
74-
ERROR: function re2replaceregexpall(text, unknown, unknown) does not exist
75-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2replace...
76-
^
77-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
7830
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2countmatches(val, 'e') > 0;
79-
ERROR: function re2countmatches(text, unknown) does not exist
80-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2countma...
81-
^
82-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
8331
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2countmatchescaseinsensitive(val, 'E') > 0;
84-
ERROR: function re2countmatchescaseinsensitive(text, unknown) does not exist
85-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2countma...
86-
^
87-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
8832
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2multimatchany(val, ARRAY['POSIX','PCRE']);
89-
ERROR: function re2multimatchany(text, text[]) does not exist
90-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2multima...
91-
^
92-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
9333
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2multimatchanyindex(val, ARRAY['POSIX','PCRE']) > 0;
94-
ERROR: function re2multimatchanyindex(text, text[]) does not exist
95-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2multima...
96-
^
97-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
9834
EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2multimatchallindices(val, ARRAY['POSIX','PCRE']) = ARRAY[1];
99-
ERROR: function re2multimatchallindices(text, text[]) does not exist
100-
LINE 1: ...PLAIN (VERBOSE, COSTS OFF) SELECT * FROM t1 WHERE re2multima...
101-
^
102-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
10335
DROP EXTENSION re2;
104-
ERROR: extension "re2" does not exist
10536
DROP USER MAPPING FOR CURRENT_USER SERVER re2_svr;
10637
SELECT clickhouse_raw_query('DROP DATABASE re2_test');
107-
clickhouse_raw_query
108-
----------------------
109-
110-
(1 row)
111-
11238
DROP SERVER re2_svr CASCADE;
113-
NOTICE: drop cascades to foreign table t1
39+
\else
40+
\echo 'SKIP: re2 extension not available'
41+
SKIP: re2 extension not available
42+
\endif

test/expected/re2_functions_2.out

Lines changed: 0 additions & 114 deletions
This file was deleted.

0 commit comments

Comments
 (0)