Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5f789c5

Browse files
committed
Extend relation_excluded_by_constraints() to check for mutually
contradictory WHERE-clauses applied to a relation. This makes theGUC variable constraint_exclusion rather inappropriately named,but I've refrained for the moment from renaming it.Per example from Martin Lesser.
1 parent6357f4e commit5f789c5

File tree

1 file changed

+43
-6
lines changed

1 file changed

+43
-6
lines changed

‎src/backend/optimizer/util/plancat.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.123 2006/08/02 01:59:46 joe Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.124 2006/08/05 00:22:49 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -438,18 +438,42 @@ get_relation_constraints(Oid relationObjectId, RelOptInfo *rel)
438438
/*
439439
* relation_excluded_by_constraints
440440
*
441-
* Detect whether the relation need not be scanned because it has CHECK
442-
* constraints that conflict with the query's WHERE clause.
441+
* Detect whether the relation need not be scanned because it has either
442+
* self-inconsistent restrictions, or restrictions inconsistent with the
443+
* relation's CHECK constraints.
443444
*/
444445
bool
445446
relation_excluded_by_constraints(RelOptInfo*rel,RangeTblEntry*rte)
446447
{
448+
List*safe_restrictions;
447449
List*constraint_pred;
450+
List*safe_constraints;
451+
ListCell*lc;
448452

449453
/* Skip the test if constraint exclusion is disabled */
450454
if (!constraint_exclusion)
451455
return false;
452456

457+
/*
458+
* Check for self-contradictory restriction clauses. We dare not make
459+
* deductions with non-immutable functions, but any immutable clauses that
460+
* are self-contradictory allow us to conclude the scan is unnecessary.
461+
*
462+
* Note: strip off RestrictInfo because predicate_refuted_by() isn't
463+
* expecting to see any in its predicate argument.
464+
*/
465+
safe_restrictions=NIL;
466+
foreach(lc,rel->baserestrictinfo)
467+
{
468+
RestrictInfo*rinfo= (RestrictInfo*)lfirst(lc);
469+
470+
if (!contain_mutable_functions((Node*)rinfo->clause))
471+
safe_restrictions=lappend(safe_restrictions,rinfo->clause);
472+
}
473+
474+
if (predicate_refuted_by(safe_restrictions,safe_restrictions))
475+
return true;
476+
453477
/* Only plain relations have constraints */
454478
if (rte->rtekind!=RTE_RELATION||rte->inh)
455479
return false;
@@ -461,16 +485,29 @@ relation_excluded_by_constraints(RelOptInfo *rel, RangeTblEntry *rte)
461485
* We do not currently enforce that CHECK constraints contain only
462486
* immutable functions, so it's necessary to check here. We daren't draw
463487
* conclusions from plan-time evaluation of non-immutable functions.
488+
* Since they're ANDed, we can just ignore any mutable constraints in
489+
* the list, and reason about the rest.
464490
*/
465-
if (contain_mutable_functions((Node*)constraint_pred))
466-
return false;
491+
safe_constraints=NIL;
492+
foreach(lc,constraint_pred)
493+
{
494+
Node*pred= (Node*)lfirst(lc);
495+
496+
if (!contain_mutable_functions(pred))
497+
safe_constraints=lappend(safe_constraints,pred);
498+
}
467499

468500
/*
469501
* The constraints are effectively ANDed together, so we can just try to
470502
* refute the entire collection at once. This may allow us to make proofs
471503
* that would fail if we took them individually.
504+
*
505+
* Note: we use rel->baserestrictinfo, not safe_restrictions as might
506+
* seem an obvious optimization. Some of the clauses might be OR clauses
507+
* that have volatile and nonvolatile subclauses, and it's OK to make
508+
* deductions with the nonvolatile parts.
472509
*/
473-
if (predicate_refuted_by(constraint_pred,rel->baserestrictinfo))
510+
if (predicate_refuted_by(safe_constraints,rel->baserestrictinfo))
474511
return true;
475512

476513
return false;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp