static SpecialJoinInfo *build_child_join_sjinfo(PlannerInfo *root,
SpecialJoinInfo *parent_sjinfo,
Relids left_relids, Relids right_relids);
-static void free_child_join_sjinfo(SpecialJoinInfo *sjinfo);
+static void free_child_join_sjinfo(SpecialJoinInfo *child_sjinfo,
+ SpecialJoinInfo *parent_sjinfo);
static void compute_partition_bounds(PlannerInfo *root, RelOptInfo *rel1,
RelOptInfo *rel2, RelOptInfo *joinrel,
SpecialJoinInfo *parent_sjinfo,
*/
pfree(appinfos);
bms_free(child_relids);
- free_child_join_sjinfo(child_sjinfo);
+ free_child_join_sjinfo(child_sjinfo, parent_sjinfo);
}
}
* SpecialJoinInfo are freed here.
*/
static void
-free_child_join_sjinfo(SpecialJoinInfo *sjinfo)
+free_child_join_sjinfo(SpecialJoinInfo *child_sjinfo,
+ SpecialJoinInfo *parent_sjinfo)
{
/*
* Dummy SpecialJoinInfos of inner joins do not have any translated fields
* and hence no fields that to be freed.
*/
- if (sjinfo->jointype != JOIN_INNER)
+ if (child_sjinfo->jointype != JOIN_INNER)
{
- bms_free(sjinfo->min_lefthand);
- bms_free(sjinfo->min_righthand);
- bms_free(sjinfo->syn_lefthand);
- bms_free(sjinfo->syn_righthand);
+ if (child_sjinfo->min_lefthand != parent_sjinfo->min_lefthand)
+ bms_free(child_sjinfo->min_lefthand);
+
+ if (child_sjinfo->min_righthand != parent_sjinfo->min_righthand)
+ bms_free(child_sjinfo->min_righthand);
+
+ if (child_sjinfo->syn_lefthand != parent_sjinfo->syn_lefthand)
+ bms_free(child_sjinfo->syn_lefthand);
+
+ if (child_sjinfo->syn_righthand != parent_sjinfo->syn_righthand)
+ bms_free(child_sjinfo->syn_righthand);
+
+ Assert(child_sjinfo->commute_above_l == parent_sjinfo->commute_above_l);
+ Assert(child_sjinfo->commute_above_r == parent_sjinfo->commute_above_r);
+ Assert(child_sjinfo->commute_below_l == parent_sjinfo->commute_below_l);
+ Assert(child_sjinfo->commute_below_r == parent_sjinfo->commute_below_r);
+
+ Assert(child_sjinfo->semi_operators == parent_sjinfo->semi_operators);
/*
* semi_rhs_exprs may in principle be freed, but a simple pfree() does
*/
}
- pfree(sjinfo);
+ pfree(child_sjinfo);
}
/*
RESET enable_partitionwise_aggregate;
RESET enable_hashjoin;
+-- bug in freeing the SpecialJoinInfo of a child-join
+EXPLAIN (COSTS OFF)
+SELECT * FROM prt1 t1 JOIN prt1 t2 ON t1.a = t2.a WHERE t1.a IN (SELECT a FROM prt1 t3);
+ QUERY PLAN
+--------------------------------------------------
+ Append
+ -> Hash Semi Join
+ Hash Cond: (t1_1.a = t3_1.a)
+ -> Hash Join
+ Hash Cond: (t1_1.a = t2_1.a)
+ -> Seq Scan on prt1_p1 t1_1
+ -> Hash
+ -> Seq Scan on prt1_p1 t2_1
+ -> Hash
+ -> Seq Scan on prt1_p1 t3_1
+ -> Hash Semi Join
+ Hash Cond: (t1_2.a = t3_2.a)
+ -> Hash Join
+ Hash Cond: (t1_2.a = t2_2.a)
+ -> Seq Scan on prt1_p2 t1_2
+ -> Hash
+ -> Seq Scan on prt1_p2 t2_2
+ -> Hash
+ -> Seq Scan on prt1_p2 t3_2
+ -> Hash Semi Join
+ Hash Cond: (t1_3.a = t3_3.a)
+ -> Hash Join
+ Hash Cond: (t1_3.a = t2_3.a)
+ -> Seq Scan on prt1_p3 t1_3
+ -> Hash
+ -> Seq Scan on prt1_p3 t2_3
+ -> Hash
+ -> Seq Scan on prt1_p3 t3_3
+(28 rows)
+
--
-- partitioned by expression
--