mirror of
https://github.com/postgres/postgres.git
synced 2025-10-16 17:07:43 +03:00
Simplify relation_has_unique_index_for()
Now that the only call to relation_has_unique_index_for() that supplied an exprlist and oprlist has been removed, the loop handling those lists is effectively dead code. This patch removes that loop and simplifies the function accordingly. Author: Richard Guo <guofenglinux@gmail.com> Discussion: https://postgr.es/m/CAMbWs4-EBnaRvEs7frTLbsXiweSTUXifsteF-d3rvv01FKO86w@mail.gmail.com
This commit is contained in:
@@ -4142,47 +4142,26 @@ ec_member_matches_indexcol(PlannerInfo *root, RelOptInfo *rel,
|
||||
* a set of equality conditions, because the conditions constrain all
|
||||
* columns of some unique index.
|
||||
*
|
||||
* The conditions can be represented in either or both of two ways:
|
||||
* 1. A list of RestrictInfo nodes, where the caller has already determined
|
||||
* that each condition is a mergejoinable equality with an expression in
|
||||
* this relation on one side, and an expression not involving this relation
|
||||
* on the other. The transient outer_is_left flag is used to identify which
|
||||
* side we should look at: left side if outer_is_left is false, right side
|
||||
* if it is true.
|
||||
* 2. A list of expressions in this relation, and a corresponding list of
|
||||
* equality operators. The caller must have already checked that the operators
|
||||
* represent equality. (Note: the operators could be cross-type; the
|
||||
* expressions should correspond to their RHS inputs.)
|
||||
* The conditions are provided as a list of RestrictInfo nodes, where the
|
||||
* caller has already determined that each condition is a mergejoinable
|
||||
* equality with an expression in this relation on one side, and an
|
||||
* expression not involving this relation on the other. The transient
|
||||
* outer_is_left flag is used to identify which side we should look at:
|
||||
* left side if outer_is_left is false, right side if it is true.
|
||||
*
|
||||
* The caller need only supply equality conditions arising from joins;
|
||||
* this routine automatically adds in any usable baserestrictinfo clauses.
|
||||
* (Note that the passed-in restrictlist will be destructively modified!)
|
||||
*
|
||||
* If extra_clauses isn't NULL, return baserestrictinfo clauses which were used
|
||||
* to derive uniqueness.
|
||||
*/
|
||||
bool
|
||||
relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
|
||||
List *restrictlist,
|
||||
List *exprlist, List *oprlist)
|
||||
{
|
||||
return relation_has_unique_index_ext(root, rel, restrictlist,
|
||||
exprlist, oprlist, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* relation_has_unique_index_ext
|
||||
* Same as relation_has_unique_index_for(), but supports extra_clauses
|
||||
* parameter. If extra_clauses isn't NULL, return baserestrictinfo clauses
|
||||
* which were used to derive uniqueness.
|
||||
*/
|
||||
bool
|
||||
relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
||||
List *restrictlist,
|
||||
List *exprlist, List *oprlist,
|
||||
List **extra_clauses)
|
||||
List *restrictlist, List **extra_clauses)
|
||||
{
|
||||
ListCell *ic;
|
||||
|
||||
Assert(list_length(exprlist) == list_length(oprlist));
|
||||
|
||||
/* Short-circuit if no indexes... */
|
||||
if (rel->indexlist == NIL)
|
||||
return false;
|
||||
@@ -4225,7 +4204,7 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
||||
}
|
||||
|
||||
/* Short-circuit the easy case */
|
||||
if (restrictlist == NIL && exprlist == NIL)
|
||||
if (restrictlist == NIL)
|
||||
return false;
|
||||
|
||||
/* Examine each index of the relation ... */
|
||||
@@ -4247,14 +4226,12 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Try to find each index column in the lists of conditions. This is
|
||||
* Try to find each index column in the list of conditions. This is
|
||||
* O(N^2) or worse, but we expect all the lists to be short.
|
||||
*/
|
||||
for (c = 0; c < ind->nkeycolumns; c++)
|
||||
{
|
||||
bool matched = false;
|
||||
ListCell *lc;
|
||||
ListCell *lc2;
|
||||
|
||||
foreach(lc, restrictlist)
|
||||
{
|
||||
@@ -4284,8 +4261,6 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
||||
|
||||
if (match_index_to_operand(rexpr, c, ind))
|
||||
{
|
||||
matched = true; /* column is unique */
|
||||
|
||||
if (bms_membership(rinfo->clause_relids) == BMS_SINGLETON)
|
||||
{
|
||||
MemoryContext oldMemCtx =
|
||||
@@ -4303,43 +4278,11 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
||||
MemoryContextSwitchTo(oldMemCtx);
|
||||
}
|
||||
|
||||
break;
|
||||
break; /* found a match; column is unique */
|
||||
}
|
||||
}
|
||||
|
||||
if (matched)
|
||||
continue;
|
||||
|
||||
forboth(lc, exprlist, lc2, oprlist)
|
||||
{
|
||||
Node *expr = (Node *) lfirst(lc);
|
||||
Oid opr = lfirst_oid(lc2);
|
||||
|
||||
/* See if the expression matches the index key */
|
||||
if (!match_index_to_operand(expr, c, ind))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The equality operator must be a member of the index
|
||||
* opfamily, else it is not asserting the right kind of
|
||||
* equality behavior for this index. We assume the caller
|
||||
* determined it is an equality operator, so we don't need to
|
||||
* check any more tightly than this.
|
||||
*/
|
||||
if (!op_in_opfamily(opr, ind->opfamily[c]))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* XXX at some point we may need to check collations here too.
|
||||
* For the moment we assume all collations reduce to the same
|
||||
* notion of equality.
|
||||
*/
|
||||
|
||||
matched = true; /* column is unique */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!matched)
|
||||
if (lc == NULL)
|
||||
break; /* no match; this index doesn't help us */
|
||||
}
|
||||
|
||||
|
@@ -990,11 +990,10 @@ rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel, List *clause_list,
|
||||
{
|
||||
/*
|
||||
* Examine the indexes to see if we have a matching unique index.
|
||||
* relation_has_unique_index_ext automatically adds any usable
|
||||
* relation_has_unique_index_for automatically adds any usable
|
||||
* restriction clauses for the rel, so we needn't do that here.
|
||||
*/
|
||||
if (relation_has_unique_index_ext(root, rel, clause_list, NIL, NIL,
|
||||
extra_clauses))
|
||||
if (relation_has_unique_index_for(root, rel, clause_list, extra_clauses))
|
||||
return true;
|
||||
}
|
||||
else if (rel->rtekind == RTE_SUBQUERY)
|
||||
|
@@ -71,10 +71,7 @@ extern void generate_partitionwise_join_paths(PlannerInfo *root,
|
||||
extern void create_index_paths(PlannerInfo *root, RelOptInfo *rel);
|
||||
extern bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
|
||||
List *restrictlist,
|
||||
List *exprlist, List *oprlist);
|
||||
extern bool relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
||||
List *restrictlist, List *exprlist,
|
||||
List *oprlist, List **extra_clauses);
|
||||
List **extra_clauses);
|
||||
extern bool indexcol_is_bool_constant_for_query(PlannerInfo *root,
|
||||
IndexOptInfo *index,
|
||||
int indexcol);
|
||||
|
Reference in New Issue
Block a user