summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r--src/backend/optimizer/util/plancat.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index c926ae5d488..b6dcfa144f2 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.117 2006/01/31 21:39:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.118 2006/02/04 23:03:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,6 +25,7 @@
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/plancat.h"
+#include "optimizer/predtest.h"
#include "optimizer/prep.h"
#include "optimizer/tlist.h"
#include "parser/parsetree.h"
@@ -40,8 +41,13 @@
#include "miscadmin.h"
+/* GUC parameter */
+bool constraint_exclusion = false;
+
+
static void estimate_rel_size(Relation rel, int32 *attr_widths,
BlockNumber *pages, double *tuples);
+static List *get_relation_constraints(Oid relationObjectId, RelOptInfo *rel);
/*
@@ -360,7 +366,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
* run, and in many cases it won't be invoked at all, so there seems no
* point in caching the data in RelOptInfo.
*/
-List *
+static List *
get_relation_constraints(Oid relationObjectId, RelOptInfo *rel)
{
List *result = NIL;
@@ -425,6 +431,48 @@ get_relation_constraints(Oid relationObjectId, RelOptInfo *rel)
/*
+ * relation_excluded_by_constraints
+ *
+ * Detect whether the relation need not be scanned because it has CHECK
+ * constraints that conflict with the query's WHERE clause.
+ */
+bool
+relation_excluded_by_constraints(RelOptInfo *rel, RangeTblEntry *rte)
+{
+ List *constraint_pred;
+
+ /* Skip the test if constraint exclusion is disabled */
+ if (!constraint_exclusion)
+ return false;
+
+ /* Only plain relations have constraints */
+ if (rte->rtekind != RTE_RELATION || rte->inh)
+ return false;
+
+ /* OK to fetch the constraint expressions */
+ constraint_pred = get_relation_constraints(rte->relid, rel);
+
+ /*
+ * We do not currently enforce that CHECK constraints contain only
+ * immutable functions, so it's necessary to check here. We daren't draw
+ * conclusions from plan-time evaluation of non-immutable functions.
+ */
+ if (contain_mutable_functions((Node *) constraint_pred))
+ return false;
+
+ /*
+ * The constraints are effectively ANDed together, so we can just try to
+ * refute the entire collection at once. This may allow us to make proofs
+ * that would fail if we took them individually.
+ */
+ if (predicate_refuted_by(constraint_pred, rel->baserestrictinfo))
+ return true;
+
+ return false;
+}
+
+
+/*
* build_physical_tlist
*
* Build a targetlist consisting of exactly the relation's user attributes,