* However, currently the extended-stats machinery won't do anything
* with non-RestrictInfo clauses anyway, so there's no point in
* spending extra cycles; just fail if that's what we have.
+ *
+ * An exception to that rule is if we have a bare BoolExpr AND clause.
+ * We treat this as a special case because the restrictinfo machinery
+ * doesn't build RestrictInfos on top of AND clauses.
*/
+ if (is_andclause(rinfo))
+ {
+ RelOptInfo *rel;
+
+ rel = find_single_rel_for_clauses(root,
+ ((BoolExpr *) rinfo)->args);
+
+ if (rel == NULL)
+ return NULL;
+ if (lastrelid == 0)
+ lastrelid = rel->relid;
+ else if (rel->relid != lastrelid)
+ return NULL;
+
+ continue;
+ }
+
if (!IsA(rinfo, RestrictInfo))
return NULL;
RestrictInfo *rinfo = (RestrictInfo *) clause;
Oid userid;
+ /*
+ * Special-case handling for bare BoolExpr AND clauses, because the
+ * restrictinfo machinery doesn't build RestrictInfos on top of AND
+ * clauses.
+ */
+ if (is_andclause(clause))
+ {
+ BoolExpr *expr = (BoolExpr *) clause;
+ ListCell *lc;
+
+ /*
+ * Check that each sub-clause is compatible. We expect these to be
+ * RestrictInfos.
+ */
+ foreach(lc, expr->args)
+ {
+ if (!statext_is_compatible_clause(root, (Node *) lfirst(lc),
+ relid, attnums))
+ return false;
+ }
+
+ return true;
+ }
+
+ /* Otherwise it must be a RestrictInfo. */
if (!IsA(rinfo, RestrictInfo))
return false;
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c = 0) OR (a = 1 AND b = 1 AND c = 1) OR (a = 2 AND b = 2 AND c = 2)');
estimated | actual
-----------+--------
- 300 | 306
+ 306 | 306
(1 row)
SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a = 0 AND c = 0) OR (b = 0 AND c = 0)');
estimated | actual
-----------+--------
- 306 | 102
+ 108 | 102
(1 row)
DROP TABLE mcv_lists_partial;