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->translatedVars = TranslatedVars(root,
relationRestriction->index);
plannerRestrictionContext->relationRestrictionContext->hasPseudoConstantQuals =
root->hasPseudoConstantQuals;
RelationRestrictionContext *relationRestrictionContext =
plannerRestrictionContext->relationRestrictionContext;

View File

@ -193,6 +193,10 @@ static Query * CreateOuterSubquery(RangeTblEntry *rangeTableEntry,
List *outerSubqueryTargetList);
static List * GenerateRequiredColNamesFromTargetList(List *targetList);
static char * GetRelationNameAndAliasName(RangeTblEntry *rangeTablentry);
#if PG_VERSION_NUM < PG_VERSION_17
static bool hasPseudoconstantQuals(
RelationRestrictionContext *relationRestrictionContext);
#endif
/*
* GenerateSubplansForSubqueriesAndCTEs is a wrapper around RecursivelyPlanSubqueriesAndCTEs.
@ -481,25 +485,23 @@ ShouldRecursivelyPlanOuterJoins(Query *query, RecursivePlanningContext *context)
bool hasOuterJoin =
context->plannerRestrictionContext->joinRestrictionContext->hasOuterJoin;
#if PG_VERSION_NUM < PG_VERSION_17
bool hasPseudoConstantQuals =
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 (!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 "
"pseudoconstant quals are not supported in PG15 and PG16."),
@ -2142,7 +2144,6 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
subquery->targetList = lappend(subquery->targetList, targetEntry);
}
}
/*
* If tupleDesc is NULL we have 2 different cases:
*
@ -2192,7 +2193,6 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
columnType = list_nth_oid(rangeTblFunction->funccoltypes,
targetColumnIndex);
}
/* use the types in the function definition otherwise */
else
{
@ -2616,3 +2616,29 @@ GeneratingSubplans(void)
{
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
{
bool allReferenceTables;
bool hasPseudoConstantQuals;
List *relationRestrictionList;
} RelationRestrictionContext;