Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a9a174c

Browse files
Alexander PyhalovCommitfest Bot
Alexander Pyhalov
authored and
Commitfest Bot
committed
Allow partition-wise join when reltarget contains whole row vars
This partially revert 7cfdc77, restoring setrefs logic to handle converted whole row reference.
1 parent 53a4936 commit a9a174c

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

src/backend/optimizer/path/allpaths.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,8 +976,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
976976
*/
977977
if (enable_partitionwise_join &&
978978
rel->reloptkind == RELOPT_BASEREL &&
979-
rte->relkind == RELKIND_PARTITIONED_TABLE &&
980-
bms_is_empty(rel->attr_needed[InvalidAttrNumber - rel->min_attr]))
979+
rte->relkind == RELKIND_PARTITIONED_TABLE)
981980
rel->consider_partitionwise_join = true;
982981

983982
/*

src/backend/optimizer/plan/setrefs.c

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ typedef struct
5252
int num_vars; /* number of plain Var tlist entries */
5353
bool has_ph_vars; /* are there PlaceHolderVar entries? */
5454
bool has_non_vars; /* are there other entries? */
55+
bool has_conv_whole_rows; /* are there ConvertRowtypeExpr
56+
* entries encapsulating a whole-row
57+
* Var? */
5558
tlist_vinfo vars[FLEXIBLE_ARRAY_MEMBER]; /* has num_vars entries */
5659
} indexed_tlist;
5760

@@ -211,6 +214,7 @@ static List *set_windowagg_runcondition_references(PlannerInfo *root,
211214
List *runcondition,
212215
Plan *plan);
213216

217+
static bool is_converted_whole_row_reference(Node *node);
214218

215219
/*****************************************************************************
216220
*
@@ -2738,6 +2742,7 @@ build_tlist_index(List *tlist)
27382742
itlist->tlist = tlist;
27392743
itlist->has_ph_vars = false;
27402744
itlist->has_non_vars = false;
2745+
itlist->has_conv_whole_rows = false;
27412746

27422747
/* Find the Vars and fill in the index array */
27432748
vinfo = itlist->vars;
@@ -2757,6 +2762,8 @@ build_tlist_index(List *tlist)
27572762
}
27582763
else if (tle->expr && IsA(tle->expr, PlaceHolderVar))
27592764
itlist->has_ph_vars = true;
2765+
else if (is_converted_whole_row_reference((Node *) tle->expr))
2766+
itlist->has_conv_whole_rows = true;
27602767
else
27612768
itlist->has_non_vars = true;
27622769
}
@@ -2772,7 +2779,10 @@ build_tlist_index(List *tlist)
27722779
* This is like build_tlist_index, but we only index tlist entries that
27732780
* are Vars belonging to some rel other than the one specified. We will set
27742781
* has_ph_vars (allowing PlaceHolderVars to be matched), but not has_non_vars
2775-
* (so nothing other than Vars and PlaceHolderVars can be matched).
2782+
* (so nothing other than Vars and PlaceHolderVars can be matched). In case of
2783+
* DML, where this function will be used, returning lists from child relations
2784+
* will be appended similar to a simple append relation. That does not require
2785+
* fixing ConvertRowtypeExpr references. So, those are not considered here.
27762786
*/
27772787
static indexed_tlist *
27782788
build_tlist_index_other_vars(List *tlist, int ignore_rel)
@@ -2789,6 +2799,7 @@ build_tlist_index_other_vars(List *tlist, int ignore_rel)
27892799
itlist->tlist = tlist;
27902800
itlist->has_ph_vars = false;
27912801
itlist->has_non_vars = false;
2802+
itlist->has_conv_whole_rows = false;
27922803

27932804
/* Find the desired Vars and fill in the index array */
27942805
vinfo = itlist->vars;
@@ -3094,6 +3105,7 @@ static Node *
30943105
fix_join_expr_mutator(Node *node, fix_join_expr_context *context)
30953106
{
30963107
Var *newvar;
3108+
bool converted_whole_row;
30973109

30983110
if (node == NULL)
30993111
return NULL;
@@ -3182,15 +3194,16 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context)
31823194
return fix_join_expr_mutator((Node *) phv->phexpr, context);
31833195
}
31843196
/* Try matching more complex expressions too, if tlists have any */
3185-
if (context->outer_itlist && context->outer_itlist->has_non_vars)
3197+
converted_whole_row = is_converted_whole_row_reference(node);
3198+
if (context->outer_itlist && (context->outer_itlist->has_non_vars || (context->outer_itlist->has_conv_whole_rows && converted_whole_row)))
31863199
{
31873200
newvar = search_indexed_tlist_for_non_var((Expr *) node,
31883201
context->outer_itlist,
31893202
OUTER_VAR);
31903203
if (newvar)
31913204
return (Node *) newvar;
31923205
}
3193-
if (context->inner_itlist && context->inner_itlist->has_non_vars)
3206+
if (context->inner_itlist && (context->inner_itlist->has_non_vars || (context->inner_itlist->has_conv_whole_rows && converted_whole_row)))
31943207
{
31953208
newvar = search_indexed_tlist_for_non_var((Expr *) node,
31963209
context->inner_itlist,
@@ -3301,7 +3314,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
33013314
return fix_upper_expr_mutator((Node *) phv->phexpr, context);
33023315
}
33033316
/* Try matching more complex expressions too, if tlist has any */
3304-
if (context->subplan_itlist->has_non_vars)
3317+
if (context->subplan_itlist->has_non_vars || (context->subplan_itlist->has_conv_whole_rows && is_converted_whole_row_reference(node)))
33053318
{
33063319
newvar = search_indexed_tlist_for_non_var((Expr *) node,
33073320
context->subplan_itlist,
@@ -3701,3 +3714,33 @@ extract_query_dependencies_walker(Node *node, PlannerInfo *context)
37013714
return expression_tree_walker(node, extract_query_dependencies_walker,
37023715
context);
37033716
}
3717+
3718+
/*
3719+
* is_converted_whole_row_reference
3720+
* If the given node is a ConvertRowtypeExpr encapsulating a whole-row
3721+
* reference as implicit cast, return true. Otherwise return false.
3722+
*/
3723+
static bool
3724+
is_converted_whole_row_reference(Node *node)
3725+
{
3726+
ConvertRowtypeExpr *convexpr;
3727+
3728+
if (!node || !IsA(node, ConvertRowtypeExpr))
3729+
return false;
3730+
3731+
/* Traverse nested ConvertRowtypeExpr's. */
3732+
convexpr = castNode(ConvertRowtypeExpr, node);
3733+
while (convexpr->convertformat == COERCE_IMPLICIT_CAST &&
3734+
IsA(convexpr->arg, ConvertRowtypeExpr))
3735+
convexpr = castNode(ConvertRowtypeExpr, convexpr->arg);
3736+
3737+
if (IsA(convexpr->arg, Var))
3738+
{
3739+
Var *var = castNode(Var, convexpr->arg);
3740+
3741+
if (var->varattno == 0)
3742+
return true;
3743+
}
3744+
3745+
return false;
3746+
}

0 commit comments

Comments
 (0)