From c99dcb3de3d0e42d03af71027ca4b1cd6d130127 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Sun, 28 Jun 2026 19:21:40 +0800 Subject: [PATCH] Fix qual pushdown with nondeterministic partition collations --- src/backend/optimizer/path/allpaths.c | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index c134594a21a..995972e15dc 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -57,6 +57,7 @@ #define UNSAFE_NOTIN_DISTINCTON_CLAUSE (1 << 2) #define UNSAFE_NOTIN_PARTITIONBY_CLAUSE (1 << 3) #define UNSAFE_TYPE_MISMATCH (1 << 4) +#define UNSAFE_HAS_NONDETERMINITIC (1 << 5) /* results of subquery_is_pushdown_safe */ typedef struct pushdown_safety_info @@ -159,6 +160,7 @@ static void check_output_expressions(Query *subquery, static void compare_tlist_datatypes(List *tlist, List *colTypes, pushdown_safety_info *safetyInfo); static bool targetIsInAllPartitionLists(TargetEntry *tle, Query *query); +static bool contain_nondeterministic_partition_clause(TargetEntry *tle, Query *query); static pushdown_safe_type qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo, pushdown_safety_info *safetyInfo); @@ -4345,6 +4347,16 @@ check_output_expressions(Query *subquery, pushdown_safety_info *safetyInfo) safetyInfo->unsafeFlags[tle->resno] |= UNSAFE_NOTIN_PARTITIONBY_CLAUSE; continue; } + + if (subquery->hasWindowFuncs && + (safetyInfo->unsafeFlags[tle->resno] & + UNSAFE_HAS_NONDETERMINITIC) == 0 && + contain_nondeterministic_partition_clause(tle, subquery)) + { + /* has nondeterministic partition collations */ + safetyInfo->unsafeFlags[tle->resno] |= UNSAFE_HAS_NONDETERMINITIC; + continue; + } } } @@ -4413,6 +4425,22 @@ targetIsInAllPartitionLists(TargetEntry *tle, Query *query) return true; } +static bool +contain_nondeterministic_partition_clause(TargetEntry *tle, Query *query) +{ + Oid collid; + + if (!targetIsInAllPartitionLists(tle, query)) + return false; + + collid = exprCollation((Node *) tle->expr); + + if (OidIsValid(collid)) + return !get_collation_isdeterministic(collid); + + return false; +} + /* * qual_is_pushdown_safe - is a particular rinfo safe to push down? * @@ -4525,6 +4553,15 @@ qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo, safe = PUSHDOWN_UNSAFE; break; } + else if (safetyInfo->unsafeFlags[var->varattno] & + UNSAFE_HAS_NONDETERMINITIC) + { + if (get_collation_isdeterministic(exprInputCollation(qual))) + { + safe = PUSHDOWN_UNSAFE; + break; + } + } else { /* UNSAFE_NOTIN_PARTITIONBY_CLAUSE is ok for run conditions */ -- 2.34.1