From 7584f7ccaecf2be1c48da04bac8f39c1f1372488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 29 Jul 2025 18:40:58 +0000 Subject: [PATCH 1/9] update ci --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c22521d..ba161f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,13 +11,13 @@ jobs: strategy: fail-fast: false matrix: - pg: [14, 13, 12, 11] + pg: [17, 16, 15, 14, 13, 12, 11] check_code: ["false", "clang"] name: Test clickhouse_fdw runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Pull `clickhouse` run: docker compose pull clickhouse - name: Run `clickhouse` From 20ca0272ef78bcbc3155ca7362b7f3108638335a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 29 Jul 2025 19:27:57 +0000 Subject: [PATCH 2/9] fix text to cstring --- src/clickhouse-cpp/clickhouse/types/types.h | 1 + src/clickhouse_fdw.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/clickhouse-cpp/clickhouse/types/types.h b/src/clickhouse-cpp/clickhouse/types/types.h index bb608a0..da69377 100644 --- a/src/clickhouse-cpp/clickhouse/types/types.h +++ b/src/clickhouse-cpp/clickhouse/types/types.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace clickhouse { diff --git a/src/clickhouse_fdw.c b/src/clickhouse_fdw.c index 1c2722e..27a1b1c 100644 --- a/src/clickhouse_fdw.c +++ b/src/clickhouse_fdw.c @@ -49,6 +49,11 @@ PG_MODULE_MAGIC; +#if PG_VERSION_NUM >= 100000 +#define textDatumToCString text_to_cstring +#else +#define TextDatumGetCString text_to_cstring +#endif /* Default CPU cost to start up a foreign query. */ #define DEFAULT_FDW_STARTUP_COST 100.0 @@ -296,10 +301,10 @@ void _PG_init(void){} Datum clickhousedb_raw_query(PG_FUNCTION_ARGS) { - char *connstring = TextDatumGetCString(PG_GETARG_TEXT_P(1)), - *query = TextDatumGetCString(PG_GETARG_TEXT_P(0)); + char *connstring = text_to_cstring(PG_GETARG_TEXT_P(1)), + *query = text_to_cstring(PG_GETARG_TEXT_P(0)); - ch_connection_details *details = connstring_parse(connstring); + ch_connection_details *details = connstring_parse(connstring); ch_connection conn = chfdw_http_connect(details); ch_cursor *cursor = conn.methods->simple_query(conn.conn, query); text *res = chfdw_http_fetch_raw_data(cursor); From e6b07aac8e415e843c7bd3e70136d0b1be5bb704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 29 Jul 2025 20:33:10 +0000 Subject: [PATCH 3/9] expected _2 --- src/clickhouse_fdw.c | 6 - tests/expected/binary_queries_2.out | 748 +++++++++++++++++++++++++++ tests/expected/http_2.out | 773 ++++++++++++++++++++++++++++ 3 files changed, 1521 insertions(+), 6 deletions(-) create mode 100644 tests/expected/binary_queries_2.out create mode 100644 tests/expected/http_2.out diff --git a/src/clickhouse_fdw.c b/src/clickhouse_fdw.c index 27a1b1c..0a6f970 100644 --- a/src/clickhouse_fdw.c +++ b/src/clickhouse_fdw.c @@ -49,12 +49,6 @@ PG_MODULE_MAGIC; -#if PG_VERSION_NUM >= 100000 -#define textDatumToCString text_to_cstring -#else -#define TextDatumGetCString text_to_cstring -#endif - /* Default CPU cost to start up a foreign query. */ #define DEFAULT_FDW_STARTUP_COST 100.0 diff --git a/tests/expected/binary_queries_2.out b/tests/expected/binary_queries_2.out new file mode 100644 index 0000000..32e2bbe --- /dev/null +++ b/tests/expected/binary_queries_2.out @@ -0,0 +1,748 @@ +CREATE EXTENSION clickhouse_fdw; +SET datestyle = 'ISO'; +CREATE SERVER loopback FOREIGN DATA WRAPPER clickhouse_fdw OPTIONS(dbname 'regression', driver 'binary'); +CREATE SERVER loopback2 FOREIGN DATA WRAPPER clickhouse_fdw OPTIONS(dbname 'regression', driver 'binary'); +CREATE USER MAPPING FOR CURRENT_USER SERVER loopback; +CREATE USER MAPPING FOR CURRENT_USER SERVER loopback2; +SELECT clickhousedb_raw_query('DROP DATABASE IF EXISTS regression'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE DATABASE regression'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE TABLE regression.t1 + (c1 Int, c2 Int, c3 String, c4 Date, c5 Date, c6 String, c7 String, c8 String) + ENGINE = MergeTree PARTITION BY c4 ORDER BY (c1); +'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE TABLE regression.t2 (c1 Int, c2 String) + ENGINE = MergeTree PARTITION BY c1 % 10000 ORDER BY (c1);'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE TABLE regression.t3 (c1 Int, c3 String) + ENGINE = MergeTree PARTITION BY c1 % 10000 ORDER BY (c1);'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE TABLE regression.t4 (c1 Int, c2 Int, c3 String) + ENGINE = MergeTree PARTITION BY c1 % 10000 ORDER BY (c1);'); + clickhousedb_raw_query +------------------------ + +(1 row) + +CREATE FOREIGN TABLE ft1 ( + c0 int, + c1 int NOT NULL, + c2 int NOT NULL, + c3 text, + c4 date, + c5 date, + c6 varchar(10), + c7 char(10) default 'ft1', + c8 text +) SERVER loopback OPTIONS (table_name 't1'); +ALTER FOREIGN TABLE ft1 DROP COLUMN c0; +CREATE FOREIGN TABLE ft2 ( + c1 int NOT NULL, + c2 text NOT NULL +) SERVER loopback OPTIONS (table_name 't2'); +CREATE FOREIGN TABLE ft3 ( + c1 int NOT NULL, + c3 text +) SERVER loopback OPTIONS (table_name 't3'); +CREATE FOREIGN TABLE ft4 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER loopback OPTIONS (table_name 't4'); +CREATE FOREIGN TABLE ft5 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER loopback OPTIONS (table_name 't4'); +CREATE FOREIGN TABLE ft6 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER loopback2 OPTIONS (table_name 't4'); +select clickhousedb_raw_query($$ + INSERT INTO regression.t1 + SELECT number, + number % 10, + toString(number), + toDate('1990-01-01'), + toDate('1990-01-01'), + number % 10, + number % 10, + 'foo' + FROM numbers(1, 110);$$); + clickhousedb_raw_query +------------------------ + +(1 row) + +select clickhousedb_raw_query($$ + INSERT INTO regression.t2 + SELECT number, + concat('AAA', toString(number)) + FROM numbers(1, 100);$$); + clickhousedb_raw_query +------------------------ + +(1 row) + +select clickhousedb_raw_query($$ + INSERT INTO regression.t4 + SELECT number, + number + 1, + concat('AAA', toString(number)) + FROM numbers(1, 100);$$); + clickhousedb_raw_query +------------------------ + +(1 row) + +/* escape sequences */ +INSERT INTO ft3 VALUES (1, E'lf\ntab\t\b\f\r'); +SELECT c3, (c3 = E'lf\ntab\t\b\f\r') AS true FROM ft3 WHERE c1 = 1; + c3 | true +--------------------+------ + lf +| t + tab \x08\x0C\r | +(1 row) + +INSERT INTO ft3 VALUES (2, 'lf\ntab\t\b\f\r'); +SELECT c3, (c3 = 'lf\ntab\t\b\f\r') AS true FROM ft3 WHERE c1 = 2; + c3 | true +-----------------+------ + lf\ntab\t\b\f\r | t +(1 row) + +\set VERBOSITY terse +SELECT c3, c4 FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work + c3 | c4 +----+------------ + 1 | 1990-01-01 +(1 row) + +ALTER SERVER loopback OPTIONS (SET dbname 'no such database'); +SELECT c3, c4 FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should fail +ERROR: clickhouse_fdw: DB::Exception: Database `no such database` doesn't exist +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback OPTIONS (ADD user 'no such user'); +SELECT c3, c4 FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should fail +ERROR: clickhouse_fdw: connection error: DB::Exception: no such user: Authentication failed: password is incorrect or there is no user with such name +ALTER SERVER loopback OPTIONS (SET dbname 'regression'); +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback OPTIONS (DROP user); +SELECT c3, c4 FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work again + c3 | c4 +----+------------ + 1 | 1990-01-01 +(1 row) + +\set VERBOSITY default +ANALYZE ft1; +EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c1 OFFSET 100 LIMIT 10; + QUERY PLAN +--------------------- + Foreign Scan on ft1 +(1 row) + +SELECT * FROM ft1 ORDER BY c1 OFFSET 100 LIMIT 10; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +-----+----+-----+------------+------------+----+----+----- + 101 | 1 | 101 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 102 | 2 | 102 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 103 | 3 | 103 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 104 | 4 | 104 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 105 | 5 | 105 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 106 | 6 | 106 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 107 | 7 | 107 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 108 | 8 | 108 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 109 | 9 | 109 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 110 | 0 | 110 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo +(10 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c1, t1.tableoid OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid + -> Sort + Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid + Sort Key: t1.c1, t1.tableoid + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 +(8 rows) + +SELECT * FROM ft1 t1 ORDER BY t1.c1, t1.tableoid OFFSET 100 LIMIT 10; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +-----+----+-----+------------+------------+----+----+----- + 101 | 1 | 101 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 102 | 2 | 102 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 103 | 3 | 103 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 104 | 4 | 104 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 105 | 5 | 105 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 106 | 6 | 106 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 107 | 7 | 107 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 108 | 8 | 108 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 109 | 9 | 109 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 110 | 0 | 110 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo +(10 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: t1.*, c1 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 ORDER BY c1 ASC LIMIT 10 OFFSET 100 +(3 rows) + +SELECT t1 FROM ft1 t1 ORDER BY t1.c1 OFFSET 100 LIMIT 10; + t1 +------------------------------------------- + (101,1,101,1990-01-01,1990-01-01,1,1,foo) + (102,2,102,1990-01-01,1990-01-01,2,2,foo) + (103,3,103,1990-01-01,1990-01-01,3,3,foo) + (104,4,104,1990-01-01,1990-01-01,4,4,foo) + (105,5,105,1990-01-01,1990-01-01,5,5,foo) + (106,6,106,1990-01-01,1990-01-01,6,6,foo) + (107,7,107,1990-01-01,1990-01-01,7,7,foo) + (108,8,108,1990-01-01,1990-01-01,8,8,foo) + (109,9,109,1990-01-01,1990-01-01,9,9,foo) + (110,0,110,1990-01-01,1990-01-01,0,0,foo) +(10 rows) + +SELECT * FROM ft1 WHERE false; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +----+----+----+----+----+----+----+---- +(0 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c7 >= '1')) AND ((c1 = 101)) AND ((c6 = '1')) +(3 rows) + +SELECT COUNT(*) FROM ft1 t1; + count +------- + 110 +(1 row) + +SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c2 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +----+----+----+----+----+----+----+---- +(0 rows) + +SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c2) FROM ft2 t2) ORDER BY c1; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +----+----+----+----+----+----+----+---- +(0 rows) + +WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c2 FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; + c1 | c2 | c2 +----+-------+------- + 1 | AAA1 | AAA1 + 2 | AAA2 | AAA2 + 3 | AAA3 | AAA3 + 4 | AAA4 | AAA4 + 5 | AAA5 | AAA5 + 6 | AAA6 | AAA6 + 7 | AAA7 | AAA7 + 8 | AAA8 | AAA8 + 9 | AAA9 | AAA9 + 10 | AAA10 | AAA10 +(10 rows) + +SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1; + ?column? | ?column? +----------+---------- + fixed | +(1 row) + +SET enable_hashjoin TO false; +SET enable_nestloop TO false; +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 JOIN ft1 t2 ON (t1.c1 = t2.c1) OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan + Output: t1.c1, t2.c1 + Relations: (ft2 t1) INNER JOIN (ft1 t2) + Remote SQL: SELECT r1.c1, r2.c1 FROM regression.t2 r1 ALL INNER JOIN regression.t1 r2 ON (((r1.c1 = r2.c1))) LIMIT 10 OFFSET 100 +(4 rows) + +SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10; + c1 | c1 +----+---- + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | 6 + 7 | 7 + 8 | 8 + 9 | 9 + 10 | 10 +(10 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan + Output: t1.c1, t2.c1 + Relations: (ft2 t1) LEFT JOIN (ft1 t2) + Remote SQL: SELECT r1.c1, r2.c1 FROM regression.t2 r1 ALL LEFT JOIN regression.t1 r2 ON (((r1.c1 = r2.c1))) LIMIT 10 OFFSET 100 +(4 rows) + +EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------- + Limit (cost=-0.99..-0.98 rows=1 width=8) + -> Unique (cost=-0.99..-0.98 rows=1 width=8) + -> Sort (cost=-0.99..-0.98 rows=1 width=1) + Sort Key: t1.c1, t2.c1 + -> Foreign Scan (cost=1.00..-1.00 rows=1 width=1) + Relations: (ft2 t1) LEFT JOIN (ft1 t2) +(6 rows) + +SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10; + c1 | c1 +----+---- + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | 6 + 7 | 7 + 8 | 8 + 9 | 9 + 10 | 10 +(10 rows) + +RESET enable_hashjoin; +RESET enable_nestloop; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 1; -- Var, OpExpr(b), Const + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 = 1)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 100 AND t1.c2 = 0; -- BoolExpr + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 = 100)) AND ((c2 = 0)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NULL; -- NullTest + QUERY PLAN +--------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 IS NULL)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL; -- NullTest + QUERY PLAN +------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 IS NOT NULL)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((round(abs(c1), 0) = 1)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- OpExpr(l) + QUERY PLAN +---------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 = (- c1))) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = factorial(c1); -- OpExpr(r) + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((1 = factorial(c1))) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE (((c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL))) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((has([c2, 1, (c1 + 0)],c1))) +(3 rows) + +SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]) ORDER BY c1; -- ScalarArrayOpExpr + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +-----+----+-----+------------+------------+----+----+----- + 1 | 1 | 1 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 2 | 2 | 2 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 3 | 3 | 3 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 4 | 4 | 4 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 5 | 5 | 5 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 6 | 6 | 6 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 7 | 7 | 7 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 8 | 8 | 8 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 9 | 9 | 9 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 10 | 0 | 10 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 11 | 1 | 11 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 12 | 2 | 12 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 13 | 3 | 13 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 14 | 4 | 14 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 15 | 5 | 15 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 16 | 6 | 16 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 17 | 7 | 17 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 18 | 8 | 18 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 19 | 9 | 19 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 20 | 0 | 20 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 21 | 1 | 21 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 22 | 2 | 22 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 23 | 3 | 23 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 24 | 4 | 24 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 25 | 5 | 25 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 26 | 6 | 26 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 27 | 7 | 27 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 28 | 8 | 28 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 29 | 9 | 29 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 30 | 0 | 30 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 31 | 1 | 31 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 32 | 2 | 32 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 33 | 3 | 33 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 34 | 4 | 34 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 35 | 5 | 35 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 36 | 6 | 36 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 37 | 7 | 37 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 38 | 8 | 38 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 39 | 9 | 39 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 40 | 0 | 40 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 41 | 1 | 41 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 42 | 2 | 42 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 43 | 3 | 43 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 44 | 4 | 44 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 45 | 5 | 45 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 46 | 6 | 46 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 47 | 7 | 47 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 48 | 8 | 48 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 49 | 9 | 49 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 50 | 0 | 50 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 51 | 1 | 51 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 52 | 2 | 52 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 53 | 3 | 53 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 54 | 4 | 54 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 55 | 5 | 55 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 56 | 6 | 56 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 57 | 7 | 57 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 58 | 8 | 58 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 59 | 9 | 59 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 60 | 0 | 60 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 61 | 1 | 61 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 62 | 2 | 62 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 63 | 3 | 63 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 64 | 4 | 64 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 65 | 5 | 65 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 66 | 6 | 66 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 67 | 7 | 67 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 68 | 8 | 68 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 69 | 9 | 69 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 70 | 0 | 70 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 71 | 1 | 71 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 72 | 2 | 72 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 73 | 3 | 73 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 74 | 4 | 74 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 75 | 5 | 75 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 76 | 6 | 76 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 77 | 7 | 77 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 78 | 8 | 78 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 79 | 9 | 79 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 80 | 0 | 80 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 81 | 1 | 81 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 82 | 2 | 82 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 83 | 3 | 83 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 84 | 4 | 84 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 85 | 5 | 85 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 86 | 6 | 86 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 87 | 7 | 87 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 88 | 8 | 88 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 89 | 9 | 89 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 90 | 0 | 90 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 91 | 1 | 91 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 92 | 2 | 92 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 93 | 3 | 93 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 94 | 4 | 94 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 95 | 5 | 95 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 96 | 6 | 96 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 97 | 7 | 97 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 98 | 8 | 98 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 99 | 9 | 99 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 100 | 0 | 100 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 101 | 1 | 101 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 102 | 2 | 102 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 103 | 3 | 103 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 104 | 4 | 104 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 105 | 5 | 105 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 106 | 6 | 106 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 107 | 7 | 107 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 108 | 8 | 108 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 109 | 9 | 109 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 110 | 0 | 110 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo +(110 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- ArrayRef + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 = (([c1, c2, 3])[1]))) +(3 rows) + +SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1] ORDER BY c1; -- ArrayRef + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +-----+----+-----+------------+------------+----+----+----- + 1 | 1 | 1 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 2 | 2 | 2 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 3 | 3 | 3 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 4 | 4 | 4 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 5 | 5 | 5 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 6 | 6 | 6 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 7 | 7 | 7 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 8 | 8 | 8 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 9 | 9 | 9 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 10 | 0 | 10 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 11 | 1 | 11 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 12 | 2 | 12 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 13 | 3 | 13 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 14 | 4 | 14 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 15 | 5 | 15 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 16 | 6 | 16 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 17 | 7 | 17 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 18 | 8 | 18 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 19 | 9 | 19 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 20 | 0 | 20 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 21 | 1 | 21 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 22 | 2 | 22 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 23 | 3 | 23 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 24 | 4 | 24 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 25 | 5 | 25 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 26 | 6 | 26 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 27 | 7 | 27 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 28 | 8 | 28 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 29 | 9 | 29 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 30 | 0 | 30 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 31 | 1 | 31 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 32 | 2 | 32 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 33 | 3 | 33 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 34 | 4 | 34 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 35 | 5 | 35 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 36 | 6 | 36 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 37 | 7 | 37 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 38 | 8 | 38 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 39 | 9 | 39 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 40 | 0 | 40 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 41 | 1 | 41 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 42 | 2 | 42 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 43 | 3 | 43 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 44 | 4 | 44 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 45 | 5 | 45 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 46 | 6 | 46 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 47 | 7 | 47 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 48 | 8 | 48 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 49 | 9 | 49 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 50 | 0 | 50 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 51 | 1 | 51 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 52 | 2 | 52 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 53 | 3 | 53 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 54 | 4 | 54 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 55 | 5 | 55 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 56 | 6 | 56 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 57 | 7 | 57 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 58 | 8 | 58 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 59 | 9 | 59 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 60 | 0 | 60 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 61 | 1 | 61 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 62 | 2 | 62 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 63 | 3 | 63 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 64 | 4 | 64 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 65 | 5 | 65 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 66 | 6 | 66 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 67 | 7 | 67 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 68 | 8 | 68 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 69 | 9 | 69 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 70 | 0 | 70 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 71 | 1 | 71 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 72 | 2 | 72 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 73 | 3 | 73 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 74 | 4 | 74 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 75 | 5 | 75 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 76 | 6 | 76 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 77 | 7 | 77 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 78 | 8 | 78 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 79 | 9 | 79 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 80 | 0 | 80 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 81 | 1 | 81 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 82 | 2 | 82 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 83 | 3 | 83 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 84 | 4 | 84 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 85 | 5 | 85 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 86 | 6 | 86 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 87 | 7 | 87 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 88 | 8 | 88 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 89 | 9 | 89 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 90 | 0 | 90 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 91 | 1 | 91 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 92 | 2 | 92 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 93 | 3 | 93 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 94 | 4 | 94 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 95 | 5 | 95 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 96 | 6 | 96 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 97 | 7 | 97 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 98 | 8 | 98 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 99 | 9 | 99 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 100 | 0 | 100 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 101 | 1 | 101 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 102 | 2 | 102 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 103 | 3 | 103 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 104 | 4 | 104 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 105 | 5 | 105 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 106 | 6 | 106 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 107 | 7 | 107 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 108 | 8 | 108 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 109 | 9 | 109 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 110 | 0 | 110 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo +(110 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c6 = E'foo''s\\bar'; -- check special chars + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c6 = E'foo''s\\bar')) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't be sent to remote + QUERY PLAN +--------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c8 = 'foo')) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT (CASE WHEN c1 < 10 THEN 1 WHEN c1 < 50 THEN 2 ELSE 3 END) a, + sum(length(c2)) FROM ft2 GROUP BY a ORDER BY a; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan + Output: (CASE WHEN (c1 < 10) THEN 1 WHEN (c1 < 50) THEN 2 ELSE 3 END), (sum(length(c2))) + Relations: Aggregate on (ft2) + Remote SQL: SELECT CASE WHEN (c1 < 10) THEN toInt32(1) WHEN (c1 < 50) THEN toInt32(2) ELSE toInt32(3) END, sum(length(c2)) FROM regression.t2 GROUP BY (CASE WHEN (c1 < 10) THEN toInt32(1) WHEN (c1 < 50) THEN toInt32(2) ELSE toInt32(3) END) ORDER BY CASE WHEN (c1 < 10) THEN toInt32(1) WHEN (c1 < 50) THEN toInt32(2) ELSE toInt32(3) END ASC +(4 rows) + +SELECT (CASE WHEN c1 < 10 THEN 1 WHEN c1 < 50 THEN 2 ELSE 3 END) a, + sum(length(c2)) FROM ft2 GROUP BY a ORDER BY a; + a | sum +---+----- + 1 | 36 + 2 | 200 + 3 | 256 +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT SUM(c1) FILTER (WHERE c1 < 20) FROM ft2; + QUERY PLAN +--------------------------------------------------------------------- + Foreign Scan + Output: (sum(c1) FILTER (WHERE (c1 < 20))) + Relations: Aggregate on (ft2) + Remote SQL: SELECT sumIf(c1,(((c1 < 20)) > 0)) FROM regression.t2 +(4 rows) + +SELECT SUM(c1) FILTER (WHERE c1 < 20) FROM ft2; + sum +----- + 190 +(1 row) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT COUNT(DISTINCT c1) FROM ft2; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan + Output: (count(DISTINCT c1)) + Relations: Aggregate on (ft2) + Remote SQL: SELECT count(DISTINCT c1) FROM regression.t2 +(4 rows) + +SELECT COUNT(DISTINCT c1) FROM ft2; + count +------- + 100 +(1 row) + +/* DISTINCT with IF */ +EXPLAIN (VERBOSE, COSTS OFF) SELECT COUNT(DISTINCT c1) FILTER (WHERE c1 < 20) FROM ft2; + QUERY PLAN +------------------------------------------------------- + Aggregate + Output: count(DISTINCT c1) FILTER (WHERE (c1 < 20)) + -> Foreign Scan on public.ft2 + Output: c1, c2 + Remote SQL: SELECT c1 FROM regression.t2 ORDER BY c1 ASC +(5 rows) + +DROP USER MAPPING FOR CURRENT_USER SERVER loopback; +DROP USER MAPPING FOR CURRENT_USER SERVER loopback2; +SELECT clickhousedb_raw_query('DROP DATABASE regression'); + clickhousedb_raw_query +------------------------ + +(1 row) + +DROP EXTENSION IF EXISTS clickhouse_fdw CASCADE; +NOTICE: drop cascades to 8 other objects +DETAIL: drop cascades to server loopback +drop cascades to foreign table ft1 +drop cascades to foreign table ft2 +drop cascades to foreign table ft3 +drop cascades to foreign table ft4 +drop cascades to foreign table ft5 +drop cascades to server loopback2 +drop cascades to foreign table ft6 diff --git a/tests/expected/http_2.out b/tests/expected/http_2.out new file mode 100644 index 0000000..ea848ef --- /dev/null +++ b/tests/expected/http_2.out @@ -0,0 +1,773 @@ +CREATE EXTENSION clickhouse_fdw; +SET datestyle = 'ISO'; +CREATE SERVER loopback FOREIGN DATA WRAPPER clickhouse_fdw OPTIONS(dbname 'regression', driver 'http'); +CREATE SERVER loopback2 FOREIGN DATA WRAPPER clickhouse_fdw OPTIONS(dbname 'regression'); +CREATE USER MAPPING FOR CURRENT_USER SERVER loopback; +CREATE USER MAPPING FOR CURRENT_USER SERVER loopback2; +SELECT clickhousedb_raw_query('DROP DATABASE IF EXISTS regression'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE DATABASE regression'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE TABLE regression.t1 + (c1 Int, c2 Int, c3 String, c4 Date, c5 Date, c6 String, c7 String, c8 String) + ENGINE = MergeTree PARTITION BY c4 ORDER BY (c1); +'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE TABLE regression.t2 (c1 Int, c2 String) + ENGINE = MergeTree PARTITION BY c1 % 10000 ORDER BY (c1);'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE TABLE regression.t3 (c1 Int, c3 String) + ENGINE = MergeTree PARTITION BY c1 % 10000 ORDER BY (c1);'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query('CREATE TABLE regression.t4 (c1 Int, c2 Int, c3 String) + ENGINE = MergeTree PARTITION BY c1 % 10000 ORDER BY (c1);'); + clickhousedb_raw_query +------------------------ + +(1 row) + +SELECT clickhousedb_raw_query(' + CREATE TABLE regression.tcopy + (c1 Int32, c2 Int64, c3 Date, c4 Nullable(DateTime), c5 DateTime, c6 String) + ENGINE = MergeTree + PARTITION BY c3 + ORDER BY (c1, c2, c3); +'); + clickhousedb_raw_query +------------------------ + +(1 row) + +CREATE FOREIGN TABLE ft1 ( + c0 int, + c1 int NOT NULL, + c2 int NOT NULL, + c3 text, + c4 date, + c5 date, + c6 varchar(10), + c7 char(10) default 'ft1', + c8 text +) SERVER loopback OPTIONS (table_name 't1'); +ALTER FOREIGN TABLE ft1 DROP COLUMN c0; +CREATE FOREIGN TABLE ft2 ( + c1 int NOT NULL, + c2 text NOT NULL +) SERVER loopback OPTIONS (table_name 't2'); +CREATE FOREIGN TABLE ft3 ( + c1 int NOT NULL, + c3 text +) SERVER loopback OPTIONS (table_name 't3'); +CREATE FOREIGN TABLE ft4 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER loopback OPTIONS (table_name 't4'); +CREATE FOREIGN TABLE ft5 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER loopback OPTIONS (table_name 't4'); +CREATE FOREIGN TABLE ft6 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER loopback2 OPTIONS (table_name 't4'); +CREATE FOREIGN TABLE ftcopy ( + c1 int, + c2 int8, + c3 date, + c4 timestamp without time zone, + c5 time, + c6 text +) SERVER loopback OPTIONS (table_name 'tcopy'); +INSERT INTO ft1 + SELECT id, + id % 10, + to_char(id, 'FM00000'), + '1990-01-01', + '1990-01-01', + id % 10, + id % 10, + 'foo' + FROM generate_series(1, 110) id; +INSERT INTO ft2 + SELECT id, + 'AAA' || to_char(id, 'FM000') + FROM generate_series(1, 100) id; +INSERT INTO ft3 VALUES (1, E'lf\ntab\t\b\f\r'); +SELECT c3, (c3 = E'lf\ntab\t\b\f\r') AS true FROM ft3 WHERE c1 = 1; + c3 | true +--------------------+------ + lf +| t + tab \x08\x0C\r | +(1 row) + +INSERT INTO ft3 VALUES (2, 'lf\ntab\t\b\f\r'); +SELECT c3, (c3 = 'lf\ntab\t\b\f\r') AS true FROM ft3 WHERE c1 = 2; + c3 | true +-----------------+------ + lf\ntab\t\b\f\r | t +(1 row) + +INSERT INTO ft4 + SELECT id, + id + 1, + 'AAA' || to_char(id, 'FM000') + FROM generate_series(1, 100) id; +COPY ftcopy FROM stdin; +INSERT INTO ftcopy VALUES + (3, 4, '1990-03-03', '1990-03-03 12:02:02', '12:02:02', 'val3'), + (4, 5, '1991-04-04', '1990-04-04 12:04:04', '12:02:04', 'val4'), + (5, 6, '1991-04-04', NULL, '12:02:05', 'val5'); +EXPLAIN (VERBOSE) SELECT * FROM ftcopy ORDER BY c1; + QUERY PLAN +----------------------------------------------------------------------------------- + Foreign Scan on public.ftcopy (cost=1.00..-0.50 rows=1 width=64) + Output: c1, c2, c3, c4, c5, c6 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6 FROM regression.tcopy ORDER BY c1 ASC +(3 rows) + +SELECT * FROM ftcopy ORDER BY c1; + c1 | c2 | c3 | c4 | c5 | c6 +----+----+------------+---------------------+----------+------ + 1 | 2 | 1990-01-01 | 1990-01-01 10:01:02 | 10:01:02 | val1 + 2 | 3 | 1990-02-02 | 1990-02-02 11:02:03 | 11:01:02 | val2 + 3 | 4 | 1990-03-03 | 1990-03-03 12:02:02 | 12:02:02 | val3 + 4 | 5 | 1991-04-04 | 1990-04-04 12:04:04 | 12:02:04 | val4 + 5 | 6 | 1991-04-04 | | 12:02:05 | val5 +(5 rows) + +SELECT c3, c4 FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work + c3 | c4 +-------+------------ + 00001 | 1990-01-01 +(1 row) + +ALTER SERVER loopback OPTIONS (SET dbname 'no such database'); +SELECT c3, c4 FROM ft1 ORDER BY c3, c1; -- should fail +ERROR: clickhouse_fdw:Code: 81. DB::Exception: Database `no such database` doesn't exist. (UNKNOWN_DATABASE) +QUERY:SELECT c1, c3, c4 FROM "no such database".t1 ORDER BY c3 ASC, c1 ASC +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback OPTIONS (ADD user 'no such user'); +SELECT c3, c4 FROM ft1 ORDER BY c3, c1; -- should fail +ERROR: clickhouse_fdw:Code: 516. DB::Exception: no such user: Authentication failed: password is incorrect or there is no user with such name. (AUTHENTICATION_FAILED) +QUERY:SELECT c1, c3, c4 FROM "no such database".t1 ORDER BY c3 ASC, c1 ASC +ALTER SERVER loopback OPTIONS (SET dbname 'regression'); +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback OPTIONS (DROP user); +SELECT c3, c4 FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work again + c3 | c4 +-------+------------ + 00001 | 1990-01-01 +(1 row) + +ANALYZE ft1; +EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; + QUERY PLAN +--------------------- + Foreign Scan on ft1 +(1 row) + +SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +-----+----+-------+------------+------------+----+------------+----- + 101 | 1 | 00101 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 102 | 2 | 00102 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 103 | 3 | 00103 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 104 | 4 | 00104 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 105 | 5 | 00105 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 106 | 6 | 00106 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 107 | 7 | 00107 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 108 | 8 | 00108 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 109 | 9 | 00109 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 110 | 0 | 00110 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo +(10 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid + -> Sort + Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid + Sort Key: t1.c3, t1.c1, t1.tableoid + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 +(8 rows) + +SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +-----+----+-------+------------+------------+----+------------+----- + 101 | 1 | 00101 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 102 | 2 | 00102 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 103 | 3 | 00103 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 104 | 4 | 00104 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 105 | 5 | 00105 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 106 | 6 | 00106 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 107 | 7 | 00107 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 108 | 8 | 00108 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 109 | 9 | 00109 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 110 | 0 | 00110 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo +(10 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: t1.*, c3, c1 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 ORDER BY c3 ASC, c1 ASC LIMIT 10 OFFSET 100 +(3 rows) + +SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + t1 +-------------------------------------------------------- + (101,1,00101,1990-01-01,1990-01-01,1,"1 ",foo) + (102,2,00102,1990-01-01,1990-01-01,2,"2 ",foo) + (103,3,00103,1990-01-01,1990-01-01,3,"3 ",foo) + (104,4,00104,1990-01-01,1990-01-01,4,"4 ",foo) + (105,5,00105,1990-01-01,1990-01-01,5,"5 ",foo) + (106,6,00106,1990-01-01,1990-01-01,6,"6 ",foo) + (107,7,00107,1990-01-01,1990-01-01,7,"7 ",foo) + (108,8,00108,1990-01-01,1990-01-01,8,"8 ",foo) + (109,9,00109,1990-01-01,1990-01-01,9,"9 ",foo) + (110,0,00110,1990-01-01,1990-01-01,0,"0 ",foo) +(10 rows) + +SELECT * FROM ft1 WHERE false; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +----+----+----+----+----+----+----+---- +(0 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c7 >= '1')) AND ((c1 = 101)) AND ((c6 = '1')) +(3 rows) + +SELECT COUNT(*) FROM ft1 t1; + count +------- + 110 +(1 row) + +SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c2 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +----+----+----+----+----+----+----+---- +(0 rows) + +SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c2) FROM ft2 t2) ORDER BY c1; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +----+----+----+----+----+----+----+---- +(0 rows) + +WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c2 FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; + c1 | c2 | c2 +----+--------+-------- + 1 | AAA001 | AAA001 + 2 | AAA002 | AAA002 + 3 | AAA003 | AAA003 + 4 | AAA004 | AAA004 + 5 | AAA005 | AAA005 + 6 | AAA006 | AAA006 + 7 | AAA007 | AAA007 + 8 | AAA008 | AAA008 + 9 | AAA009 | AAA009 + 10 | AAA010 | AAA010 +(10 rows) + +SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1; + ?column? | ?column? +----------+---------- + fixed | +(1 row) + +SET enable_hashjoin TO false; +SET enable_nestloop TO false; +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 JOIN ft1 t2 ON (t1.c1 = t2.c1) OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan + Output: t1.c1, t2.c1 + Relations: (ft2 t1) INNER JOIN (ft1 t2) + Remote SQL: SELECT r1.c1, r2.c1 FROM regression.t2 r1 ALL INNER JOIN regression.t1 r2 ON (((r1.c1 = r2.c1))) LIMIT 10 OFFSET 100 +(4 rows) + +SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10; + c1 | c1 +----+---- + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | 6 + 7 | 7 + 8 | 8 + 9 | 9 + 10 | 10 +(10 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan + Output: t1.c1, t2.c1 + Relations: (ft2 t1) LEFT JOIN (ft1 t2) + Remote SQL: SELECT r1.c1, r2.c1 FROM regression.t2 r1 ALL LEFT JOIN regression.t1 r2 ON (((r1.c1 = r2.c1))) LIMIT 10 OFFSET 100 +(4 rows) + +EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------- + Limit (cost=-0.99..-0.98 rows=1 width=8) + -> Unique (cost=-0.99..-0.98 rows=1 width=8) + -> Sort (cost=-0.99..-0.98 rows=1 width=1) + Sort Key: t1.c1, t2.c1 + -> Foreign Scan (cost=1.00..-1.00 rows=1 width=1) + Relations: (ft2 t1) LEFT JOIN (ft1 t2) +(6 rows) + +SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10; + c1 | c1 +----+---- + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | 6 + 7 | 7 + 8 | 8 + 9 | 9 + 10 | 10 +(10 rows) + +RESET enable_hashjoin; +RESET enable_nestloop; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 1; -- Var, OpExpr(b), Const + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 = 1)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 100 AND t1.c2 = 0; -- BoolExpr + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 = 100)) AND ((c2 = 0)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NULL; -- NullTest + QUERY PLAN +--------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 IS NULL)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL; -- NullTest + QUERY PLAN +------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 IS NOT NULL)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((round(abs(c1), 0) = 1)) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- OpExpr(l) + QUERY PLAN +---------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 = (- c1))) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = factorial(c1); -- OpExpr(r) + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((1 = factorial(c1))) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE (((c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL))) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((has([c2, 1, (c1 + 0)],c1))) +(3 rows) + +SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]) ORDER BY c1; -- ScalarArrayOpExpr + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +-----+----+-------+------------+------------+----+------------+----- + 1 | 1 | 00001 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 2 | 2 | 00002 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 3 | 3 | 00003 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 4 | 4 | 00004 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 5 | 5 | 00005 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 6 | 6 | 00006 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 7 | 7 | 00007 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 8 | 8 | 00008 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 9 | 9 | 00009 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 10 | 0 | 00010 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 11 | 1 | 00011 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 12 | 2 | 00012 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 13 | 3 | 00013 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 14 | 4 | 00014 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 15 | 5 | 00015 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 16 | 6 | 00016 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 17 | 7 | 00017 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 18 | 8 | 00018 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 19 | 9 | 00019 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 20 | 0 | 00020 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 21 | 1 | 00021 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 22 | 2 | 00022 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 23 | 3 | 00023 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 24 | 4 | 00024 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 25 | 5 | 00025 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 26 | 6 | 00026 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 27 | 7 | 00027 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 28 | 8 | 00028 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 29 | 9 | 00029 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 30 | 0 | 00030 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 31 | 1 | 00031 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 32 | 2 | 00032 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 33 | 3 | 00033 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 34 | 4 | 00034 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 35 | 5 | 00035 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 36 | 6 | 00036 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 37 | 7 | 00037 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 38 | 8 | 00038 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 39 | 9 | 00039 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 40 | 0 | 00040 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 41 | 1 | 00041 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 42 | 2 | 00042 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 43 | 3 | 00043 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 44 | 4 | 00044 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 45 | 5 | 00045 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 46 | 6 | 00046 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 47 | 7 | 00047 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 48 | 8 | 00048 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 49 | 9 | 00049 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 50 | 0 | 00050 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 51 | 1 | 00051 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 52 | 2 | 00052 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 53 | 3 | 00053 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 54 | 4 | 00054 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 55 | 5 | 00055 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 56 | 6 | 00056 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 57 | 7 | 00057 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 58 | 8 | 00058 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 59 | 9 | 00059 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 60 | 0 | 00060 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 61 | 1 | 00061 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 62 | 2 | 00062 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 63 | 3 | 00063 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 64 | 4 | 00064 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 65 | 5 | 00065 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 66 | 6 | 00066 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 67 | 7 | 00067 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 68 | 8 | 00068 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 69 | 9 | 00069 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 70 | 0 | 00070 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 71 | 1 | 00071 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 72 | 2 | 00072 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 73 | 3 | 00073 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 74 | 4 | 00074 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 75 | 5 | 00075 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 76 | 6 | 00076 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 77 | 7 | 00077 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 78 | 8 | 00078 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 79 | 9 | 00079 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 80 | 0 | 00080 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 81 | 1 | 00081 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 82 | 2 | 00082 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 83 | 3 | 00083 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 84 | 4 | 00084 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 85 | 5 | 00085 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 86 | 6 | 00086 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 87 | 7 | 00087 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 88 | 8 | 00088 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 89 | 9 | 00089 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 90 | 0 | 00090 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 91 | 1 | 00091 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 92 | 2 | 00092 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 93 | 3 | 00093 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 94 | 4 | 00094 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 95 | 5 | 00095 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 96 | 6 | 00096 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 97 | 7 | 00097 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 98 | 8 | 00098 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 99 | 9 | 00099 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 100 | 0 | 00100 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 101 | 1 | 00101 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 102 | 2 | 00102 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 103 | 3 | 00103 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 104 | 4 | 00104 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 105 | 5 | 00105 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 106 | 6 | 00106 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 107 | 7 | 00107 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 108 | 8 | 00108 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 109 | 9 | 00109 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 110 | 0 | 00110 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo +(110 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- ArrayRef + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c1 = (([c1, c2, 3])[1]))) +(3 rows) + +SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1] ORDER BY c1; -- ArrayRef + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +-----+----+-------+------------+------------+----+------------+----- + 1 | 1 | 00001 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 2 | 2 | 00002 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 3 | 3 | 00003 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 4 | 4 | 00004 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 5 | 5 | 00005 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 6 | 6 | 00006 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 7 | 7 | 00007 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 8 | 8 | 00008 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 9 | 9 | 00009 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 10 | 0 | 00010 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 11 | 1 | 00011 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 12 | 2 | 00012 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 13 | 3 | 00013 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 14 | 4 | 00014 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 15 | 5 | 00015 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 16 | 6 | 00016 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 17 | 7 | 00017 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 18 | 8 | 00018 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 19 | 9 | 00019 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 20 | 0 | 00020 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 21 | 1 | 00021 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 22 | 2 | 00022 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 23 | 3 | 00023 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 24 | 4 | 00024 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 25 | 5 | 00025 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 26 | 6 | 00026 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 27 | 7 | 00027 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 28 | 8 | 00028 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 29 | 9 | 00029 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 30 | 0 | 00030 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 31 | 1 | 00031 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 32 | 2 | 00032 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 33 | 3 | 00033 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 34 | 4 | 00034 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 35 | 5 | 00035 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 36 | 6 | 00036 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 37 | 7 | 00037 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 38 | 8 | 00038 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 39 | 9 | 00039 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 40 | 0 | 00040 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 41 | 1 | 00041 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 42 | 2 | 00042 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 43 | 3 | 00043 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 44 | 4 | 00044 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 45 | 5 | 00045 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 46 | 6 | 00046 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 47 | 7 | 00047 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 48 | 8 | 00048 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 49 | 9 | 00049 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 50 | 0 | 00050 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 51 | 1 | 00051 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 52 | 2 | 00052 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 53 | 3 | 00053 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 54 | 4 | 00054 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 55 | 5 | 00055 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 56 | 6 | 00056 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 57 | 7 | 00057 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 58 | 8 | 00058 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 59 | 9 | 00059 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 60 | 0 | 00060 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 61 | 1 | 00061 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 62 | 2 | 00062 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 63 | 3 | 00063 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 64 | 4 | 00064 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 65 | 5 | 00065 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 66 | 6 | 00066 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 67 | 7 | 00067 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 68 | 8 | 00068 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 69 | 9 | 00069 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 70 | 0 | 00070 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 71 | 1 | 00071 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 72 | 2 | 00072 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 73 | 3 | 00073 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 74 | 4 | 00074 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 75 | 5 | 00075 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 76 | 6 | 00076 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 77 | 7 | 00077 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 78 | 8 | 00078 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 79 | 9 | 00079 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 80 | 0 | 00080 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 81 | 1 | 00081 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 82 | 2 | 00082 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 83 | 3 | 00083 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 84 | 4 | 00084 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 85 | 5 | 00085 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 86 | 6 | 00086 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 87 | 7 | 00087 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 88 | 8 | 00088 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 89 | 9 | 00089 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 90 | 0 | 00090 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 91 | 1 | 00091 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 92 | 2 | 00092 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 93 | 3 | 00093 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 94 | 4 | 00094 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 95 | 5 | 00095 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 96 | 6 | 00096 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 97 | 7 | 00097 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 98 | 8 | 00098 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 99 | 9 | 00099 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 100 | 0 | 00100 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo + 101 | 1 | 00101 | 1990-01-01 | 1990-01-01 | 1 | 1 | foo + 102 | 2 | 00102 | 1990-01-01 | 1990-01-01 | 2 | 2 | foo + 103 | 3 | 00103 | 1990-01-01 | 1990-01-01 | 3 | 3 | foo + 104 | 4 | 00104 | 1990-01-01 | 1990-01-01 | 4 | 4 | foo + 105 | 5 | 00105 | 1990-01-01 | 1990-01-01 | 5 | 5 | foo + 106 | 6 | 00106 | 1990-01-01 | 1990-01-01 | 6 | 6 | foo + 107 | 7 | 00107 | 1990-01-01 | 1990-01-01 | 7 | 7 | foo + 108 | 8 | 00108 | 1990-01-01 | 1990-01-01 | 8 | 8 | foo + 109 | 9 | 00109 | 1990-01-01 | 1990-01-01 | 9 | 9 | foo + 110 | 0 | 00110 | 1990-01-01 | 1990-01-01 | 0 | 0 | foo +(110 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c6 = E'foo''s\\bar'; -- check special chars + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c6 = E'foo''s\\bar')) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't be sent to remote + QUERY PLAN +--------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT c1, c2, c3, c4, c5, c6, c7, c8 FROM regression.t1 WHERE ((c8 = 'foo')) +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT (CASE WHEN c1 < 10 THEN 1 WHEN c1 < 50 THEN 2 ELSE 3 END) a, + sum(length(c2)) FROM ft2 GROUP BY a ORDER BY a; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan + Output: (CASE WHEN (c1 < 10) THEN 1 WHEN (c1 < 50) THEN 2 ELSE 3 END), (sum(length(c2))) + Relations: Aggregate on (ft2) + Remote SQL: SELECT CASE WHEN (c1 < 10) THEN toInt32(1) WHEN (c1 < 50) THEN toInt32(2) ELSE toInt32(3) END, sum(length(c2)) FROM regression.t2 GROUP BY (CASE WHEN (c1 < 10) THEN toInt32(1) WHEN (c1 < 50) THEN toInt32(2) ELSE toInt32(3) END) ORDER BY CASE WHEN (c1 < 10) THEN toInt32(1) WHEN (c1 < 50) THEN toInt32(2) ELSE toInt32(3) END ASC +(4 rows) + +SELECT (CASE WHEN c1 < 10 THEN 1 WHEN c1 < 50 THEN 2 ELSE 3 END) a, + sum(length(c2)) FROM ft2 GROUP BY a ORDER BY a; + a | sum +---+----- + 1 | 54 + 2 | 240 + 3 | 306 +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT SUM(c1) FILTER (WHERE c1 < 20) FROM ft2; + QUERY PLAN +--------------------------------------------------------------------- + Foreign Scan + Output: (sum(c1) FILTER (WHERE (c1 < 20))) + Relations: Aggregate on (ft2) + Remote SQL: SELECT sumIf(c1,(((c1 < 20)) > 0)) FROM regression.t2 +(4 rows) + +SELECT SUM(c1) FILTER (WHERE c1 < 20) FROM ft2; + sum +----- + 190 +(1 row) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT COUNT(DISTINCT c1) FROM ft2; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan + Output: (count(DISTINCT c1)) + Relations: Aggregate on (ft2) + Remote SQL: SELECT count(DISTINCT c1) FROM regression.t2 +(4 rows) + +SELECT COUNT(DISTINCT c1) FROM ft2; + count +------- + 100 +(1 row) + +/* DISTINCT with IF */ +EXPLAIN (VERBOSE, COSTS OFF) SELECT COUNT(DISTINCT c1) FILTER (WHERE c1 < 20) FROM ft2; + QUERY PLAN +------------------------------------------------------- + Aggregate + Output: count(DISTINCT c1) FILTER (WHERE (c1 < 20)) + -> Foreign Scan on public.ft2 + Output: c1, c2 + Remote SQL: SELECT c1 FROM regression.t2 ORDER BY c1 ASC +(5 rows) + +DROP USER MAPPING FOR CURRENT_USER SERVER loopback; +DROP USER MAPPING FOR CURRENT_USER SERVER loopback2; +SELECT clickhousedb_raw_query('DROP DATABASE regression'); + clickhousedb_raw_query +------------------------ + +(1 row) + +DROP EXTENSION IF EXISTS clickhouse_fdw CASCADE; +NOTICE: drop cascades to 9 other objects +DETAIL: drop cascades to server loopback +drop cascades to foreign table ft1 +drop cascades to foreign table ft2 +drop cascades to foreign table ft3 +drop cascades to foreign table ft4 +drop cascades to foreign table ft5 +drop cascades to foreign table ftcopy +drop cascades to server loopback2 +drop cascades to foreign table ft6 From 5f9a573f40ae6b940bc83f4920ebd9c12371fc21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 29 Jul 2025 20:48:32 +0000 Subject: [PATCH 4/9] pg17 --- src/clickhouse_fdw.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/clickhouse_fdw.c b/src/clickhouse_fdw.c index 0a6f970..37d35b1 100644 --- a/src/clickhouse_fdw.c +++ b/src/clickhouse_fdw.c @@ -510,9 +510,13 @@ clickhouseGetForeignPaths(PlannerInfo *root, ForeignPath *path; CHFdwRelationInfo *fpinfo = (CHFdwRelationInfo *) baserel->fdw_private; - path= create_foreignscan_path(root, baserel, NULL, + path = create_foreignscan_path(root, baserel, NULL, fpinfo->rows, fpinfo->startup_cost, fpinfo->total_cost, - NULL, NULL, NULL, NIL); + NULL, NULL, NULL, NIL +#if PG_VERSION_NUM >= 170000 + , NIL +#endif + ); add_path(baserel, (Path *) path); add_paths_with_pathkeys_for_rel(root, baserel, NULL); @@ -1205,7 +1209,7 @@ clickhouseBeginForeignInsert(ModifyTableState *mtstate, NULL, sql.data, targetAttrs, - table_name); + table_name); resultRelInfo->ri_FdwState = fmstate; } @@ -2024,6 +2028,9 @@ clickhouseGetForeignJoinPaths(PlannerInfo *root, NIL, /* no pathkeys */ NULL, epq_path, +#if PG_VERSION_NUM >= 170000 + NIL, +#endif NIL); /* no fdw_private */ /* Add generated path into joinrel by add_path(). */ @@ -2394,6 +2401,9 @@ add_foreign_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, total_cost, NIL, /* no pathkeys */ NULL, +#if PG_VERSION_NUM >= 170000 + NIL, +#endif NIL); /* no fdw_private */ #endif @@ -2532,6 +2542,9 @@ add_foreign_ordered_paths(PlannerInfo *root, RelOptInfo *input_rel, total_cost, root->sort_pathkeys, NULL, /* no extra plan */ +#if PG_VERSION_NUM >= 170000 + NIL, +#endif fdw_private); #endif @@ -2677,6 +2690,9 @@ add_foreign_final_paths(PlannerInfo *root, RelOptInfo *input_rel, -10, pathkeys, NULL, /* no extra plan */ +#if PG_VERSION_NUM >= 170000 + NIL, +#endif fdw_private); /* and add it to the final_rel */ From 076528c52bbabde41bd74e1f24d1012e532bba35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 29 Jul 2025 21:00:42 +0000 Subject: [PATCH 5/9] ------ --- tests/expected/binary_queries_2.out | 2 +- tests/expected/http_2.out | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/expected/binary_queries_2.out b/tests/expected/binary_queries_2.out index 32e2bbe..988fc0f 100644 --- a/tests/expected/binary_queries_2.out +++ b/tests/expected/binary_queries_2.out @@ -720,7 +720,7 @@ SELECT COUNT(DISTINCT c1) FROM ft2; /* DISTINCT with IF */ EXPLAIN (VERBOSE, COSTS OFF) SELECT COUNT(DISTINCT c1) FILTER (WHERE c1 < 20) FROM ft2; QUERY PLAN -------------------------------------------------------- +------------------------------------------------------------------ Aggregate Output: count(DISTINCT c1) FILTER (WHERE (c1 < 20)) -> Foreign Scan on public.ft2 diff --git a/tests/expected/http_2.out b/tests/expected/http_2.out index ea848ef..06099d9 100644 --- a/tests/expected/http_2.out +++ b/tests/expected/http_2.out @@ -744,7 +744,7 @@ SELECT COUNT(DISTINCT c1) FROM ft2; /* DISTINCT with IF */ EXPLAIN (VERBOSE, COSTS OFF) SELECT COUNT(DISTINCT c1) FILTER (WHERE c1 < 20) FROM ft2; QUERY PLAN -------------------------------------------------------- +------------------------------------------------------------------ Aggregate Output: count(DISTINCT c1) FILTER (WHERE (c1 < 20)) -> Foreign Scan on public.ft2 From 614e1338ec751112d7adb64e85a4c03589f8d450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 29 Jul 2025 21:02:30 +0000 Subject: [PATCH 6/9] more pg17 --- src/clickhouse_fdw.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/clickhouse_fdw.c b/src/clickhouse_fdw.c index 37d35b1..0cd39fd 100644 --- a/src/clickhouse_fdw.c +++ b/src/clickhouse_fdw.c @@ -1858,6 +1858,9 @@ add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel, useful_pathkeys, NULL, sorted_epq_path, +#if PG_VERSION_NUM >= 170000 + NIL, +#endif NIL)); else add_path(rel, (Path *) @@ -1869,6 +1872,9 @@ add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel, useful_pathkeys, NULL, sorted_epq_path, +#if PG_VERSION_NUM >= 170000 + NIL, +#endif NIL)); } } From 4a426722f1b40f6d29b6dc3100cbd5502771f03e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 29 Jul 2025 21:20:52 +0000 Subject: [PATCH 7/9] pg17 alloc --- src/binary.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/binary.cc b/src/binary.cc index 8f57451..722f232 100644 --- a/src/binary.cc +++ b/src/binary.cc @@ -65,7 +65,11 @@ static void * exc_palloc(Size size) context->isReset = false; +#if PG_VERSION_NUM >= 170000 + ret = context->methods->alloc(context, size, 0); +#else ret = context->methods->alloc(context, size); +#endif if (unlikely(ret == NULL)) throw std::bad_alloc(); @@ -87,7 +91,11 @@ void * exc_palloc0(Size size) context->isReset = false; +#if PG_VERSION_NUM >= 170000 + ret = context->methods->alloc(context, size, 0); +#else ret = context->methods->alloc(context, size); +#endif if (unlikely(ret == NULL)) throw std::bad_alloc(); From e35db9644abb2e666ea076327576618e87ecd66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 29 Jul 2025 21:27:27 +0000 Subject: [PATCH 8/9] skip 16/17 false --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba161f3..02f1118 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,11 @@ jobs: matrix: pg: [17, 16, 15, 14, 13, 12, 11] check_code: ["false", "clang"] + exclude: + - pg: 16 + check_code: "false" + - pg: 17 + check_code: "false" name: Test clickhouse_fdw runs-on: ubuntu-latest From 4c614f14fad495dc2c888972e65df3fb0f401117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 29 Jul 2025 21:32:29 +0000 Subject: [PATCH 9/9] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1413c5f..2614196 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The `clickhouse_fdw` is open-source. It is a Foreign Data Wrapper (FDW) for `Cli Supported PostgreSQL Versions ------------------------------ -PostgreSQL 11-14 +PostgreSQL 11-17 Installation ----------------