aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-05-11 17:56:22 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-05-11 17:56:22 +0000
commit1b72c707029b4639019fe34a60f05156ac27bfc0 (patch)
tree2b7dfd95b29f44e56e638ec97a08baf75b4f8a7a
parent2518811877f6b9320bf364b7384d53d5bbf84c40 (diff)
downloadpostgresql-1b72c707029b4639019fe34a60f05156ac27bfc0.tar.gz
postgresql-1b72c707029b4639019fe34a60f05156ac27bfc0.zip
Partially revert my patch of 2008-11-12 that installed a limit on the number
of AND/OR clause branches that predtest.c would attempt to deal with. As noted in bug #4721, that change disabled proof attempts for sizes of problems that people are actually expecting it to work for. The original complaint it was trying to solve was O(N^2) behavior for long IN-lists, so let's try applying the limit to just ScalarArrayOpExprs rather than everything. Another case of "foolish consistency" I fear. Back-patch to 8.2, same as the previous patch was.
-rw-r--r--src/backend/optimizer/util/predtest.c39
1 files changed, 18 insertions, 21 deletions
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index 4730ce46298..56e709093b2 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.10.2.4 2008/11/12 23:08:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.10.2.5 2009/05/11 17:56:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,13 +29,13 @@
/*
- * Proof attempts involving many AND or OR branches are likely to require
- * O(N^2) time, and more often than not fail anyway. So we set an arbitrary
- * limit on the number of branches that we will allow at any one level of
- * clause. (Note that this is only effective because the trees have been
- * AND/OR flattened!) XXX is it worth exposing this as a GUC knob?
+ * Proof attempts involving large arrays in ScalarArrayOpExpr nodes are
+ * likely to require O(N^2) time, and more often than not fail anyway.
+ * So we set an arbitrary limit on the number of array elements that
+ * we will allow to be treated as an AND or OR clause.
+ * XXX is it worth exposing this as a GUC knob?
*/
-#define MAX_BRANCHES_TO_TEST 100
+#define MAX_SAOP_ARRAY_SIZE 100
/*
* To avoid redundant coding in predicate_implied_by_recurse and
@@ -697,12 +697,12 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate)
* If the expression is classified as AND- or OR-type, then *info is filled
* in with the functions needed to iterate over its components.
*
- * This function also implements enforcement of MAX_BRANCHES_TO_TEST: if an
- * AND/OR expression has too many branches, we just classify it as an atom.
- * (This will result in its being passed as-is to the simple_clause functions,
- * which will fail to prove anything about it.) Note that we cannot just stop
- * after considering MAX_BRANCHES_TO_TEST branches; in general that would
- * result in wrong proofs rather than failing to prove anything.
+ * This function also implements enforcement of MAX_SAOP_ARRAY_SIZE: if a
+ * ScalarArrayOpExpr's array has too many elements, we just classify it as an
+ * atom. (This will result in its being passed as-is to the simple_clause
+ * functions, which will fail to prove anything about it.) Note that we
+ * cannot just stop after considering MAX_SAOP_ARRAY_SIZE elements; in general
+ * that would result in wrong proofs, rather than failing to prove anything.
*/
static PredClass
predicate_classify(Node *clause, PredIterInfo info)
@@ -715,8 +715,7 @@ predicate_classify(Node *clause, PredIterInfo info)
* If we see a List, assume it's an implicit-AND list; this is the correct
* semantics for lists of RestrictInfo nodes.
*/
- if (IsA(clause, List) &&
- list_length((List *) clause) <= MAX_BRANCHES_TO_TEST)
+ if (IsA(clause, List))
{
info->startup_fn = list_startup_fn;
info->next_fn = list_next_fn;
@@ -725,16 +724,14 @@ predicate_classify(Node *clause, PredIterInfo info)
}
/* Handle normal AND and OR boolean clauses */
- if (and_clause(clause) &&
- list_length(((BoolExpr *) clause)->args) <= MAX_BRANCHES_TO_TEST)
+ if (and_clause(clause))
{
info->startup_fn = boolexpr_startup_fn;
info->next_fn = list_next_fn;
info->cleanup_fn = list_cleanup_fn;
return CLASS_AND;
}
- if (or_clause(clause) &&
- list_length(((BoolExpr *) clause)->args) <= MAX_BRANCHES_TO_TEST)
+ if (or_clause(clause))
{
info->startup_fn = boolexpr_startup_fn;
info->next_fn = list_next_fn;
@@ -762,7 +759,7 @@ predicate_classify(Node *clause, PredIterInfo info)
arrayval = DatumGetArrayTypeP(((Const *) arraynode)->constvalue);
nelems = ArrayGetNItems(ARR_NDIM(arrayval), ARR_DIMS(arrayval));
- if (nelems <= MAX_BRANCHES_TO_TEST)
+ if (nelems <= MAX_SAOP_ARRAY_SIZE)
{
info->startup_fn = arrayconst_startup_fn;
info->next_fn = arrayconst_next_fn;
@@ -772,7 +769,7 @@ predicate_classify(Node *clause, PredIterInfo info)
}
else if (arraynode && IsA(arraynode, ArrayExpr) &&
!((ArrayExpr *) arraynode)->multidims &&
- list_length(((ArrayExpr *) arraynode)->elements) <= MAX_BRANCHES_TO_TEST)
+ list_length(((ArrayExpr *) arraynode)->elements) <= MAX_SAOP_ARRAY_SIZE)
{
info->startup_fn = arrayexpr_startup_fn;
info->next_fn = arrayexpr_next_fn;