summaryrefslogtreecommitdiffstats
path: root/contrib/postgres_fdw
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-14 19:16:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-14 19:16:24 +0000
commit2a0f262beff32ba86bcb58f3273214e5d0517c09 (patch)
tree24c0ad10dab36bbd5c22743d3c88c4e0ccd5bc65 /contrib/postgres_fdw
parentReleasing progress-linux version 16.2-2~progress7.99u1. (diff)
downloadpostgresql-16-2a0f262beff32ba86bcb58f3273214e5d0517c09.tar.xz
postgresql-16-2a0f262beff32ba86bcb58f3273214e5d0517c09.zip
Merging upstream version 16.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'contrib/postgres_fdw')
-rw-r--r--contrib/postgres_fdw/connection.c8
-rw-r--r--contrib/postgres_fdw/deparse.c25
-rw-r--r--contrib/postgres_fdw/expected/postgres_fdw.out93
-rw-r--r--contrib/postgres_fdw/postgres_fdw.c18
-rw-r--r--contrib/postgres_fdw/sql/postgres_fdw.sql32
5 files changed, 129 insertions, 47 deletions
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index f839308..3246e18 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -658,10 +658,12 @@ configure_remote_session(PGconn *conn)
* anyway. However it makes the regression test outputs more predictable.
*
* We don't risk setting remote zone equal to ours, since the remote
- * server might use a different timezone database. Instead, use UTC
- * (quoted, because very old servers are picky about case).
+ * server might use a different timezone database. Instead, use GMT
+ * (quoted, because very old servers are picky about case). That's
+ * guaranteed to work regardless of the remote's timezone database,
+ * because pg_tzset() hard-wires it (at least in PG 9.2 and later).
*/
- do_sql_command(conn, "SET timezone = 'UTC'");
+ do_sql_command(conn, "SET timezone = 'GMT'");
/*
* Set values needed to ensure unambiguous data output from remote. (This
diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c
index 09d6dd6..6cba343 100644
--- a/contrib/postgres_fdw/deparse.c
+++ b/contrib/postgres_fdw/deparse.c
@@ -3770,13 +3770,12 @@ appendOrderByClause(List *pathkeys, bool has_final_sort,
{
ListCell *lcell;
int nestlevel;
- const char *delim = " ";
StringInfo buf = context->buf;
+ bool gotone = false;
/* Make sure any constants in the exprs are printed portably */
nestlevel = set_transmission_modes();
- appendStringInfoString(buf, " ORDER BY");
foreach(lcell, pathkeys)
{
PathKey *pathkey = lfirst(lcell);
@@ -3810,6 +3809,26 @@ appendOrderByClause(List *pathkeys, bool has_final_sort,
em_expr = em->em_expr;
/*
+ * If the member is a Const expression then we needn't add it to the
+ * ORDER BY clause. This can happen in UNION ALL queries where the
+ * union child targetlist has a Const. Adding these would be
+ * wasteful, but also, for INT columns, an integer literal would be
+ * seen as an ordinal column position rather than a value to sort by.
+ * deparseConst() does have code to handle this, but it seems less
+ * effort on all accounts just to skip these for ORDER BY clauses.
+ */
+ if (IsA(em_expr, Const))
+ continue;
+
+ if (!gotone)
+ {
+ appendStringInfoString(buf, " ORDER BY ");
+ gotone = true;
+ }
+ else
+ appendStringInfoString(buf, ", ");
+
+ /*
* Lookup the operator corresponding to the strategy in the opclass.
* The datatype used by the opfamily is not necessarily the same as
* the expression type (for array types for example).
@@ -3823,7 +3842,6 @@ appendOrderByClause(List *pathkeys, bool has_final_sort,
pathkey->pk_strategy, em->em_datatype, em->em_datatype,
pathkey->pk_opfamily);
- appendStringInfoString(buf, delim);
deparseExpr(em_expr, context);
/*
@@ -3833,7 +3851,6 @@ appendOrderByClause(List *pathkeys, bool has_final_sort,
appendOrderBySuffix(oprid, exprType((Node *) em_expr),
pathkey->pk_nulls_first, context);
- delim = ", ";
}
reset_transmission_modes(nestlevel);
}
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index 08fab73..87c6343 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -893,32 +893,6 @@ SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5));
4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo
(4 rows)
--- we should not push order by clause with volatile expressions or unsafe
--- collations
-EXPLAIN (VERBOSE, COSTS OFF)
- SELECT * FROM ft2 ORDER BY ft2.c1, random();
- QUERY PLAN
--------------------------------------------------------------------------------
- Sort
- Output: c1, c2, c3, c4, c5, c6, c7, c8, (random())
- Sort Key: ft2.c1, (random())
- -> Foreign Scan on public.ft2
- Output: c1, c2, c3, c4, c5, c6, c7, c8, random()
- Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
-(6 rows)
-
-EXPLAIN (VERBOSE, COSTS OFF)
- SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C";
- QUERY PLAN
--------------------------------------------------------------------------------
- Sort
- Output: c1, c2, c3, c4, c5, c6, c7, c8, ((c3)::text)
- Sort Key: ft2.c1, ft2.c3 COLLATE "C"
- -> Foreign Scan on public.ft2
- Output: c1, c2, c3, c4, c5, c6, c7, c8, c3
- Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
-(6 rows)
-
-- user-defined operator/function
CREATE FUNCTION postgres_fdw_abs(int) RETURNS int AS $$
BEGIN
@@ -1207,6 +1181,73 @@ WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0;
(1 row)
-- ===================================================================
+-- ORDER BY queries
+-- ===================================================================
+-- we should not push order by clause with volatile expressions or unsafe
+-- collations
+EXPLAIN (VERBOSE, COSTS OFF)
+ SELECT * FROM ft2 ORDER BY ft2.c1, random();
+ QUERY PLAN
+-------------------------------------------------------------------------------
+ Sort
+ Output: c1, c2, c3, c4, c5, c6, c7, c8, (random())
+ Sort Key: ft2.c1, (random())
+ -> Foreign Scan on public.ft2
+ Output: c1, c2, c3, c4, c5, c6, c7, c8, random()
+ Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
+(6 rows)
+
+EXPLAIN (VERBOSE, COSTS OFF)
+ SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C";
+ QUERY PLAN
+-------------------------------------------------------------------------------
+ Sort
+ Output: c1, c2, c3, c4, c5, c6, c7, c8, ((c3)::text)
+ Sort Key: ft2.c1, ft2.c3 COLLATE "C"
+ -> Foreign Scan on public.ft2
+ Output: c1, c2, c3, c4, c5, c6, c7, c8, c3
+ Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
+(6 rows)
+
+-- Ensure we don't push ORDER BY expressions which are Consts at the UNION
+-- child level to the foreign server.
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT * FROM (
+ SELECT 1 AS type,c1 FROM ft1
+ UNION ALL
+ SELECT 2 AS type,c1 FROM ft2
+) a ORDER BY type,c1;
+ QUERY PLAN
+---------------------------------------------------------------------------------
+ Merge Append
+ Sort Key: (1), ft1.c1
+ -> Foreign Scan on public.ft1
+ Output: 1, ft1.c1
+ Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST
+ -> Foreign Scan on public.ft2
+ Output: 2, ft2.c1
+ Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST
+(8 rows)
+
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT * FROM (
+ SELECT 1 AS type,c1 FROM ft1
+ UNION ALL
+ SELECT 2 AS type,c1 FROM ft2
+) a ORDER BY type;
+ QUERY PLAN
+---------------------------------------------------
+ Merge Append
+ Sort Key: (1)
+ -> Foreign Scan on public.ft1
+ Output: 1, ft1.c1
+ Remote SQL: SELECT "C 1" FROM "S 1"."T 1"
+ -> Foreign Scan on public.ft2
+ Output: 2, ft2.c1
+ Remote SQL: SELECT "C 1" FROM "S 1"."T 1"
+(8 rows)
+
+-- ===================================================================
-- JOIN queries
-- ===================================================================
-- Analyze ft4 and ft5 so that we have better statistics. These tables do not
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index c5cada5..23a5710 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -7174,14 +7174,16 @@ postgresForeignAsyncConfigureWait(AsyncRequest *areq)
{
/*
* This is the case when the in-process request was made by another
- * Append. Note that it might be useless to process the request,
- * because the query might not need tuples from that Append anymore.
- * If there are any child subplans of the same parent that are ready
- * for new requests, skip the given request. Likewise, if there are
- * any configured events other than the postmaster death event, skip
- * it. Otherwise, process the in-process request, then begin a fetch
- * to configure the event below, because we might otherwise end up
- * with no configured events other than the postmaster death event.
+ * Append. Note that it might be useless to process the request made
+ * by that Append, because the query might not need tuples from that
+ * Append anymore; so we avoid processing it to begin a fetch for the
+ * given request if possible. If there are any child subplans of the
+ * same parent that are ready for new requests, skip the given
+ * request. Likewise, if there are any configured events other than
+ * the postmaster death event, skip it. Otherwise, process the
+ * in-process request, then begin a fetch to configure the event
+ * below, because we might otherwise end up with no configured events
+ * other than the postmaster death event.
*/
if (!bms_is_empty(requestor->as_needrequest))
return;
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index a846f4e..3b863ec 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -355,12 +355,6 @@ WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7);
-- bug before 9.3.5 due to sloppy handling of remote-estimate parameters
SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5));
SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5));
--- we should not push order by clause with volatile expressions or unsafe
--- collations
-EXPLAIN (VERBOSE, COSTS OFF)
- SELECT * FROM ft2 ORDER BY ft2.c1, random();
-EXPLAIN (VERBOSE, COSTS OFF)
- SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C";
-- user-defined operator/function
CREATE FUNCTION postgres_fdw_abs(int) RETURNS int AS $$
@@ -463,6 +457,32 @@ SELECT c1, to_tsvector('custom_search'::regconfig, c3) FROM ft1
WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0;
-- ===================================================================
+-- ORDER BY queries
+-- ===================================================================
+-- we should not push order by clause with volatile expressions or unsafe
+-- collations
+EXPLAIN (VERBOSE, COSTS OFF)
+ SELECT * FROM ft2 ORDER BY ft2.c1, random();
+EXPLAIN (VERBOSE, COSTS OFF)
+ SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C";
+
+-- Ensure we don't push ORDER BY expressions which are Consts at the UNION
+-- child level to the foreign server.
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT * FROM (
+ SELECT 1 AS type,c1 FROM ft1
+ UNION ALL
+ SELECT 2 AS type,c1 FROM ft2
+) a ORDER BY type,c1;
+
+EXPLAIN (VERBOSE, COSTS OFF)
+SELECT * FROM (
+ SELECT 1 AS type,c1 FROM ft1
+ UNION ALL
+ SELECT 2 AS type,c1 FROM ft2
+) a ORDER BY type;
+
+-- ===================================================================
-- JOIN queries
-- ===================================================================
-- Analyze ft4 and ft5 so that we have better statistics. These tables do not