1 /*-------------------------------------------------------------------------
2  *
3  * predtest.c
4  *	  Routines to attempt to prove logical implications between predicate
5  *	  expressions.
6  *
7  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *	  src/backend/optimizer/util/predtest.c
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17 
18 #include "catalog/pg_proc.h"
19 #include "catalog/pg_type.h"
20 #include "executor/executor.h"
21 #include "miscadmin.h"
22 #include "nodes/nodeFuncs.h"
23 #include "optimizer/clauses.h"
24 #include "optimizer/predtest.h"
25 #include "utils/array.h"
26 #include "utils/inval.h"
27 #include "utils/lsyscache.h"
28 #include "utils/syscache.h"
29 
30 
31 /*
32  * Proof attempts involving large arrays in ScalarArrayOpExpr nodes are
33  * likely to require O(N^2) time, and more often than not fail anyway.
34  * So we set an arbitrary limit on the number of array elements that
35  * we will allow to be treated as an AND or OR clause.
36  * XXX is it worth exposing this as a GUC knob?
37  */
38 #define MAX_SAOP_ARRAY_SIZE		100
39 
40 /*
41  * To avoid redundant coding in predicate_implied_by_recurse and
42  * predicate_refuted_by_recurse, we need to abstract out the notion of
43  * iterating over the components of an expression that is logically an AND
44  * or OR structure.  There are multiple sorts of expression nodes that can
45  * be treated as ANDs or ORs, and we don't want to code each one separately.
46  * Hence, these types and support routines.
47  */
48 typedef enum
49 {
50 	CLASS_ATOM,					/* expression that's not AND or OR */
51 	CLASS_AND,					/* expression with AND semantics */
52 	CLASS_OR					/* expression with OR semantics */
53 } PredClass;
54 
55 typedef struct PredIterInfoData *PredIterInfo;
56 
57 typedef struct PredIterInfoData
58 {
59 	/* node-type-specific iteration state */
60 	void	   *state;
61 	/* initialize to do the iteration */
62 	void		(*startup_fn) (Node *clause, PredIterInfo info);
63 	/* next-component iteration function */
64 	Node	   *(*next_fn) (PredIterInfo info);
65 	/* release resources when done with iteration */
66 	void		(*cleanup_fn) (PredIterInfo info);
67 } PredIterInfoData;
68 
69 #define iterate_begin(item, clause, info)	\
70 	do { \
71 		Node   *item; \
72 		(info).startup_fn((clause), &(info)); \
73 		while ((item = (info).next_fn(&(info))) != NULL)
74 
75 #define iterate_end(info)	\
76 		(info).cleanup_fn(&(info)); \
77 	} while (0)
78 
79 
80 static bool predicate_implied_by_recurse(Node *clause, Node *predicate);
81 static bool predicate_refuted_by_recurse(Node *clause, Node *predicate);
82 static PredClass predicate_classify(Node *clause, PredIterInfo info);
83 static void list_startup_fn(Node *clause, PredIterInfo info);
84 static Node *list_next_fn(PredIterInfo info);
85 static void list_cleanup_fn(PredIterInfo info);
86 static void boolexpr_startup_fn(Node *clause, PredIterInfo info);
87 static void arrayconst_startup_fn(Node *clause, PredIterInfo info);
88 static Node *arrayconst_next_fn(PredIterInfo info);
89 static void arrayconst_cleanup_fn(PredIterInfo info);
90 static void arrayexpr_startup_fn(Node *clause, PredIterInfo info);
91 static Node *arrayexpr_next_fn(PredIterInfo info);
92 static void arrayexpr_cleanup_fn(PredIterInfo info);
93 static bool predicate_implied_by_simple_clause(Expr *predicate, Node *clause);
94 static bool predicate_refuted_by_simple_clause(Expr *predicate, Node *clause);
95 static Node *extract_not_arg(Node *clause);
96 static Node *extract_strong_not_arg(Node *clause);
97 static bool list_member_strip(List *list, Expr *datum);
98 static bool operator_predicate_proof(Expr *predicate, Node *clause,
99 						 bool refute_it);
100 static bool operator_same_subexprs_proof(Oid pred_op, Oid clause_op,
101 							 bool refute_it);
102 static bool operator_same_subexprs_lookup(Oid pred_op, Oid clause_op,
103 							  bool refute_it);
104 static Oid	get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it);
105 static void InvalidateOprProofCacheCallBack(Datum arg, int cacheid, uint32 hashvalue);
106 
107 
108 /*
109  * predicate_implied_by
110  *	  Recursively checks whether the clauses in restrictinfo_list imply
111  *	  that the given predicate is true.
112  *
113  * The top-level List structure of each list corresponds to an AND list.
114  * We assume that eval_const_expressions() has been applied and so there
115  * are no un-flattened ANDs or ORs (e.g., no AND immediately within an AND,
116  * including AND just below the top-level List structure).
117  * If this is not true we might fail to prove an implication that is
118  * valid, but no worse consequences will ensue.
119  *
120  * We assume the predicate has already been checked to contain only
121  * immutable functions and operators.  (In most current uses this is true
122  * because the predicate is part of an index predicate that has passed
123  * CheckPredicate().)  We dare not make deductions based on non-immutable
124  * functions, because they might change answers between the time we make
125  * the plan and the time we execute the plan.
126  */
127 bool
predicate_implied_by(List * predicate_list,List * restrictinfo_list)128 predicate_implied_by(List *predicate_list, List *restrictinfo_list)
129 {
130 	Node	   *p,
131 			   *r;
132 
133 	if (predicate_list == NIL)
134 		return true;			/* no predicate: implication is vacuous */
135 	if (restrictinfo_list == NIL)
136 		return false;			/* no restriction: implication must fail */
137 
138 	/*
139 	 * If either input is a single-element list, replace it with its lone
140 	 * member; this avoids one useless level of AND-recursion.  We only need
141 	 * to worry about this at top level, since eval_const_expressions should
142 	 * have gotten rid of any trivial ANDs or ORs below that.
143 	 */
144 	if (list_length(predicate_list) == 1)
145 		p = (Node *) linitial(predicate_list);
146 	else
147 		p = (Node *) predicate_list;
148 	if (list_length(restrictinfo_list) == 1)
149 		r = (Node *) linitial(restrictinfo_list);
150 	else
151 		r = (Node *) restrictinfo_list;
152 
153 	/* And away we go ... */
154 	return predicate_implied_by_recurse(r, p);
155 }
156 
157 /*
158  * predicate_refuted_by
159  *	  Recursively checks whether the clauses in restrictinfo_list refute
160  *	  the given predicate (that is, prove it false).
161  *
162  * This is NOT the same as !(predicate_implied_by), though it is similar
163  * in the technique and structure of the code.
164  *
165  * An important fine point is that truth of the clauses must imply that
166  * the predicate returns FALSE, not that it does not return TRUE.  This
167  * is normally used to try to refute CHECK constraints, and the only
168  * thing we can assume about a CHECK constraint is that it didn't return
169  * FALSE --- a NULL result isn't a violation per the SQL spec.  (Someday
170  * perhaps this code should be extended to support both "strong" and
171  * "weak" refutation, but for now we only need "strong".)
172  *
173  * The top-level List structure of each list corresponds to an AND list.
174  * We assume that eval_const_expressions() has been applied and so there
175  * are no un-flattened ANDs or ORs (e.g., no AND immediately within an AND,
176  * including AND just below the top-level List structure).
177  * If this is not true we might fail to prove an implication that is
178  * valid, but no worse consequences will ensue.
179  *
180  * We assume the predicate has already been checked to contain only
181  * immutable functions and operators.  We dare not make deductions based on
182  * non-immutable functions, because they might change answers between the
183  * time we make the plan and the time we execute the plan.
184  */
185 bool
predicate_refuted_by(List * predicate_list,List * restrictinfo_list)186 predicate_refuted_by(List *predicate_list, List *restrictinfo_list)
187 {
188 	Node	   *p,
189 			   *r;
190 
191 	if (predicate_list == NIL)
192 		return false;			/* no predicate: no refutation is possible */
193 	if (restrictinfo_list == NIL)
194 		return false;			/* no restriction: refutation must fail */
195 
196 	/*
197 	 * If either input is a single-element list, replace it with its lone
198 	 * member; this avoids one useless level of AND-recursion.  We only need
199 	 * to worry about this at top level, since eval_const_expressions should
200 	 * have gotten rid of any trivial ANDs or ORs below that.
201 	 */
202 	if (list_length(predicate_list) == 1)
203 		p = (Node *) linitial(predicate_list);
204 	else
205 		p = (Node *) predicate_list;
206 	if (list_length(restrictinfo_list) == 1)
207 		r = (Node *) linitial(restrictinfo_list);
208 	else
209 		r = (Node *) restrictinfo_list;
210 
211 	/* And away we go ... */
212 	return predicate_refuted_by_recurse(r, p);
213 }
214 
215 /*----------
216  * predicate_implied_by_recurse
217  *	  Does the predicate implication test for non-NULL restriction and
218  *	  predicate clauses.
219  *
220  * The logic followed here is ("=>" means "implies"):
221  *	atom A => atom B iff:			predicate_implied_by_simple_clause says so
222  *	atom A => AND-expr B iff:		A => each of B's components
223  *	atom A => OR-expr B iff:		A => any of B's components
224  *	AND-expr A => atom B iff:		any of A's components => B
225  *	AND-expr A => AND-expr B iff:	A => each of B's components
226  *	AND-expr A => OR-expr B iff:	A => any of B's components,
227  *									*or* any of A's components => B
228  *	OR-expr A => atom B iff:		each of A's components => B
229  *	OR-expr A => AND-expr B iff:	A => each of B's components
230  *	OR-expr A => OR-expr B iff:		each of A's components => any of B's
231  *
232  * An "atom" is anything other than an AND or OR node.  Notice that we don't
233  * have any special logic to handle NOT nodes; these should have been pushed
234  * down or eliminated where feasible by prepqual.c.
235  *
236  * We can't recursively expand either side first, but have to interleave
237  * the expansions per the above rules, to be sure we handle all of these
238  * examples:
239  *		(x OR y) => (x OR y OR z)
240  *		(x AND y AND z) => (x AND y)
241  *		(x AND y) => ((x AND y) OR z)
242  *		((x OR y) AND z) => (x OR y)
243  * This is still not an exhaustive test, but it handles most normal cases
244  * under the assumption that both inputs have been AND/OR flattened.
245  *
246  * We have to be prepared to handle RestrictInfo nodes in the restrictinfo
247  * tree, though not in the predicate tree.
248  *----------
249  */
250 static bool
predicate_implied_by_recurse(Node * clause,Node * predicate)251 predicate_implied_by_recurse(Node *clause, Node *predicate)
252 {
253 	PredIterInfoData clause_info;
254 	PredIterInfoData pred_info;
255 	PredClass	pclass;
256 	bool		result;
257 
258 	/* skip through RestrictInfo */
259 	Assert(clause != NULL);
260 	if (IsA(clause, RestrictInfo))
261 		clause = (Node *) ((RestrictInfo *) clause)->clause;
262 
263 	pclass = predicate_classify(predicate, &pred_info);
264 
265 	switch (predicate_classify(clause, &clause_info))
266 	{
267 		case CLASS_AND:
268 			switch (pclass)
269 			{
270 				case CLASS_AND:
271 
272 					/*
273 					 * AND-clause => AND-clause if A implies each of B's items
274 					 */
275 					result = true;
276 					iterate_begin(pitem, predicate, pred_info)
277 					{
278 						if (!predicate_implied_by_recurse(clause, pitem))
279 						{
280 							result = false;
281 							break;
282 						}
283 					}
284 					iterate_end(pred_info);
285 					return result;
286 
287 				case CLASS_OR:
288 
289 					/*
290 					 * AND-clause => OR-clause if A implies any of B's items
291 					 *
292 					 * Needed to handle (x AND y) => ((x AND y) OR z)
293 					 */
294 					result = false;
295 					iterate_begin(pitem, predicate, pred_info)
296 					{
297 						if (predicate_implied_by_recurse(clause, pitem))
298 						{
299 							result = true;
300 							break;
301 						}
302 					}
303 					iterate_end(pred_info);
304 					if (result)
305 						return result;
306 
307 					/*
308 					 * Also check if any of A's items implies B
309 					 *
310 					 * Needed to handle ((x OR y) AND z) => (x OR y)
311 					 */
312 					iterate_begin(citem, clause, clause_info)
313 					{
314 						if (predicate_implied_by_recurse(citem, predicate))
315 						{
316 							result = true;
317 							break;
318 						}
319 					}
320 					iterate_end(clause_info);
321 					return result;
322 
323 				case CLASS_ATOM:
324 
325 					/*
326 					 * AND-clause => atom if any of A's items implies B
327 					 */
328 					result = false;
329 					iterate_begin(citem, clause, clause_info)
330 					{
331 						if (predicate_implied_by_recurse(citem, predicate))
332 						{
333 							result = true;
334 							break;
335 						}
336 					}
337 					iterate_end(clause_info);
338 					return result;
339 			}
340 			break;
341 
342 		case CLASS_OR:
343 			switch (pclass)
344 			{
345 				case CLASS_OR:
346 
347 					/*
348 					 * OR-clause => OR-clause if each of A's items implies any
349 					 * of B's items.  Messy but can't do it any more simply.
350 					 */
351 					result = true;
352 					iterate_begin(citem, clause, clause_info)
353 					{
354 						bool		presult = false;
355 
356 						iterate_begin(pitem, predicate, pred_info)
357 						{
358 							if (predicate_implied_by_recurse(citem, pitem))
359 							{
360 								presult = true;
361 								break;
362 							}
363 						}
364 						iterate_end(pred_info);
365 						if (!presult)
366 						{
367 							result = false;		/* doesn't imply any of B's */
368 							break;
369 						}
370 					}
371 					iterate_end(clause_info);
372 					return result;
373 
374 				case CLASS_AND:
375 				case CLASS_ATOM:
376 
377 					/*
378 					 * OR-clause => AND-clause if each of A's items implies B
379 					 *
380 					 * OR-clause => atom if each of A's items implies B
381 					 */
382 					result = true;
383 					iterate_begin(citem, clause, clause_info)
384 					{
385 						if (!predicate_implied_by_recurse(citem, predicate))
386 						{
387 							result = false;
388 							break;
389 						}
390 					}
391 					iterate_end(clause_info);
392 					return result;
393 			}
394 			break;
395 
396 		case CLASS_ATOM:
397 			switch (pclass)
398 			{
399 				case CLASS_AND:
400 
401 					/*
402 					 * atom => AND-clause if A implies each of B's items
403 					 */
404 					result = true;
405 					iterate_begin(pitem, predicate, pred_info)
406 					{
407 						if (!predicate_implied_by_recurse(clause, pitem))
408 						{
409 							result = false;
410 							break;
411 						}
412 					}
413 					iterate_end(pred_info);
414 					return result;
415 
416 				case CLASS_OR:
417 
418 					/*
419 					 * atom => OR-clause if A implies any of B's items
420 					 */
421 					result = false;
422 					iterate_begin(pitem, predicate, pred_info)
423 					{
424 						if (predicate_implied_by_recurse(clause, pitem))
425 						{
426 							result = true;
427 							break;
428 						}
429 					}
430 					iterate_end(pred_info);
431 					return result;
432 
433 				case CLASS_ATOM:
434 
435 					/*
436 					 * atom => atom is the base case
437 					 */
438 					return
439 						predicate_implied_by_simple_clause((Expr *) predicate,
440 														   clause);
441 			}
442 			break;
443 	}
444 
445 	/* can't get here */
446 	elog(ERROR, "predicate_classify returned a bogus value");
447 	return false;
448 }
449 
450 /*----------
451  * predicate_refuted_by_recurse
452  *	  Does the predicate refutation test for non-NULL restriction and
453  *	  predicate clauses.
454  *
455  * The logic followed here is ("R=>" means "refutes"):
456  *	atom A R=> atom B iff:			predicate_refuted_by_simple_clause says so
457  *	atom A R=> AND-expr B iff:		A R=> any of B's components
458  *	atom A R=> OR-expr B iff:		A R=> each of B's components
459  *	AND-expr A R=> atom B iff:		any of A's components R=> B
460  *	AND-expr A R=> AND-expr B iff:	A R=> any of B's components,
461  *									*or* any of A's components R=> B
462  *	AND-expr A R=> OR-expr B iff:	A R=> each of B's components
463  *	OR-expr A R=> atom B iff:		each of A's components R=> B
464  *	OR-expr A R=> AND-expr B iff:	each of A's components R=> any of B's
465  *	OR-expr A R=> OR-expr B iff:	A R=> each of B's components
466  *
467  * In addition, if the predicate is a NOT-clause then we can use
468  *	A R=> NOT B if:					A => B
469  * This works for several different SQL constructs that assert the non-truth
470  * of their argument, ie NOT, IS FALSE, IS NOT TRUE, IS UNKNOWN.
471  * Unfortunately we *cannot* use
472  *	NOT A R=> B if:					B => A
473  * because this type of reasoning fails to prove that B doesn't yield NULL.
474  * We can however make the more limited deduction that
475  *	NOT A R=> A
476  *
477  * Other comments are as for predicate_implied_by_recurse().
478  *----------
479  */
480 static bool
predicate_refuted_by_recurse(Node * clause,Node * predicate)481 predicate_refuted_by_recurse(Node *clause, Node *predicate)
482 {
483 	PredIterInfoData clause_info;
484 	PredIterInfoData pred_info;
485 	PredClass	pclass;
486 	Node	   *not_arg;
487 	bool		result;
488 
489 	/* skip through RestrictInfo */
490 	Assert(clause != NULL);
491 	if (IsA(clause, RestrictInfo))
492 		clause = (Node *) ((RestrictInfo *) clause)->clause;
493 
494 	pclass = predicate_classify(predicate, &pred_info);
495 
496 	switch (predicate_classify(clause, &clause_info))
497 	{
498 		case CLASS_AND:
499 			switch (pclass)
500 			{
501 				case CLASS_AND:
502 
503 					/*
504 					 * AND-clause R=> AND-clause if A refutes any of B's items
505 					 *
506 					 * Needed to handle (x AND y) R=> ((!x OR !y) AND z)
507 					 */
508 					result = false;
509 					iterate_begin(pitem, predicate, pred_info)
510 					{
511 						if (predicate_refuted_by_recurse(clause, pitem))
512 						{
513 							result = true;
514 							break;
515 						}
516 					}
517 					iterate_end(pred_info);
518 					if (result)
519 						return result;
520 
521 					/*
522 					 * Also check if any of A's items refutes B
523 					 *
524 					 * Needed to handle ((x OR y) AND z) R=> (!x AND !y)
525 					 */
526 					iterate_begin(citem, clause, clause_info)
527 					{
528 						if (predicate_refuted_by_recurse(citem, predicate))
529 						{
530 							result = true;
531 							break;
532 						}
533 					}
534 					iterate_end(clause_info);
535 					return result;
536 
537 				case CLASS_OR:
538 
539 					/*
540 					 * AND-clause R=> OR-clause if A refutes each of B's items
541 					 */
542 					result = true;
543 					iterate_begin(pitem, predicate, pred_info)
544 					{
545 						if (!predicate_refuted_by_recurse(clause, pitem))
546 						{
547 							result = false;
548 							break;
549 						}
550 					}
551 					iterate_end(pred_info);
552 					return result;
553 
554 				case CLASS_ATOM:
555 
556 					/*
557 					 * If B is a NOT-clause, A R=> B if A => B's arg
558 					 */
559 					not_arg = extract_not_arg(predicate);
560 					if (not_arg &&
561 						predicate_implied_by_recurse(clause, not_arg))
562 						return true;
563 
564 					/*
565 					 * AND-clause R=> atom if any of A's items refutes B
566 					 */
567 					result = false;
568 					iterate_begin(citem, clause, clause_info)
569 					{
570 						if (predicate_refuted_by_recurse(citem, predicate))
571 						{
572 							result = true;
573 							break;
574 						}
575 					}
576 					iterate_end(clause_info);
577 					return result;
578 			}
579 			break;
580 
581 		case CLASS_OR:
582 			switch (pclass)
583 			{
584 				case CLASS_OR:
585 
586 					/*
587 					 * OR-clause R=> OR-clause if A refutes each of B's items
588 					 */
589 					result = true;
590 					iterate_begin(pitem, predicate, pred_info)
591 					{
592 						if (!predicate_refuted_by_recurse(clause, pitem))
593 						{
594 							result = false;
595 							break;
596 						}
597 					}
598 					iterate_end(pred_info);
599 					return result;
600 
601 				case CLASS_AND:
602 
603 					/*
604 					 * OR-clause R=> AND-clause if each of A's items refutes
605 					 * any of B's items.
606 					 */
607 					result = true;
608 					iterate_begin(citem, clause, clause_info)
609 					{
610 						bool		presult = false;
611 
612 						iterate_begin(pitem, predicate, pred_info)
613 						{
614 							if (predicate_refuted_by_recurse(citem, pitem))
615 							{
616 								presult = true;
617 								break;
618 							}
619 						}
620 						iterate_end(pred_info);
621 						if (!presult)
622 						{
623 							result = false;		/* citem refutes nothing */
624 							break;
625 						}
626 					}
627 					iterate_end(clause_info);
628 					return result;
629 
630 				case CLASS_ATOM:
631 
632 					/*
633 					 * If B is a NOT-clause, A R=> B if A => B's arg
634 					 */
635 					not_arg = extract_not_arg(predicate);
636 					if (not_arg &&
637 						predicate_implied_by_recurse(clause, not_arg))
638 						return true;
639 
640 					/*
641 					 * OR-clause R=> atom if each of A's items refutes B
642 					 */
643 					result = true;
644 					iterate_begin(citem, clause, clause_info)
645 					{
646 						if (!predicate_refuted_by_recurse(citem, predicate))
647 						{
648 							result = false;
649 							break;
650 						}
651 					}
652 					iterate_end(clause_info);
653 					return result;
654 			}
655 			break;
656 
657 		case CLASS_ATOM:
658 
659 			/*
660 			 * If A is a strong NOT-clause, A R=> B if B equals A's arg
661 			 *
662 			 * We cannot make the stronger conclusion that B is refuted if B
663 			 * implies A's arg; that would only prove that B is not-TRUE, not
664 			 * that it's not NULL either.  Hence use equal() rather than
665 			 * predicate_implied_by_recurse().  We could do the latter if we
666 			 * ever had a need for the weak form of refutation.
667 			 */
668 			not_arg = extract_strong_not_arg(clause);
669 			if (not_arg && equal(predicate, not_arg))
670 				return true;
671 
672 			switch (pclass)
673 			{
674 				case CLASS_AND:
675 
676 					/*
677 					 * atom R=> AND-clause if A refutes any of B's items
678 					 */
679 					result = false;
680 					iterate_begin(pitem, predicate, pred_info)
681 					{
682 						if (predicate_refuted_by_recurse(clause, pitem))
683 						{
684 							result = true;
685 							break;
686 						}
687 					}
688 					iterate_end(pred_info);
689 					return result;
690 
691 				case CLASS_OR:
692 
693 					/*
694 					 * atom R=> OR-clause if A refutes each of B's items
695 					 */
696 					result = true;
697 					iterate_begin(pitem, predicate, pred_info)
698 					{
699 						if (!predicate_refuted_by_recurse(clause, pitem))
700 						{
701 							result = false;
702 							break;
703 						}
704 					}
705 					iterate_end(pred_info);
706 					return result;
707 
708 				case CLASS_ATOM:
709 
710 					/*
711 					 * If B is a NOT-clause, A R=> B if A => B's arg
712 					 */
713 					not_arg = extract_not_arg(predicate);
714 					if (not_arg &&
715 						predicate_implied_by_recurse(clause, not_arg))
716 						return true;
717 
718 					/*
719 					 * atom R=> atom is the base case
720 					 */
721 					return
722 						predicate_refuted_by_simple_clause((Expr *) predicate,
723 														   clause);
724 			}
725 			break;
726 	}
727 
728 	/* can't get here */
729 	elog(ERROR, "predicate_classify returned a bogus value");
730 	return false;
731 }
732 
733 
734 /*
735  * predicate_classify
736  *	  Classify an expression node as AND-type, OR-type, or neither (an atom).
737  *
738  * If the expression is classified as AND- or OR-type, then *info is filled
739  * in with the functions needed to iterate over its components.
740  *
741  * This function also implements enforcement of MAX_SAOP_ARRAY_SIZE: if a
742  * ScalarArrayOpExpr's array has too many elements, we just classify it as an
743  * atom.  (This will result in its being passed as-is to the simple_clause
744  * functions, which will fail to prove anything about it.)	Note that we
745  * cannot just stop after considering MAX_SAOP_ARRAY_SIZE elements; in general
746  * that would result in wrong proofs, rather than failing to prove anything.
747  */
748 static PredClass
predicate_classify(Node * clause,PredIterInfo info)749 predicate_classify(Node *clause, PredIterInfo info)
750 {
751 	/* Caller should not pass us NULL, nor a RestrictInfo clause */
752 	Assert(clause != NULL);
753 	Assert(!IsA(clause, RestrictInfo));
754 
755 	/*
756 	 * If we see a List, assume it's an implicit-AND list; this is the correct
757 	 * semantics for lists of RestrictInfo nodes.
758 	 */
759 	if (IsA(clause, List))
760 	{
761 		info->startup_fn = list_startup_fn;
762 		info->next_fn = list_next_fn;
763 		info->cleanup_fn = list_cleanup_fn;
764 		return CLASS_AND;
765 	}
766 
767 	/* Handle normal AND and OR boolean clauses */
768 	if (and_clause(clause))
769 	{
770 		info->startup_fn = boolexpr_startup_fn;
771 		info->next_fn = list_next_fn;
772 		info->cleanup_fn = list_cleanup_fn;
773 		return CLASS_AND;
774 	}
775 	if (or_clause(clause))
776 	{
777 		info->startup_fn = boolexpr_startup_fn;
778 		info->next_fn = list_next_fn;
779 		info->cleanup_fn = list_cleanup_fn;
780 		return CLASS_OR;
781 	}
782 
783 	/* Handle ScalarArrayOpExpr */
784 	if (IsA(clause, ScalarArrayOpExpr))
785 	{
786 		ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
787 		Node	   *arraynode = (Node *) lsecond(saop->args);
788 
789 		/*
790 		 * We can break this down into an AND or OR structure, but only if we
791 		 * know how to iterate through expressions for the array's elements.
792 		 * We can do that if the array operand is a non-null constant or a
793 		 * simple ArrayExpr.
794 		 */
795 		if (arraynode && IsA(arraynode, Const) &&
796 			!((Const *) arraynode)->constisnull)
797 		{
798 			ArrayType  *arrayval;
799 			int			nelems;
800 
801 			arrayval = DatumGetArrayTypeP(((Const *) arraynode)->constvalue);
802 			nelems = ArrayGetNItems(ARR_NDIM(arrayval), ARR_DIMS(arrayval));
803 			if (nelems <= MAX_SAOP_ARRAY_SIZE)
804 			{
805 				info->startup_fn = arrayconst_startup_fn;
806 				info->next_fn = arrayconst_next_fn;
807 				info->cleanup_fn = arrayconst_cleanup_fn;
808 				return saop->useOr ? CLASS_OR : CLASS_AND;
809 			}
810 		}
811 		else if (arraynode && IsA(arraynode, ArrayExpr) &&
812 				 !((ArrayExpr *) arraynode)->multidims &&
813 				 list_length(((ArrayExpr *) arraynode)->elements) <= MAX_SAOP_ARRAY_SIZE)
814 		{
815 			info->startup_fn = arrayexpr_startup_fn;
816 			info->next_fn = arrayexpr_next_fn;
817 			info->cleanup_fn = arrayexpr_cleanup_fn;
818 			return saop->useOr ? CLASS_OR : CLASS_AND;
819 		}
820 	}
821 
822 	/* None of the above, so it's an atom */
823 	return CLASS_ATOM;
824 }
825 
826 /*
827  * PredIterInfo routines for iterating over regular Lists.  The iteration
828  * state variable is the next ListCell to visit.
829  */
830 static void
list_startup_fn(Node * clause,PredIterInfo info)831 list_startup_fn(Node *clause, PredIterInfo info)
832 {
833 	info->state = (void *) list_head((List *) clause);
834 }
835 
836 static Node *
list_next_fn(PredIterInfo info)837 list_next_fn(PredIterInfo info)
838 {
839 	ListCell   *l = (ListCell *) info->state;
840 	Node	   *n;
841 
842 	if (l == NULL)
843 		return NULL;
844 	n = lfirst(l);
845 	info->state = (void *) lnext(l);
846 	return n;
847 }
848 
849 static void
list_cleanup_fn(PredIterInfo info)850 list_cleanup_fn(PredIterInfo info)
851 {
852 	/* Nothing to clean up */
853 }
854 
855 /*
856  * BoolExpr needs its own startup function, but can use list_next_fn and
857  * list_cleanup_fn.
858  */
859 static void
boolexpr_startup_fn(Node * clause,PredIterInfo info)860 boolexpr_startup_fn(Node *clause, PredIterInfo info)
861 {
862 	info->state = (void *) list_head(((BoolExpr *) clause)->args);
863 }
864 
865 /*
866  * PredIterInfo routines for iterating over a ScalarArrayOpExpr with a
867  * constant array operand.
868  */
869 typedef struct
870 {
871 	OpExpr		opexpr;
872 	Const		constexpr;
873 	int			next_elem;
874 	int			num_elems;
875 	Datum	   *elem_values;
876 	bool	   *elem_nulls;
877 } ArrayConstIterState;
878 
879 static void
arrayconst_startup_fn(Node * clause,PredIterInfo info)880 arrayconst_startup_fn(Node *clause, PredIterInfo info)
881 {
882 	ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
883 	ArrayConstIterState *state;
884 	Const	   *arrayconst;
885 	ArrayType  *arrayval;
886 	int16		elmlen;
887 	bool		elmbyval;
888 	char		elmalign;
889 
890 	/* Create working state struct */
891 	state = (ArrayConstIterState *) palloc(sizeof(ArrayConstIterState));
892 	info->state = (void *) state;
893 
894 	/* Deconstruct the array literal */
895 	arrayconst = (Const *) lsecond(saop->args);
896 	arrayval = DatumGetArrayTypeP(arrayconst->constvalue);
897 	get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
898 						 &elmlen, &elmbyval, &elmalign);
899 	deconstruct_array(arrayval,
900 					  ARR_ELEMTYPE(arrayval),
901 					  elmlen, elmbyval, elmalign,
902 					  &state->elem_values, &state->elem_nulls,
903 					  &state->num_elems);
904 
905 	/* Set up a dummy OpExpr to return as the per-item node */
906 	state->opexpr.xpr.type = T_OpExpr;
907 	state->opexpr.opno = saop->opno;
908 	state->opexpr.opfuncid = saop->opfuncid;
909 	state->opexpr.opresulttype = BOOLOID;
910 	state->opexpr.opretset = false;
911 	state->opexpr.opcollid = InvalidOid;
912 	state->opexpr.inputcollid = saop->inputcollid;
913 	state->opexpr.args = list_copy(saop->args);
914 
915 	/* Set up a dummy Const node to hold the per-element values */
916 	state->constexpr.xpr.type = T_Const;
917 	state->constexpr.consttype = ARR_ELEMTYPE(arrayval);
918 	state->constexpr.consttypmod = -1;
919 	state->constexpr.constcollid = arrayconst->constcollid;
920 	state->constexpr.constlen = elmlen;
921 	state->constexpr.constbyval = elmbyval;
922 	lsecond(state->opexpr.args) = &state->constexpr;
923 
924 	/* Initialize iteration state */
925 	state->next_elem = 0;
926 }
927 
928 static Node *
arrayconst_next_fn(PredIterInfo info)929 arrayconst_next_fn(PredIterInfo info)
930 {
931 	ArrayConstIterState *state = (ArrayConstIterState *) info->state;
932 
933 	if (state->next_elem >= state->num_elems)
934 		return NULL;
935 	state->constexpr.constvalue = state->elem_values[state->next_elem];
936 	state->constexpr.constisnull = state->elem_nulls[state->next_elem];
937 	state->next_elem++;
938 	return (Node *) &(state->opexpr);
939 }
940 
941 static void
arrayconst_cleanup_fn(PredIterInfo info)942 arrayconst_cleanup_fn(PredIterInfo info)
943 {
944 	ArrayConstIterState *state = (ArrayConstIterState *) info->state;
945 
946 	pfree(state->elem_values);
947 	pfree(state->elem_nulls);
948 	list_free(state->opexpr.args);
949 	pfree(state);
950 }
951 
952 /*
953  * PredIterInfo routines for iterating over a ScalarArrayOpExpr with a
954  * one-dimensional ArrayExpr array operand.
955  */
956 typedef struct
957 {
958 	OpExpr		opexpr;
959 	ListCell   *next;
960 } ArrayExprIterState;
961 
962 static void
arrayexpr_startup_fn(Node * clause,PredIterInfo info)963 arrayexpr_startup_fn(Node *clause, PredIterInfo info)
964 {
965 	ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
966 	ArrayExprIterState *state;
967 	ArrayExpr  *arrayexpr;
968 
969 	/* Create working state struct */
970 	state = (ArrayExprIterState *) palloc(sizeof(ArrayExprIterState));
971 	info->state = (void *) state;
972 
973 	/* Set up a dummy OpExpr to return as the per-item node */
974 	state->opexpr.xpr.type = T_OpExpr;
975 	state->opexpr.opno = saop->opno;
976 	state->opexpr.opfuncid = saop->opfuncid;
977 	state->opexpr.opresulttype = BOOLOID;
978 	state->opexpr.opretset = false;
979 	state->opexpr.opcollid = InvalidOid;
980 	state->opexpr.inputcollid = saop->inputcollid;
981 	state->opexpr.args = list_copy(saop->args);
982 
983 	/* Initialize iteration variable to first member of ArrayExpr */
984 	arrayexpr = (ArrayExpr *) lsecond(saop->args);
985 	state->next = list_head(arrayexpr->elements);
986 }
987 
988 static Node *
arrayexpr_next_fn(PredIterInfo info)989 arrayexpr_next_fn(PredIterInfo info)
990 {
991 	ArrayExprIterState *state = (ArrayExprIterState *) info->state;
992 
993 	if (state->next == NULL)
994 		return NULL;
995 	lsecond(state->opexpr.args) = lfirst(state->next);
996 	state->next = lnext(state->next);
997 	return (Node *) &(state->opexpr);
998 }
999 
1000 static void
arrayexpr_cleanup_fn(PredIterInfo info)1001 arrayexpr_cleanup_fn(PredIterInfo info)
1002 {
1003 	ArrayExprIterState *state = (ArrayExprIterState *) info->state;
1004 
1005 	list_free(state->opexpr.args);
1006 	pfree(state);
1007 }
1008 
1009 
1010 /*----------
1011  * predicate_implied_by_simple_clause
1012  *	  Does the predicate implication test for a "simple clause" predicate
1013  *	  and a "simple clause" restriction.
1014  *
1015  * We return TRUE if able to prove the implication, FALSE if not.
1016  *
1017  * We have three strategies for determining whether one simple clause
1018  * implies another:
1019  *
1020  * A simple and general way is to see if they are equal(); this works for any
1021  * kind of expression.  (Actually, there is an implied assumption that the
1022  * functions in the expression are immutable, ie dependent only on their input
1023  * arguments --- but this was checked for the predicate by the caller.)
1024  *
1025  * When the predicate is of the form "foo IS NOT NULL", we can conclude that
1026  * the predicate is implied if the clause is a strict operator or function
1027  * that has "foo" as an input.  In this case the clause must yield NULL when
1028  * "foo" is NULL, which we can take as equivalent to FALSE because we know
1029  * we are within an AND/OR subtree of a WHERE clause.  (Again, "foo" is
1030  * already known immutable, so the clause will certainly always fail.)
1031  * Also, if the clause is just "foo" (meaning it's a boolean variable),
1032  * the predicate is implied since the clause can't be true if "foo" is NULL.
1033  *
1034  * Finally, if both clauses are binary operator expressions, we may be able
1035  * to prove something using the system's knowledge about operators; those
1036  * proof rules are encapsulated in operator_predicate_proof().
1037  *----------
1038  */
1039 static bool
predicate_implied_by_simple_clause(Expr * predicate,Node * clause)1040 predicate_implied_by_simple_clause(Expr *predicate, Node *clause)
1041 {
1042 	/* Allow interrupting long proof attempts */
1043 	CHECK_FOR_INTERRUPTS();
1044 
1045 	/* First try the equal() test */
1046 	if (equal((Node *) predicate, clause))
1047 		return true;
1048 
1049 	/* Next try the IS NOT NULL case */
1050 	if (predicate && IsA(predicate, NullTest) &&
1051 		((NullTest *) predicate)->nulltesttype == IS_NOT_NULL)
1052 	{
1053 		Expr	   *nonnullarg = ((NullTest *) predicate)->arg;
1054 
1055 		/* row IS NOT NULL does not act in the simple way we have in mind */
1056 		if (!((NullTest *) predicate)->argisrow)
1057 		{
1058 			if (is_opclause(clause) &&
1059 				list_member_strip(((OpExpr *) clause)->args, nonnullarg) &&
1060 				op_strict(((OpExpr *) clause)->opno))
1061 				return true;
1062 			if (is_funcclause(clause) &&
1063 				list_member_strip(((FuncExpr *) clause)->args, nonnullarg) &&
1064 				func_strict(((FuncExpr *) clause)->funcid))
1065 				return true;
1066 			if (equal(clause, nonnullarg))
1067 				return true;
1068 		}
1069 		return false;			/* we can't succeed below... */
1070 	}
1071 
1072 	/* Else try operator-related knowledge */
1073 	return operator_predicate_proof(predicate, clause, false);
1074 }
1075 
1076 /*----------
1077  * predicate_refuted_by_simple_clause
1078  *	  Does the predicate refutation test for a "simple clause" predicate
1079  *	  and a "simple clause" restriction.
1080  *
1081  * We return TRUE if able to prove the refutation, FALSE if not.
1082  *
1083  * Unlike the implication case, checking for equal() clauses isn't
1084  * helpful.
1085  *
1086  * When the predicate is of the form "foo IS NULL", we can conclude that
1087  * the predicate is refuted if the clause is a strict operator or function
1088  * that has "foo" as an input (see notes for implication case), or if the
1089  * clause is "foo IS NOT NULL".  A clause "foo IS NULL" refutes a predicate
1090  * "foo IS NOT NULL", but unfortunately does not refute strict predicates,
1091  * because we are looking for strong refutation.  (The motivation for covering
1092  * these cases is to support using IS NULL/IS NOT NULL as partition-defining
1093  * constraints.)
1094  *
1095  * Finally, if both clauses are binary operator expressions, we may be able
1096  * to prove something using the system's knowledge about operators; those
1097  * proof rules are encapsulated in operator_predicate_proof().
1098  *----------
1099  */
1100 static bool
predicate_refuted_by_simple_clause(Expr * predicate,Node * clause)1101 predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
1102 {
1103 	/* Allow interrupting long proof attempts */
1104 	CHECK_FOR_INTERRUPTS();
1105 
1106 	/* A simple clause can't refute itself */
1107 	/* Worth checking because of relation_excluded_by_constraints() */
1108 	if ((Node *) predicate == clause)
1109 		return false;
1110 
1111 	/* Try the predicate-IS-NULL case */
1112 	if (predicate && IsA(predicate, NullTest) &&
1113 		((NullTest *) predicate)->nulltesttype == IS_NULL)
1114 	{
1115 		Expr	   *isnullarg = ((NullTest *) predicate)->arg;
1116 
1117 		/* row IS NULL does not act in the simple way we have in mind */
1118 		if (((NullTest *) predicate)->argisrow)
1119 			return false;
1120 
1121 		/* Any strict op/func on foo refutes foo IS NULL */
1122 		if (is_opclause(clause) &&
1123 			list_member_strip(((OpExpr *) clause)->args, isnullarg) &&
1124 			op_strict(((OpExpr *) clause)->opno))
1125 			return true;
1126 		if (is_funcclause(clause) &&
1127 			list_member_strip(((FuncExpr *) clause)->args, isnullarg) &&
1128 			func_strict(((FuncExpr *) clause)->funcid))
1129 			return true;
1130 
1131 		/* foo IS NOT NULL refutes foo IS NULL */
1132 		if (clause && IsA(clause, NullTest) &&
1133 			((NullTest *) clause)->nulltesttype == IS_NOT_NULL &&
1134 			!((NullTest *) clause)->argisrow &&
1135 			equal(((NullTest *) clause)->arg, isnullarg))
1136 			return true;
1137 
1138 		return false;			/* we can't succeed below... */
1139 	}
1140 
1141 	/* Try the clause-IS-NULL case */
1142 	if (clause && IsA(clause, NullTest) &&
1143 		((NullTest *) clause)->nulltesttype == IS_NULL)
1144 	{
1145 		Expr	   *isnullarg = ((NullTest *) clause)->arg;
1146 
1147 		/* row IS NULL does not act in the simple way we have in mind */
1148 		if (((NullTest *) clause)->argisrow)
1149 			return false;
1150 
1151 		/* foo IS NULL refutes foo IS NOT NULL */
1152 		if (predicate && IsA(predicate, NullTest) &&
1153 			((NullTest *) predicate)->nulltesttype == IS_NOT_NULL &&
1154 			!((NullTest *) predicate)->argisrow &&
1155 			equal(((NullTest *) predicate)->arg, isnullarg))
1156 			return true;
1157 
1158 		return false;			/* we can't succeed below... */
1159 	}
1160 
1161 	/* Else try operator-related knowledge */
1162 	return operator_predicate_proof(predicate, clause, true);
1163 }
1164 
1165 
1166 /*
1167  * If clause asserts the non-truth of a subclause, return that subclause;
1168  * otherwise return NULL.
1169  */
1170 static Node *
extract_not_arg(Node * clause)1171 extract_not_arg(Node *clause)
1172 {
1173 	if (clause == NULL)
1174 		return NULL;
1175 	if (IsA(clause, BoolExpr))
1176 	{
1177 		BoolExpr   *bexpr = (BoolExpr *) clause;
1178 
1179 		if (bexpr->boolop == NOT_EXPR)
1180 			return (Node *) linitial(bexpr->args);
1181 	}
1182 	else if (IsA(clause, BooleanTest))
1183 	{
1184 		BooleanTest *btest = (BooleanTest *) clause;
1185 
1186 		if (btest->booltesttype == IS_NOT_TRUE ||
1187 			btest->booltesttype == IS_FALSE ||
1188 			btest->booltesttype == IS_UNKNOWN)
1189 			return (Node *) btest->arg;
1190 	}
1191 	return NULL;
1192 }
1193 
1194 /*
1195  * If clause asserts the falsity of a subclause, return that subclause;
1196  * otherwise return NULL.
1197  */
1198 static Node *
extract_strong_not_arg(Node * clause)1199 extract_strong_not_arg(Node *clause)
1200 {
1201 	if (clause == NULL)
1202 		return NULL;
1203 	if (IsA(clause, BoolExpr))
1204 	{
1205 		BoolExpr   *bexpr = (BoolExpr *) clause;
1206 
1207 		if (bexpr->boolop == NOT_EXPR)
1208 			return (Node *) linitial(bexpr->args);
1209 	}
1210 	else if (IsA(clause, BooleanTest))
1211 	{
1212 		BooleanTest *btest = (BooleanTest *) clause;
1213 
1214 		if (btest->booltesttype == IS_FALSE)
1215 			return (Node *) btest->arg;
1216 	}
1217 	return NULL;
1218 }
1219 
1220 
1221 /*
1222  * Check whether an Expr is equal() to any member of a list, ignoring
1223  * any top-level RelabelType nodes.  This is legitimate for the purposes
1224  * we use it for (matching IS [NOT] NULL arguments to arguments of strict
1225  * functions) because RelabelType doesn't change null-ness.  It's helpful
1226  * for cases such as a varchar argument of a strict function on text.
1227  */
1228 static bool
list_member_strip(List * list,Expr * datum)1229 list_member_strip(List *list, Expr *datum)
1230 {
1231 	ListCell   *cell;
1232 
1233 	if (datum && IsA(datum, RelabelType))
1234 		datum = ((RelabelType *) datum)->arg;
1235 
1236 	foreach(cell, list)
1237 	{
1238 		Expr	   *elem = (Expr *) lfirst(cell);
1239 
1240 		if (elem && IsA(elem, RelabelType))
1241 			elem = ((RelabelType *) elem)->arg;
1242 
1243 		if (equal(elem, datum))
1244 			return true;
1245 	}
1246 
1247 	return false;
1248 }
1249 
1250 
1251 /*
1252  * Define "operator implication tables" for btree operators ("strategies"),
1253  * and similar tables for refutation.
1254  *
1255  * The strategy numbers defined by btree indexes (see access/stratnum.h) are:
1256  *		1 <		2 <=	3 =		4 >=	5 >
1257  * and in addition we use 6 to represent <>.  <> is not a btree-indexable
1258  * operator, but we assume here that if an equality operator of a btree
1259  * opfamily has a negator operator, the negator behaves as <> for the opfamily.
1260  * (This convention is also known to get_op_btree_interpretation().)
1261  *
1262  * BT_implies_table[] and BT_refutes_table[] are used for cases where we have
1263  * two identical subexpressions and we want to know whether one operator
1264  * expression implies or refutes the other.  That is, if the "clause" is
1265  * EXPR1 clause_op EXPR2 and the "predicate" is EXPR1 pred_op EXPR2 for the
1266  * same two (immutable) subexpressions:
1267  *		BT_implies_table[clause_op-1][pred_op-1]
1268  *			is true if the clause implies the predicate
1269  *		BT_refutes_table[clause_op-1][pred_op-1]
1270  *			is true if the clause refutes the predicate
1271  * where clause_op and pred_op are strategy numbers (from 1 to 6) in the
1272  * same btree opfamily.  For example, "x < y" implies "x <= y" and refutes
1273  * "x > y".
1274  *
1275  * BT_implic_table[] and BT_refute_table[] are used where we have two
1276  * constants that we need to compare.  The interpretation of:
1277  *
1278  *		test_op = BT_implic_table[clause_op-1][pred_op-1]
1279  *
1280  * where test_op, clause_op and pred_op are strategy numbers (from 1 to 6)
1281  * of btree operators, is as follows:
1282  *
1283  *	 If you know, for some EXPR, that "EXPR clause_op CONST1" is true, and you
1284  *	 want to determine whether "EXPR pred_op CONST2" must also be true, then
1285  *	 you can use "CONST2 test_op CONST1" as a test.  If this test returns true,
1286  *	 then the predicate expression must be true; if the test returns false,
1287  *	 then the predicate expression may be false.
1288  *
1289  * For example, if clause is "Quantity > 10" and pred is "Quantity > 5"
1290  * then we test "5 <= 10" which evals to true, so clause implies pred.
1291  *
1292  * Similarly, the interpretation of a BT_refute_table entry is:
1293  *
1294  *	 If you know, for some EXPR, that "EXPR clause_op CONST1" is true, and you
1295  *	 want to determine whether "EXPR pred_op CONST2" must be false, then
1296  *	 you can use "CONST2 test_op CONST1" as a test.  If this test returns true,
1297  *	 then the predicate expression must be false; if the test returns false,
1298  *	 then the predicate expression may be true.
1299  *
1300  * For example, if clause is "Quantity > 10" and pred is "Quantity < 5"
1301  * then we test "5 <= 10" which evals to true, so clause refutes pred.
1302  *
1303  * An entry where test_op == 0 means the implication cannot be determined.
1304  */
1305 
1306 #define BTLT BTLessStrategyNumber
1307 #define BTLE BTLessEqualStrategyNumber
1308 #define BTEQ BTEqualStrategyNumber
1309 #define BTGE BTGreaterEqualStrategyNumber
1310 #define BTGT BTGreaterStrategyNumber
1311 #define BTNE ROWCOMPARE_NE
1312 
1313 /* We use "none" for 0/false to make the tables align nicely */
1314 #define none 0
1315 
1316 static const bool BT_implies_table[6][6] = {
1317 /*
1318  *			The predicate operator:
1319  *	 LT    LE	 EQ    GE	 GT    NE
1320  */
1321 	{TRUE, TRUE, none, none, none, TRUE},		/* LT */
1322 	{none, TRUE, none, none, none, none},		/* LE */
1323 	{none, TRUE, TRUE, TRUE, none, none},		/* EQ */
1324 	{none, none, none, TRUE, none, none},		/* GE */
1325 	{none, none, none, TRUE, TRUE, TRUE},		/* GT */
1326 	{none, none, none, none, none, TRUE}		/* NE */
1327 };
1328 
1329 static const bool BT_refutes_table[6][6] = {
1330 /*
1331  *			The predicate operator:
1332  *	 LT    LE	 EQ    GE	 GT    NE
1333  */
1334 	{none, none, TRUE, TRUE, TRUE, none},		/* LT */
1335 	{none, none, none, none, TRUE, none},		/* LE */
1336 	{TRUE, none, none, none, TRUE, TRUE},		/* EQ */
1337 	{TRUE, none, none, none, none, none},		/* GE */
1338 	{TRUE, TRUE, TRUE, none, none, none},		/* GT */
1339 	{none, none, TRUE, none, none, none}		/* NE */
1340 };
1341 
1342 static const StrategyNumber BT_implic_table[6][6] = {
1343 /*
1344  *			The predicate operator:
1345  *	 LT    LE	 EQ    GE	 GT    NE
1346  */
1347 	{BTGE, BTGE, none, none, none, BTGE},		/* LT */
1348 	{BTGT, BTGE, none, none, none, BTGT},		/* LE */
1349 	{BTGT, BTGE, BTEQ, BTLE, BTLT, BTNE},		/* EQ */
1350 	{none, none, none, BTLE, BTLT, BTLT},		/* GE */
1351 	{none, none, none, BTLE, BTLE, BTLE},		/* GT */
1352 	{none, none, none, none, none, BTEQ}		/* NE */
1353 };
1354 
1355 static const StrategyNumber BT_refute_table[6][6] = {
1356 /*
1357  *			The predicate operator:
1358  *	 LT    LE	 EQ    GE	 GT    NE
1359  */
1360 	{none, none, BTGE, BTGE, BTGE, none},		/* LT */
1361 	{none, none, BTGT, BTGT, BTGE, none},		/* LE */
1362 	{BTLE, BTLT, BTNE, BTGT, BTGE, BTEQ},		/* EQ */
1363 	{BTLE, BTLT, BTLT, none, none, none},		/* GE */
1364 	{BTLE, BTLE, BTLE, none, none, none},		/* GT */
1365 	{none, none, BTEQ, none, none, none}		/* NE */
1366 };
1367 
1368 
1369 /*
1370  * operator_predicate_proof
1371  *	  Does the predicate implication or refutation test for a "simple clause"
1372  *	  predicate and a "simple clause" restriction, when both are operator
1373  *	  clauses using related operators and identical input expressions.
1374  *
1375  * When refute_it == false, we want to prove the predicate true;
1376  * when refute_it == true, we want to prove the predicate false.
1377  * (There is enough common code to justify handling these two cases
1378  * in one routine.)  We return TRUE if able to make the proof, FALSE
1379  * if not able to prove it.
1380  *
1381  * We can make proofs involving several expression forms (here "foo" and "bar"
1382  * represent subexpressions that are identical according to equal()):
1383  *	"foo op1 bar" refutes "foo op2 bar" if op1 is op2's negator
1384  *	"foo op1 bar" implies "bar op2 foo" if op1 is op2's commutator
1385  *	"foo op1 bar" refutes "bar op2 foo" if op1 is negator of op2's commutator
1386  *	"foo op1 bar" can imply/refute "foo op2 bar" based on btree semantics
1387  *	"foo op1 bar" can imply/refute "bar op2 foo" based on btree semantics
1388  *	"foo op1 const1" can imply/refute "foo op2 const2" based on btree semantics
1389  *
1390  * For the last three cases, op1 and op2 have to be members of the same btree
1391  * operator family.  When both subexpressions are identical, the idea is that,
1392  * for instance, x < y implies x <= y, independently of exactly what x and y
1393  * are.  If we have two different constants compared to the same expression
1394  * foo, we have to execute a comparison between the two constant values
1395  * in order to determine the result; for instance, foo < c1 implies foo < c2
1396  * if c1 <= c2.  We assume it's safe to compare the constants at plan time
1397  * if the comparison operator is immutable.
1398  *
1399  * Note: all the operators and subexpressions have to be immutable for the
1400  * proof to be safe.  We assume the predicate expression is entirely immutable,
1401  * so no explicit check on the subexpressions is needed here, but in some
1402  * cases we need an extra check of operator immutability.  In particular,
1403  * btree opfamilies can contain cross-type operators that are merely stable,
1404  * and we dare not make deductions with those.
1405  */
1406 static bool
operator_predicate_proof(Expr * predicate,Node * clause,bool refute_it)1407 operator_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
1408 {
1409 	OpExpr	   *pred_opexpr,
1410 			   *clause_opexpr;
1411 	Oid			pred_collation,
1412 				clause_collation;
1413 	Oid			pred_op,
1414 				clause_op,
1415 				test_op;
1416 	Node	   *pred_leftop,
1417 			   *pred_rightop,
1418 			   *clause_leftop,
1419 			   *clause_rightop;
1420 	Const	   *pred_const,
1421 			   *clause_const;
1422 	Expr	   *test_expr;
1423 	ExprState  *test_exprstate;
1424 	Datum		test_result;
1425 	bool		isNull;
1426 	EState	   *estate;
1427 	MemoryContext oldcontext;
1428 
1429 	/*
1430 	 * Both expressions must be binary opclauses, else we can't do anything.
1431 	 *
1432 	 * Note: in future we might extend this logic to other operator-based
1433 	 * constructs such as DistinctExpr.  But the planner isn't very smart
1434 	 * about DistinctExpr in general, and this probably isn't the first place
1435 	 * to fix if you want to improve that.
1436 	 */
1437 	if (!is_opclause(predicate))
1438 		return false;
1439 	pred_opexpr = (OpExpr *) predicate;
1440 	if (list_length(pred_opexpr->args) != 2)
1441 		return false;
1442 	if (!is_opclause(clause))
1443 		return false;
1444 	clause_opexpr = (OpExpr *) clause;
1445 	if (list_length(clause_opexpr->args) != 2)
1446 		return false;
1447 
1448 	/*
1449 	 * If they're marked with different collations then we can't do anything.
1450 	 * This is a cheap test so let's get it out of the way early.
1451 	 */
1452 	pred_collation = pred_opexpr->inputcollid;
1453 	clause_collation = clause_opexpr->inputcollid;
1454 	if (pred_collation != clause_collation)
1455 		return false;
1456 
1457 	/* Grab the operator OIDs now too.  We may commute these below. */
1458 	pred_op = pred_opexpr->opno;
1459 	clause_op = clause_opexpr->opno;
1460 
1461 	/*
1462 	 * We have to match up at least one pair of input expressions.
1463 	 */
1464 	pred_leftop = (Node *) linitial(pred_opexpr->args);
1465 	pred_rightop = (Node *) lsecond(pred_opexpr->args);
1466 	clause_leftop = (Node *) linitial(clause_opexpr->args);
1467 	clause_rightop = (Node *) lsecond(clause_opexpr->args);
1468 
1469 	if (equal(pred_leftop, clause_leftop))
1470 	{
1471 		if (equal(pred_rightop, clause_rightop))
1472 		{
1473 			/* We have x op1 y and x op2 y */
1474 			return operator_same_subexprs_proof(pred_op, clause_op, refute_it);
1475 		}
1476 		else
1477 		{
1478 			/* Fail unless rightops are both Consts */
1479 			if (pred_rightop == NULL || !IsA(pred_rightop, Const))
1480 				return false;
1481 			pred_const = (Const *) pred_rightop;
1482 			if (clause_rightop == NULL || !IsA(clause_rightop, Const))
1483 				return false;
1484 			clause_const = (Const *) clause_rightop;
1485 		}
1486 	}
1487 	else if (equal(pred_rightop, clause_rightop))
1488 	{
1489 		/* Fail unless leftops are both Consts */
1490 		if (pred_leftop == NULL || !IsA(pred_leftop, Const))
1491 			return false;
1492 		pred_const = (Const *) pred_leftop;
1493 		if (clause_leftop == NULL || !IsA(clause_leftop, Const))
1494 			return false;
1495 		clause_const = (Const *) clause_leftop;
1496 		/* Commute both operators so we can assume Consts are on the right */
1497 		pred_op = get_commutator(pred_op);
1498 		if (!OidIsValid(pred_op))
1499 			return false;
1500 		clause_op = get_commutator(clause_op);
1501 		if (!OidIsValid(clause_op))
1502 			return false;
1503 	}
1504 	else if (equal(pred_leftop, clause_rightop))
1505 	{
1506 		if (equal(pred_rightop, clause_leftop))
1507 		{
1508 			/* We have x op1 y and y op2 x */
1509 			/* Commute pred_op that we can treat this like a straight match */
1510 			pred_op = get_commutator(pred_op);
1511 			if (!OidIsValid(pred_op))
1512 				return false;
1513 			return operator_same_subexprs_proof(pred_op, clause_op, refute_it);
1514 		}
1515 		else
1516 		{
1517 			/* Fail unless pred_rightop/clause_leftop are both Consts */
1518 			if (pred_rightop == NULL || !IsA(pred_rightop, Const))
1519 				return false;
1520 			pred_const = (Const *) pred_rightop;
1521 			if (clause_leftop == NULL || !IsA(clause_leftop, Const))
1522 				return false;
1523 			clause_const = (Const *) clause_leftop;
1524 			/* Commute clause_op so we can assume Consts are on the right */
1525 			clause_op = get_commutator(clause_op);
1526 			if (!OidIsValid(clause_op))
1527 				return false;
1528 		}
1529 	}
1530 	else if (equal(pred_rightop, clause_leftop))
1531 	{
1532 		/* Fail unless pred_leftop/clause_rightop are both Consts */
1533 		if (pred_leftop == NULL || !IsA(pred_leftop, Const))
1534 			return false;
1535 		pred_const = (Const *) pred_leftop;
1536 		if (clause_rightop == NULL || !IsA(clause_rightop, Const))
1537 			return false;
1538 		clause_const = (Const *) clause_rightop;
1539 		/* Commute pred_op so we can assume Consts are on the right */
1540 		pred_op = get_commutator(pred_op);
1541 		if (!OidIsValid(pred_op))
1542 			return false;
1543 	}
1544 	else
1545 	{
1546 		/* Failed to match up any of the subexpressions, so we lose */
1547 		return false;
1548 	}
1549 
1550 	/*
1551 	 * We have two identical subexpressions, and two other subexpressions that
1552 	 * are not identical but are both Consts; and we have commuted the
1553 	 * operators if necessary so that the Consts are on the right.  We'll need
1554 	 * to compare the Consts' values.  If either is NULL, fail.
1555 	 */
1556 	if (pred_const->constisnull)
1557 		return false;
1558 	if (clause_const->constisnull)
1559 		return false;
1560 
1561 	/*
1562 	 * Lookup the constant-comparison operator using the system catalogs and
1563 	 * the operator implication tables.
1564 	 */
1565 	test_op = get_btree_test_op(pred_op, clause_op, refute_it);
1566 
1567 	if (!OidIsValid(test_op))
1568 	{
1569 		/* couldn't find a suitable comparison operator */
1570 		return false;
1571 	}
1572 
1573 	/*
1574 	 * Evaluate the test.  For this we need an EState.
1575 	 */
1576 	estate = CreateExecutorState();
1577 
1578 	/* We can use the estate's working context to avoid memory leaks. */
1579 	oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1580 
1581 	/* Build expression tree */
1582 	test_expr = make_opclause(test_op,
1583 							  BOOLOID,
1584 							  false,
1585 							  (Expr *) pred_const,
1586 							  (Expr *) clause_const,
1587 							  InvalidOid,
1588 							  pred_collation);
1589 
1590 	/* Fill in opfuncids */
1591 	fix_opfuncids((Node *) test_expr);
1592 
1593 	/* Prepare it for execution */
1594 	test_exprstate = ExecInitExpr(test_expr, NULL);
1595 
1596 	/* And execute it. */
1597 	test_result = ExecEvalExprSwitchContext(test_exprstate,
1598 											GetPerTupleExprContext(estate),
1599 											&isNull, NULL);
1600 
1601 	/* Get back to outer memory context */
1602 	MemoryContextSwitchTo(oldcontext);
1603 
1604 	/* Release all the junk we just created */
1605 	FreeExecutorState(estate);
1606 
1607 	if (isNull)
1608 	{
1609 		/* Treat a null result as non-proof ... but it's a tad fishy ... */
1610 		elog(DEBUG2, "null predicate test result");
1611 		return false;
1612 	}
1613 	return DatumGetBool(test_result);
1614 }
1615 
1616 
1617 /*
1618  * operator_same_subexprs_proof
1619  *	  Assuming that EXPR1 clause_op EXPR2 is true, try to prove or refute
1620  *	  EXPR1 pred_op EXPR2.
1621  *
1622  * Return TRUE if able to make the proof, false if not able to prove it.
1623  */
1624 static bool
operator_same_subexprs_proof(Oid pred_op,Oid clause_op,bool refute_it)1625 operator_same_subexprs_proof(Oid pred_op, Oid clause_op, bool refute_it)
1626 {
1627 	/*
1628 	 * A simple and general rule is that the predicate is proven if clause_op
1629 	 * and pred_op are the same, or refuted if they are each other's negators.
1630 	 * We need not check immutability since the pred_op is already known
1631 	 * immutable.  (Actually, by this point we may have the commutator of a
1632 	 * known-immutable pred_op, but that should certainly be immutable too.
1633 	 * Likewise we don't worry whether the pred_op's negator is immutable.)
1634 	 *
1635 	 * Note: the "same" case won't get here if we actually had EXPR1 clause_op
1636 	 * EXPR2 and EXPR1 pred_op EXPR2, because the overall-expression-equality
1637 	 * test in predicate_implied_by_simple_clause would have caught it.  But
1638 	 * we can see the same operator after having commuted the pred_op.
1639 	 */
1640 	if (refute_it)
1641 	{
1642 		if (get_negator(pred_op) == clause_op)
1643 			return true;
1644 	}
1645 	else
1646 	{
1647 		if (pred_op == clause_op)
1648 			return true;
1649 	}
1650 
1651 	/*
1652 	 * Otherwise, see if we can determine the implication by finding the
1653 	 * operators' relationship via some btree opfamily.
1654 	 */
1655 	return operator_same_subexprs_lookup(pred_op, clause_op, refute_it);
1656 }
1657 
1658 
1659 /*
1660  * We use a lookaside table to cache the result of btree proof operator
1661  * lookups, since the actual lookup is pretty expensive and doesn't change
1662  * for any given pair of operators (at least as long as pg_amop doesn't
1663  * change).  A single hash entry stores both implication and refutation
1664  * results for a given pair of operators; but note we may have determined
1665  * only one of those sets of results as yet.
1666  */
1667 typedef struct OprProofCacheKey
1668 {
1669 	Oid			pred_op;		/* predicate operator */
1670 	Oid			clause_op;		/* clause operator */
1671 } OprProofCacheKey;
1672 
1673 typedef struct OprProofCacheEntry
1674 {
1675 	/* the hash lookup key MUST BE FIRST */
1676 	OprProofCacheKey key;
1677 
1678 	bool		have_implic;	/* do we know the implication result? */
1679 	bool		have_refute;	/* do we know the refutation result? */
1680 	bool		same_subexprs_implies;	/* X clause_op Y implies X pred_op Y? */
1681 	bool		same_subexprs_refutes;	/* X clause_op Y refutes X pred_op Y? */
1682 	Oid			implic_test_op; /* OID of the test operator, or 0 if none */
1683 	Oid			refute_test_op; /* OID of the test operator, or 0 if none */
1684 } OprProofCacheEntry;
1685 
1686 static HTAB *OprProofCacheHash = NULL;
1687 
1688 
1689 /*
1690  * lookup_proof_cache
1691  *	  Get, and fill in if necessary, the appropriate cache entry.
1692  */
1693 static OprProofCacheEntry *
lookup_proof_cache(Oid pred_op,Oid clause_op,bool refute_it)1694 lookup_proof_cache(Oid pred_op, Oid clause_op, bool refute_it)
1695 {
1696 	OprProofCacheKey key;
1697 	OprProofCacheEntry *cache_entry;
1698 	bool		cfound;
1699 	bool		same_subexprs = false;
1700 	Oid			test_op = InvalidOid;
1701 	bool		found = false;
1702 	List	   *pred_op_infos,
1703 			   *clause_op_infos;
1704 	ListCell   *lcp,
1705 			   *lcc;
1706 
1707 	/*
1708 	 * Find or make a cache entry for this pair of operators.
1709 	 */
1710 	if (OprProofCacheHash == NULL)
1711 	{
1712 		/* First time through: initialize the hash table */
1713 		HASHCTL		ctl;
1714 
1715 		MemSet(&ctl, 0, sizeof(ctl));
1716 		ctl.keysize = sizeof(OprProofCacheKey);
1717 		ctl.entrysize = sizeof(OprProofCacheEntry);
1718 		OprProofCacheHash = hash_create("Btree proof lookup cache", 256,
1719 										&ctl, HASH_ELEM | HASH_BLOBS);
1720 
1721 		/* Arrange to flush cache on pg_amop changes */
1722 		CacheRegisterSyscacheCallback(AMOPOPID,
1723 									  InvalidateOprProofCacheCallBack,
1724 									  (Datum) 0);
1725 	}
1726 
1727 	key.pred_op = pred_op;
1728 	key.clause_op = clause_op;
1729 	cache_entry = (OprProofCacheEntry *) hash_search(OprProofCacheHash,
1730 													 (void *) &key,
1731 													 HASH_ENTER, &cfound);
1732 	if (!cfound)
1733 	{
1734 		/* new cache entry, set it invalid */
1735 		cache_entry->have_implic = false;
1736 		cache_entry->have_refute = false;
1737 	}
1738 	else
1739 	{
1740 		/* pre-existing cache entry, see if we know the answer yet */
1741 		if (refute_it ? cache_entry->have_refute : cache_entry->have_implic)
1742 			return cache_entry;
1743 	}
1744 
1745 	/*
1746 	 * Try to find a btree opfamily containing the given operators.
1747 	 *
1748 	 * We must find a btree opfamily that contains both operators, else the
1749 	 * implication can't be determined.  Also, the opfamily must contain a
1750 	 * suitable test operator taking the operators' righthand datatypes.
1751 	 *
1752 	 * If there are multiple matching opfamilies, assume we can use any one to
1753 	 * determine the logical relationship of the two operators and the correct
1754 	 * corresponding test operator.  This should work for any logically
1755 	 * consistent opfamilies.
1756 	 *
1757 	 * Note that we can determine the operators' relationship for
1758 	 * same-subexprs cases even from an opfamily that lacks a usable test
1759 	 * operator.  This can happen in cases with incomplete sets of cross-type
1760 	 * comparison operators.
1761 	 */
1762 	clause_op_infos = get_op_btree_interpretation(clause_op);
1763 	if (clause_op_infos)
1764 		pred_op_infos = get_op_btree_interpretation(pred_op);
1765 	else	/* no point in looking */
1766 		pred_op_infos = NIL;
1767 
1768 	foreach(lcp, pred_op_infos)
1769 	{
1770 		OpBtreeInterpretation *pred_op_info = lfirst(lcp);
1771 		Oid			opfamily_id = pred_op_info->opfamily_id;
1772 
1773 		foreach(lcc, clause_op_infos)
1774 		{
1775 			OpBtreeInterpretation *clause_op_info = lfirst(lcc);
1776 			StrategyNumber pred_strategy,
1777 						clause_strategy,
1778 						test_strategy;
1779 
1780 			/* Must find them in same opfamily */
1781 			if (opfamily_id != clause_op_info->opfamily_id)
1782 				continue;
1783 			/* Lefttypes should match */
1784 			Assert(clause_op_info->oplefttype == pred_op_info->oplefttype);
1785 
1786 			pred_strategy = pred_op_info->strategy;
1787 			clause_strategy = clause_op_info->strategy;
1788 
1789 			/*
1790 			 * Check to see if we can make a proof for same-subexpressions
1791 			 * cases based on the operators' relationship in this opfamily.
1792 			 */
1793 			if (refute_it)
1794 				same_subexprs |= BT_refutes_table[clause_strategy - 1][pred_strategy - 1];
1795 			else
1796 				same_subexprs |= BT_implies_table[clause_strategy - 1][pred_strategy - 1];
1797 
1798 			/*
1799 			 * Look up the "test" strategy number in the implication table
1800 			 */
1801 			if (refute_it)
1802 				test_strategy = BT_refute_table[clause_strategy - 1][pred_strategy - 1];
1803 			else
1804 				test_strategy = BT_implic_table[clause_strategy - 1][pred_strategy - 1];
1805 
1806 			if (test_strategy == 0)
1807 			{
1808 				/* Can't determine implication using this interpretation */
1809 				continue;
1810 			}
1811 
1812 			/*
1813 			 * See if opfamily has an operator for the test strategy and the
1814 			 * datatypes.
1815 			 */
1816 			if (test_strategy == BTNE)
1817 			{
1818 				test_op = get_opfamily_member(opfamily_id,
1819 											  pred_op_info->oprighttype,
1820 											  clause_op_info->oprighttype,
1821 											  BTEqualStrategyNumber);
1822 				if (OidIsValid(test_op))
1823 					test_op = get_negator(test_op);
1824 			}
1825 			else
1826 			{
1827 				test_op = get_opfamily_member(opfamily_id,
1828 											  pred_op_info->oprighttype,
1829 											  clause_op_info->oprighttype,
1830 											  test_strategy);
1831 			}
1832 
1833 			if (!OidIsValid(test_op))
1834 				continue;
1835 
1836 			/*
1837 			 * Last check: test_op must be immutable.
1838 			 *
1839 			 * Note that we require only the test_op to be immutable, not the
1840 			 * original clause_op.  (pred_op is assumed to have been checked
1841 			 * immutable by the caller.)  Essentially we are assuming that the
1842 			 * opfamily is consistent even if it contains operators that are
1843 			 * merely stable.
1844 			 */
1845 			if (op_volatile(test_op) == PROVOLATILE_IMMUTABLE)
1846 			{
1847 				found = true;
1848 				break;
1849 			}
1850 		}
1851 
1852 		if (found)
1853 			break;
1854 	}
1855 
1856 	list_free_deep(pred_op_infos);
1857 	list_free_deep(clause_op_infos);
1858 
1859 	if (!found)
1860 	{
1861 		/* couldn't find a suitable comparison operator */
1862 		test_op = InvalidOid;
1863 	}
1864 
1865 	/*
1866 	 * If we think we were able to prove something about same-subexpressions
1867 	 * cases, check to make sure the clause_op is immutable before believing
1868 	 * it completely.  (Usually, the clause_op would be immutable if the
1869 	 * pred_op is, but it's not entirely clear that this must be true in all
1870 	 * cases, so let's check.)
1871 	 */
1872 	if (same_subexprs &&
1873 		op_volatile(clause_op) != PROVOLATILE_IMMUTABLE)
1874 		same_subexprs = false;
1875 
1876 	/* Cache the results, whether positive or negative */
1877 	if (refute_it)
1878 	{
1879 		cache_entry->refute_test_op = test_op;
1880 		cache_entry->same_subexprs_refutes = same_subexprs;
1881 		cache_entry->have_refute = true;
1882 	}
1883 	else
1884 	{
1885 		cache_entry->implic_test_op = test_op;
1886 		cache_entry->same_subexprs_implies = same_subexprs;
1887 		cache_entry->have_implic = true;
1888 	}
1889 
1890 	return cache_entry;
1891 }
1892 
1893 /*
1894  * operator_same_subexprs_lookup
1895  *	  Convenience subroutine to look up the cached answer for
1896  *	  same-subexpressions cases.
1897  */
1898 static bool
operator_same_subexprs_lookup(Oid pred_op,Oid clause_op,bool refute_it)1899 operator_same_subexprs_lookup(Oid pred_op, Oid clause_op, bool refute_it)
1900 {
1901 	OprProofCacheEntry *cache_entry;
1902 
1903 	cache_entry = lookup_proof_cache(pred_op, clause_op, refute_it);
1904 	if (refute_it)
1905 		return cache_entry->same_subexprs_refutes;
1906 	else
1907 		return cache_entry->same_subexprs_implies;
1908 }
1909 
1910 /*
1911  * get_btree_test_op
1912  *	  Identify the comparison operator needed for a btree-operator
1913  *	  proof or refutation involving comparison of constants.
1914  *
1915  * Given the truth of a clause "var clause_op const1", we are attempting to
1916  * prove or refute a predicate "var pred_op const2".  The identities of the
1917  * two operators are sufficient to determine the operator (if any) to compare
1918  * const2 to const1 with.
1919  *
1920  * Returns the OID of the operator to use, or InvalidOid if no proof is
1921  * possible.
1922  */
1923 static Oid
get_btree_test_op(Oid pred_op,Oid clause_op,bool refute_it)1924 get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
1925 {
1926 	OprProofCacheEntry *cache_entry;
1927 
1928 	cache_entry = lookup_proof_cache(pred_op, clause_op, refute_it);
1929 	if (refute_it)
1930 		return cache_entry->refute_test_op;
1931 	else
1932 		return cache_entry->implic_test_op;
1933 }
1934 
1935 
1936 /*
1937  * Callback for pg_amop inval events
1938  */
1939 static void
InvalidateOprProofCacheCallBack(Datum arg,int cacheid,uint32 hashvalue)1940 InvalidateOprProofCacheCallBack(Datum arg, int cacheid, uint32 hashvalue)
1941 {
1942 	HASH_SEQ_STATUS status;
1943 	OprProofCacheEntry *hentry;
1944 
1945 	Assert(OprProofCacheHash != NULL);
1946 
1947 	/* Currently we just reset all entries; hard to be smarter ... */
1948 	hash_seq_init(&status, OprProofCacheHash);
1949 
1950 	while ((hentry = (OprProofCacheEntry *) hash_seq_search(&status)) != NULL)
1951 	{
1952 		hentry->have_implic = false;
1953 		hentry->have_refute = false;
1954 	}
1955 }
1956