Check for hasPseudoconstantQuals differently

pull/7937/head
naisila 2025-05-02 12:19:08 +03:00
parent 61d4b25f18
commit e239ea5aba
3 changed files with 46 additions and 23 deletions

View File

@ -2002,8 +2002,6 @@ multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo,
relationRestriction->outerPlanParamsList = OuterPlanParamsList(root); relationRestriction->outerPlanParamsList = OuterPlanParamsList(root);
relationRestriction->translatedVars = TranslatedVars(root, relationRestriction->translatedVars = TranslatedVars(root,
relationRestriction->index); relationRestriction->index);
plannerRestrictionContext->relationRestrictionContext->hasPseudoConstantQuals =
root->hasPseudoConstantQuals;
RelationRestrictionContext *relationRestrictionContext = RelationRestrictionContext *relationRestrictionContext =
plannerRestrictionContext->relationRestrictionContext; plannerRestrictionContext->relationRestrictionContext;

View File

@ -193,6 +193,10 @@ static Query * CreateOuterSubquery(RangeTblEntry *rangeTableEntry,
List *outerSubqueryTargetList); List *outerSubqueryTargetList);
static List * GenerateRequiredColNamesFromTargetList(List *targetList); static List * GenerateRequiredColNamesFromTargetList(List *targetList);
static char * GetRelationNameAndAliasName(RangeTblEntry *rangeTablentry); static char * GetRelationNameAndAliasName(RangeTblEntry *rangeTablentry);
#if PG_VERSION_NUM < PG_VERSION_17
static bool hasPseudoconstantQuals(
RelationRestrictionContext *relationRestrictionContext);
#endif
/* /*
* GenerateSubplansForSubqueriesAndCTEs is a wrapper around RecursivelyPlanSubqueriesAndCTEs. * GenerateSubplansForSubqueriesAndCTEs is a wrapper around RecursivelyPlanSubqueriesAndCTEs.
@ -481,25 +485,23 @@ ShouldRecursivelyPlanOuterJoins(Query *query, RecursivePlanningContext *context)
bool hasOuterJoin = bool hasOuterJoin =
context->plannerRestrictionContext->joinRestrictionContext->hasOuterJoin; context->plannerRestrictionContext->joinRestrictionContext->hasOuterJoin;
#if PG_VERSION_NUM < PG_VERSION_17 #if PG_VERSION_NUM < PG_VERSION_17
bool hasPseudoConstantQuals = if (!hasOuterJoin)
context->plannerRestrictionContext->relationRestrictionContext->
hasPseudoConstantQuals;
/*
* PG15 commit d1ef5631e620f9a5b6480a32bb70124c857af4f1
* PG16 commit 695f5deb7902865901eb2d50a70523af655c3a00
* disallows replacing joins with scans in queries with pseudoconstant quals.
* This commit prevents the set_join_pathlist_hook from being called
* if any of the join restrictions is a pseudo-constant.
* So in these cases, citus has no info on the join, never sees that the query
* has an outer join, and ends up producing an incorrect plan.
* PG17 fixes this by commit 9e9931d2bf40e2fea447d779c2e133c2c1256ef3
* Therefore, we take this extra measure here for PG versions less than 17.
*/
if (hasPseudoConstantQuals && !hasOuterJoin)
{ {
if (FindNodeMatchingCheckFunction((Node *) query->jointree, /*
IsOuterJoinExpr)) * PG15 commit d1ef5631e620f9a5b6480a32bb70124c857af4f1
* PG16 commit 695f5deb7902865901eb2d50a70523af655c3a00
* disallows replacing joins with scans in queries with pseudoconstant quals.
* This commit prevents the set_join_pathlist_hook from being called
* if any of the join restrictions is a pseudo-constant.
* So in these cases, citus has no info on the join, never sees that the query
* has an outer join, and ends up producing an incorrect plan.
* PG17 fixes this by commit 9e9931d2bf40e2fea447d779c2e133c2c1256ef3
* Therefore, we take this extra measure here for PG versions less than 17.
* hasOuterJoin can never be true when set_join_pathlist_hook is absent.
*/
if (hasPseudoconstantQuals(
context->plannerRestrictionContext->relationRestrictionContext) &&
FindNodeMatchingCheckFunction((Node *) query->jointree, IsOuterJoinExpr))
{ {
ereport(ERROR, (errmsg("Distributed queries with outer joins and " ereport(ERROR, (errmsg("Distributed queries with outer joins and "
"pseudoconstant quals are not supported in PG15 and PG16."), "pseudoconstant quals are not supported in PG15 and PG16."),
@ -2142,7 +2144,6 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
subquery->targetList = lappend(subquery->targetList, targetEntry); subquery->targetList = lappend(subquery->targetList, targetEntry);
} }
} }
/* /*
* If tupleDesc is NULL we have 2 different cases: * If tupleDesc is NULL we have 2 different cases:
* *
@ -2192,7 +2193,6 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
columnType = list_nth_oid(rangeTblFunction->funccoltypes, columnType = list_nth_oid(rangeTblFunction->funccoltypes,
targetColumnIndex); targetColumnIndex);
} }
/* use the types in the function definition otherwise */ /* use the types in the function definition otherwise */
else else
{ {
@ -2616,3 +2616,29 @@ GeneratingSubplans(void)
{ {
return recursivePlanningDepth > 0; return recursivePlanningDepth > 0;
} }
#if PG_VERSION_NUM < PG_VERSION_17
/*
* hasPseudoconstantQuals returns true if any of the planner infos in the
* relation restriction list of the input relation restriction context
* has a pseudoconstant qual
*/
static bool
hasPseudoconstantQuals(RelationRestrictionContext *relationRestrictionContext)
{
ListCell *objectCell = NULL;
foreach(objectCell, relationRestrictionContext->relationRestrictionList)
{
if (((RelationRestriction *) lfirst(
objectCell))->plannerInfo->hasPseudoConstantQuals)
{
return true;
}
}
return false;
}
#endif

View File

@ -36,7 +36,6 @@ extern int PlannerLevel;
typedef struct RelationRestrictionContext typedef struct RelationRestrictionContext
{ {
bool allReferenceTables; bool allReferenceTables;
bool hasPseudoConstantQuals;
List *relationRestrictionList; List *relationRestrictionList;
} RelationRestrictionContext; } RelationRestrictionContext;