Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6357f4e

Browse files
committed
Teach predicate_refuted_by() how to do proofs involving NOT-clauses.
This doesn't matter too much for ordinary NOTs, since prepqual.c doesits best to get rid of those, but it helps with IS NOT TRUE clauseswhich the rule rewriter likes to insert. Per example from Martin Lesser.
1 parent3f23f4e commit6357f4e

File tree

1 file changed

+74
-4
lines changed

1 file changed

+74
-4
lines changed

‎src/backend/optimizer/util/predtest.c

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.7 2006/07/14 14:52:21 momjian Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.8 2006/08/05 00:21:14 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -81,6 +81,7 @@ static Node *arrayexpr_next_fn(PredIterInfo info);
8181
staticvoidarrayexpr_cleanup_fn(PredIterInfoinfo);
8282
staticboolpredicate_implied_by_simple_clause(Expr*predicate,Node*clause);
8383
staticboolpredicate_refuted_by_simple_clause(Expr*predicate,Node*clause);
84+
staticNode*extract_not_arg(Node*clause);
8485
staticboolbtree_predicate_proof(Expr*predicate,Node*clause,
8586
boolrefute_it);
8687

@@ -393,6 +394,13 @@ predicate_implied_by_recurse(Node *clause, Node *predicate)
393394
*OR-expr A R=> AND-expr B iff:each of A's components R=> any of B's
394395
*OR-expr A R=> OR-expr B iff:A R=> each of B's components
395396
*
397+
* In addition, if the predicate is a NOT-clause then we can use
398+
*A R=> NOT B if:A => B
399+
* while if the restriction clause is a NOT-clause then we can use
400+
*NOT A R=> B if:B => A
401+
* This works for several different SQL constructs that assert the non-truth
402+
* of their argument, ie NOT, IS FALSE, IS NOT TRUE, IS UNKNOWN.
403+
*
396404
* Other comments are as for predicate_implied_by_recurse().
397405
*----------
398406
*/
@@ -402,6 +410,7 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate)
402410
PredIterInfoDataclause_info;
403411
PredIterInfoDatapred_info;
404412
PredClasspclass;
413+
Node*not_arg;
405414
boolresult;
406415

407416
/* skip through RestrictInfo */
@@ -467,6 +476,13 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate)
467476
returnresult;
468477

469478
caseCLASS_ATOM:
479+
/*
480+
* If B is a NOT-clause, A R=> B if A => B's arg
481+
*/
482+
not_arg=extract_not_arg(predicate);
483+
if (not_arg&&
484+
predicate_implied_by_recurse(clause,not_arg))
485+
return true;
470486
/*
471487
* AND-clause R=> atom if any of A's items refutes B
472488
*/
@@ -532,6 +548,13 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate)
532548
returnresult;
533549

534550
caseCLASS_ATOM:
551+
/*
552+
* If B is a NOT-clause, A R=> B if A => B's arg
553+
*/
554+
not_arg=extract_not_arg(predicate);
555+
if (not_arg&&
556+
predicate_implied_by_recurse(clause,not_arg))
557+
return true;
535558
/*
536559
* OR-clause R=> atom if each of A's items refutes B
537560
*/
@@ -550,6 +573,13 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate)
550573
break;
551574

552575
caseCLASS_ATOM:
576+
/*
577+
* If A is a NOT-clause, A R=> B if B => A's arg
578+
*/
579+
not_arg=extract_not_arg(clause);
580+
if (not_arg&&
581+
predicate_implied_by_recurse(predicate,not_arg))
582+
return true;
553583
switch (pclass)
554584
{
555585
caseCLASS_AND:
@@ -585,6 +615,13 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate)
585615
returnresult;
586616

587617
caseCLASS_ATOM:
618+
/*
619+
* If B is a NOT-clause, A R=> B if A => B's arg
620+
*/
621+
not_arg=extract_not_arg(predicate);
622+
if (not_arg&&
623+
predicate_implied_by_recurse(clause,not_arg))
624+
return true;
588625
/*
589626
* atom R=> atom is the base case
590627
*/
@@ -917,8 +954,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause)
917954
* We return TRUE if able to prove the refutation, FALSE if not.
918955
*
919956
* Unlike the implication case, checking for equal() clauses isn't
920-
* helpful. (XXX is it worth looking at "x vs NOT x" cases? Probably
921-
* not seeing that canonicalization tries to get rid of NOTs.)
957+
* helpful.
922958
*
923959
* When the predicate is of the form "foo IS NULL", we can conclude that
924960
* the predicate is refuted if the clause is a strict operator or function
@@ -931,7 +967,12 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause)
931967
staticbool
932968
predicate_refuted_by_simple_clause(Expr*predicate,Node*clause)
933969
{
934-
/* First try the IS NULL case */
970+
/* A simple clause can't refute itself */
971+
/* Worth checking because of relation_excluded_by_constraints() */
972+
if ((Node*)predicate==clause)
973+
return false;
974+
975+
/* Try the IS NULL case */
935976
if (predicate&&IsA(predicate,NullTest)&&
936977
((NullTest*)predicate)->nulltesttype==IS_NULL)
937978
{
@@ -953,6 +994,35 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
953994
}
954995

955996

997+
/*
998+
* If clause asserts the non-truth of a subclause, return that subclause;
999+
* otherwise return NULL.
1000+
*/
1001+
staticNode*
1002+
extract_not_arg(Node*clause)
1003+
{
1004+
if (clause==NULL)
1005+
returnNULL;
1006+
if (IsA(clause,BoolExpr))
1007+
{
1008+
BoolExpr*bexpr= (BoolExpr*)clause;
1009+
1010+
if (bexpr->boolop==NOT_EXPR)
1011+
return (Node*)linitial(bexpr->args);
1012+
}
1013+
elseif (IsA(clause,BooleanTest))
1014+
{
1015+
BooleanTest*btest= (BooleanTest*)clause;
1016+
1017+
if (btest->booltesttype==IS_NOT_TRUE||
1018+
btest->booltesttype==IS_FALSE||
1019+
btest->booltesttype==IS_UNKNOWN)
1020+
return (Node*)btest->arg;
1021+
}
1022+
returnNULL;
1023+
}
1024+
1025+
9561026
/*
9571027
* Define an "operator implication table" for btree operators ("strategies"),
9581028
* and a similar table for refutation.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp