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

Commit 0568e7a

Browse files
committed
Cosmetic improvements for code related to partitionwise join.
Move have_partkey_equi_join and match_expr_to_partition_keys to relnode.c, since they're used only there. Refactor build_joinrel_partition_info to split out the code that fills the joinrel's partition key lists; this doesn't have any non-cosmetic impact, but it seems like a useful separation of concerns. Improve assorted nearby comments. Amit Langote, with a little further editorialization by me Discussion: https://postgr.es/m/CA+HiwqG2WVUGmLJqtR0tPFhniO=H=9qQ+Z3L_ZC+Y3-EVQHFGg@mail.gmail.com
1 parent 21dc488 commit 0568e7a

File tree

5 files changed

+283
-234
lines changed

5 files changed

+283
-234
lines changed

src/backend/optimizer/path/joinrels.c

Lines changed: 0 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "optimizer/pathnode.h"
2121
#include "optimizer/paths.h"
2222
#include "partitioning/partbounds.h"
23-
#include "utils/lsyscache.h"
2423
#include "utils/memutils.h"
2524

2625

@@ -46,8 +45,6 @@ static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1,
4645
static SpecialJoinInfo *build_child_join_sjinfo(PlannerInfo *root,
4746
SpecialJoinInfo *parent_sjinfo,
4847
Relids left_relids, Relids right_relids);
49-
static int match_expr_to_partition_keys(Expr *expr, RelOptInfo *rel,
50-
bool strict_op);
5148

5249

5350
/*
@@ -1573,168 +1570,3 @@ build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
15731570

15741571
return sjinfo;
15751572
}
1576-
1577-
/*
1578-
* Returns true if there exists an equi-join condition for each pair of
1579-
* partition keys from given relations being joined.
1580-
*/
1581-
bool
1582-
have_partkey_equi_join(RelOptInfo *joinrel,
1583-
RelOptInfo *rel1, RelOptInfo *rel2,
1584-
JoinType jointype, List *restrictlist)
1585-
{
1586-
PartitionScheme part_scheme = rel1->part_scheme;
1587-
ListCell *lc;
1588-
int cnt_pks;
1589-
bool pk_has_clause[PARTITION_MAX_KEYS];
1590-
bool strict_op;
1591-
1592-
/*
1593-
* This function should be called when the joining relations have same
1594-
* partitioning scheme.
1595-
*/
1596-
Assert(rel1->part_scheme == rel2->part_scheme);
1597-
Assert(part_scheme);
1598-
1599-
memset(pk_has_clause, 0, sizeof(pk_has_clause));
1600-
foreach(lc, restrictlist)
1601-
{
1602-
RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
1603-
OpExpr *opexpr;
1604-
Expr *expr1;
1605-
Expr *expr2;
1606-
int ipk1;
1607-
int ipk2;
1608-
1609-
/* If processing an outer join, only use its own join clauses. */
1610-
if (IS_OUTER_JOIN(jointype) &&
1611-
RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids))
1612-
continue;
1613-
1614-
/* Skip clauses which can not be used for a join. */
1615-
if (!rinfo->can_join)
1616-
continue;
1617-
1618-
/* Skip clauses which are not equality conditions. */
1619-
if (!rinfo->mergeopfamilies && !OidIsValid(rinfo->hashjoinoperator))
1620-
continue;
1621-
1622-
opexpr = castNode(OpExpr, rinfo->clause);
1623-
1624-
/*
1625-
* The equi-join between partition keys is strict if equi-join between
1626-
* at least one partition key is using a strict operator. See
1627-
* explanation about outer join reordering identity 3 in
1628-
* optimizer/README
1629-
*/
1630-
strict_op = op_strict(opexpr->opno);
1631-
1632-
/* Match the operands to the relation. */
1633-
if (bms_is_subset(rinfo->left_relids, rel1->relids) &&
1634-
bms_is_subset(rinfo->right_relids, rel2->relids))
1635-
{
1636-
expr1 = linitial(opexpr->args);
1637-
expr2 = lsecond(opexpr->args);
1638-
}
1639-
else if (bms_is_subset(rinfo->left_relids, rel2->relids) &&
1640-
bms_is_subset(rinfo->right_relids, rel1->relids))
1641-
{
1642-
expr1 = lsecond(opexpr->args);
1643-
expr2 = linitial(opexpr->args);
1644-
}
1645-
else
1646-
continue;
1647-
1648-
/*
1649-
* Only clauses referencing the partition keys are useful for
1650-
* partitionwise join.
1651-
*/
1652-
ipk1 = match_expr_to_partition_keys(expr1, rel1, strict_op);
1653-
if (ipk1 < 0)
1654-
continue;
1655-
ipk2 = match_expr_to_partition_keys(expr2, rel2, strict_op);
1656-
if (ipk2 < 0)
1657-
continue;
1658-
1659-
/*
1660-
* If the clause refers to keys at different ordinal positions, it can
1661-
* not be used for partitionwise join.
1662-
*/
1663-
if (ipk1 != ipk2)
1664-
continue;
1665-
1666-
/*
1667-
* The clause allows partitionwise join if only it uses the same
1668-
* operator family as that specified by the partition key.
1669-
*/
1670-
if (rel1->part_scheme->strategy == PARTITION_STRATEGY_HASH)
1671-
{
1672-
if (!op_in_opfamily(rinfo->hashjoinoperator,
1673-
part_scheme->partopfamily[ipk1]))
1674-
continue;
1675-
}
1676-
else if (!list_member_oid(rinfo->mergeopfamilies,
1677-
part_scheme->partopfamily[ipk1]))
1678-
continue;
1679-
1680-
/* Mark the partition key as having an equi-join clause. */
1681-
pk_has_clause[ipk1] = true;
1682-
}
1683-
1684-
/* Check whether every partition key has an equi-join condition. */
1685-
for (cnt_pks = 0; cnt_pks < part_scheme->partnatts; cnt_pks++)
1686-
{
1687-
if (!pk_has_clause[cnt_pks])
1688-
return false;
1689-
}
1690-
1691-
return true;
1692-
}
1693-
1694-
/*
1695-
* Find the partition key from the given relation matching the given
1696-
* expression. If found, return the index of the partition key, else return -1.
1697-
*/
1698-
static int
1699-
match_expr_to_partition_keys(Expr *expr, RelOptInfo *rel, bool strict_op)
1700-
{
1701-
int cnt;
1702-
1703-
/* This function should be called only for partitioned relations. */
1704-
Assert(rel->part_scheme);
1705-
1706-
/* Remove any relabel decorations. */
1707-
while (IsA(expr, RelabelType))
1708-
expr = (Expr *) (castNode(RelabelType, expr))->arg;
1709-
1710-
for (cnt = 0; cnt < rel->part_scheme->partnatts; cnt++)
1711-
{
1712-
ListCell *lc;
1713-
1714-
Assert(rel->partexprs);
1715-
foreach(lc, rel->partexprs[cnt])
1716-
{
1717-
if (equal(lfirst(lc), expr))
1718-
return cnt;
1719-
}
1720-
1721-
if (!strict_op)
1722-
continue;
1723-
1724-
/*
1725-
* If it's a strict equi-join a NULL partition key on one side will
1726-
* not join a NULL partition key on the other side. So, rows with NULL
1727-
* partition key from a partition on one side can not join with those
1728-
* from a non-matching partition on the other side. So, search the
1729-
* nullable partition keys as well.
1730-
*/
1731-
Assert(rel->nullable_partexprs);
1732-
foreach(lc, rel->nullable_partexprs[cnt])
1733-
{
1734-
if (equal(lfirst(lc), expr))
1735-
return cnt;
1736-
}
1737-
}
1738-
1739-
return -1;
1740-
}

src/backend/optimizer/util/plancat.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,9 +2250,8 @@ find_partition_scheme(PlannerInfo *root, Relation relation)
22502250
/*
22512251
* set_baserel_partition_key_exprs
22522252
*
2253-
* Builds partition key expressions for the given base relation and sets them
2254-
* in given RelOptInfo. Any single column partition keys are converted to Var
2255-
* nodes. All Var nodes are restamped with the relid of given relation.
2253+
* Builds partition key expressions for the given base relation and fills
2254+
* rel->partexprs.
22562255
*/
22572256
static void
22582257
set_baserel_partition_key_exprs(Relation relation,
@@ -2300,16 +2299,17 @@ set_baserel_partition_key_exprs(Relation relation,
23002299
lc = lnext(partkey->partexprs, lc);
23012300
}
23022301

2302+
/* Base relations have a single expression per key. */
23032303
partexprs[cnt] = list_make1(partexpr);
23042304
}
23052305

23062306
rel->partexprs = partexprs;
23072307

23082308
/*
2309-
* A base relation can not have nullable partition key expressions. We
2310-
* still allocate array of empty expressions lists to keep partition key
2311-
* expression handling code simple. See build_joinrel_partition_info() and
2312-
* match_expr_to_partition_keys().
2309+
* A base relation does not have nullable partition key expressions, since
2310+
* no outer join is involved. We still allocate an array of empty
2311+
* expression lists to keep partition key expression handling code simple.
2312+
* See build_joinrel_partition_info() and match_expr_to_partition_keys().
23132313
*/
23142314
rel->nullable_partexprs = (List **) palloc0(sizeof(List *) * partnatts);
23152315
}

0 commit comments

Comments
 (0)