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 */
444445bool
445446relation_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