20
20
#include "optimizer/pathnode.h"
21
21
#include "optimizer/paths.h"
22
22
#include "partitioning/partbounds.h"
23
- #include "utils/lsyscache.h"
24
23
#include "utils/memutils.h"
25
24
26
25
@@ -46,8 +45,6 @@ static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1,
46
45
static SpecialJoinInfo * build_child_join_sjinfo (PlannerInfo * root ,
47
46
SpecialJoinInfo * parent_sjinfo ,
48
47
Relids left_relids , Relids right_relids );
49
- static int match_expr_to_partition_keys (Expr * expr , RelOptInfo * rel ,
50
- bool strict_op );
51
48
52
49
53
50
/*
@@ -1573,168 +1570,3 @@ build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
1573
1570
1574
1571
return sjinfo ;
1575
1572
}
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
- }
0 commit comments