mirror of
https://github.com/postgres/postgres.git
synced 2025-10-19 15:49:24 +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
|
* a set of equality conditions, because the conditions constrain all
|
||||||
* columns of some unique index.
|
* columns of some unique index.
|
||||||
*
|
*
|
||||||
* The conditions can be represented in either or both of two ways:
|
* The conditions are provided as a list of RestrictInfo nodes, where the
|
||||||
* 1. A list of RestrictInfo nodes, where the caller has already determined
|
* caller has already determined that each condition is a mergejoinable
|
||||||
* that each condition is a mergejoinable equality with an expression in
|
* equality with an expression in this relation on one side, and an
|
||||||
* this relation on one side, and an expression not involving this relation
|
* expression not involving this relation on the other. The transient
|
||||||
* on the other. The transient outer_is_left flag is used to identify which
|
* outer_is_left flag is used to identify which side we should look at:
|
||||||
* side we should look at: left side if outer_is_left is false, right side
|
* left side if outer_is_left is false, right side if it is true.
|
||||||
* 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 caller need only supply equality conditions arising from joins;
|
* The caller need only supply equality conditions arising from joins;
|
||||||
* this routine automatically adds in any usable baserestrictinfo clauses.
|
* this routine automatically adds in any usable baserestrictinfo clauses.
|
||||||
* (Note that the passed-in restrictlist will be destructively modified!)
|
* (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
|
bool
|
||||||
relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
|
relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
|
||||||
List *restrictlist,
|
List *restrictlist, List **extra_clauses)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
ListCell *ic;
|
ListCell *ic;
|
||||||
|
|
||||||
Assert(list_length(exprlist) == list_length(oprlist));
|
|
||||||
|
|
||||||
/* Short-circuit if no indexes... */
|
/* Short-circuit if no indexes... */
|
||||||
if (rel->indexlist == NIL)
|
if (rel->indexlist == NIL)
|
||||||
return false;
|
return false;
|
||||||
@@ -4225,7 +4204,7 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Short-circuit the easy case */
|
/* Short-circuit the easy case */
|
||||||
if (restrictlist == NIL && exprlist == NIL)
|
if (restrictlist == NIL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Examine each index of the relation ... */
|
/* Examine each index of the relation ... */
|
||||||
@@ -4247,14 +4226,12 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
continue;
|
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.
|
* O(N^2) or worse, but we expect all the lists to be short.
|
||||||
*/
|
*/
|
||||||
for (c = 0; c < ind->nkeycolumns; c++)
|
for (c = 0; c < ind->nkeycolumns; c++)
|
||||||
{
|
{
|
||||||
bool matched = false;
|
|
||||||
ListCell *lc;
|
ListCell *lc;
|
||||||
ListCell *lc2;
|
|
||||||
|
|
||||||
foreach(lc, restrictlist)
|
foreach(lc, restrictlist)
|
||||||
{
|
{
|
||||||
@@ -4284,8 +4261,6 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
|
|
||||||
if (match_index_to_operand(rexpr, c, ind))
|
if (match_index_to_operand(rexpr, c, ind))
|
||||||
{
|
{
|
||||||
matched = true; /* column is unique */
|
|
||||||
|
|
||||||
if (bms_membership(rinfo->clause_relids) == BMS_SINGLETON)
|
if (bms_membership(rinfo->clause_relids) == BMS_SINGLETON)
|
||||||
{
|
{
|
||||||
MemoryContext oldMemCtx =
|
MemoryContext oldMemCtx =
|
||||||
@@ -4303,43 +4278,11 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
MemoryContextSwitchTo(oldMemCtx);
|
MemoryContextSwitchTo(oldMemCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break; /* found a match; column is unique */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matched)
|
if (lc == NULL)
|
||||||
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)
|
|
||||||
break; /* no match; this index doesn't help us */
|
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.
|
* 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.
|
* restriction clauses for the rel, so we needn't do that here.
|
||||||
*/
|
*/
|
||||||
if (relation_has_unique_index_ext(root, rel, clause_list, NIL, NIL,
|
if (relation_has_unique_index_for(root, rel, clause_list, extra_clauses))
|
||||||
extra_clauses))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (rel->rtekind == RTE_SUBQUERY)
|
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 void create_index_paths(PlannerInfo *root, RelOptInfo *rel);
|
||||||
extern bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
|
extern bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
|
||||||
List *restrictlist,
|
List *restrictlist,
|
||||||
List *exprlist, List *oprlist);
|
List **extra_clauses);
|
||||||
extern bool relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
|
|
||||||
List *restrictlist, List *exprlist,
|
|
||||||
List *oprlist, List **extra_clauses);
|
|
||||||
extern bool indexcol_is_bool_constant_for_query(PlannerInfo *root,
|
extern bool indexcol_is_bool_constant_for_query(PlannerInfo *root,
|
||||||
IndexOptInfo *index,
|
IndexOptInfo *index,
|
||||||
int indexcol);
|
int indexcol);
|
||||||
|
Reference in New Issue
Block a user