Files
postgresql/src/test/modules/test_predtest
Tom Lane 65ce07e020 Teach optimizer's predtest.c more things about ScalarArrayOpExpr.
In particular, make it possible to prove/refute "x IS NULL" and
"x IS NOT NULL" predicates from a clause involving a ScalarArrayOpExpr
even when we are unable or unwilling to deconstruct the expression
into an AND/OR tree.  This avoids a former unexpected degradation of
plan quality when the size of an ARRAY[] expression or array constant
exceeded the arbitrary MAX_SAOP_ARRAY_SIZE limit.  For IS-NULL proofs,
we don't really care about the values of the individual array elements;
at most, we care whether there are any, and for some common cases we
needn't even know that.

The main user-visible effect of this is to let the optimizer recognize
applicability of partial indexes with "x IS NOT NULL" predicates to
queries with "x IN (array)" clauses in some cases where it previously
failed to recognize that.  The structure of predtest.c is such that a
bunch of related proofs will now also succeed, but they're probably
much less useful in the wild.

James Coleman, reviewed by David Rowley

Discussion: https://postgr.es/m/CAAaqYe8yKSvzbyu8w-dThRs9aTFMwrFxn_BkTYeXgjqe3CbNjg@mail.gmail.com
2019-03-01 17:14:17 -05:00
..

test_predtest is a module for checking the correctness of the optimizer's
predicate-proof logic, in src/backend/optimizer/util/predtest.c.

The module provides a function that allows direct application of
predtest.c's exposed functions, predicate_implied_by() and
predicate_refuted_by(), to arbitrary boolean expressions, with direct
inspection of the results.  This could be done indirectly by checking
planner results, but it can be difficult to construct end-to-end test
cases that prove that the expected results were obtained.

In general, the use of this function is like
	select * from test_predtest('query string')
where the query string must be a SELECT returning two boolean
columns, for example

	select * from test_predtest($$
	select x, not x
	from (values (false), (true), (null)) as v(x)
	$$);

The function parses and plans the given query, and then applies the
predtest.c code to the two boolean expressions in the SELECT list, to see
if the first expression can be proven or refuted by the second.  It also
executes the query, and checks the resulting rows to see whether any
claimed implication or refutation relationship actually holds.  If the
query is designed to exercise the expressions on a full set of possible
input values, as in the example above, then this provides a mechanical
cross-check as to whether the proof code has given a correct answer.