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

Commit1856e60

Browse files
committed
Improve predicate_refuted_by_simple_clause() to handle IS NULL and IS NOT NULL
more completely. The motivation for having it understand IS NULL at all wasto allow use of "foo IS NULL" as one of the subsets of a partitioning on"foo", but as reported by Aleksander Kmetec, it wasn't really getting the jobdone. Backpatch to 8.2 since this is arguably a performance bug.
1 parent9aa3c78 commit1856e60

File tree

1 file changed

+51
-16
lines changed

1 file changed

+51
-16
lines changed

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

Lines changed: 51 additions & 16 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.14 2007/03/17 00:11:04 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.15 2007/05/12 19:22:35 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -82,6 +82,7 @@ static Node *arrayexpr_next_fn(PredIterInfo info);
8282
staticvoidarrayexpr_cleanup_fn(PredIterInfoinfo);
8383
staticboolpredicate_implied_by_simple_clause(Expr*predicate,Node*clause);
8484
staticboolpredicate_refuted_by_simple_clause(Expr*predicate,Node*clause);
85+
staticboolis_null_contradicts(NullTest*ntest,Node*clause);
8586
staticNode*extract_not_arg(Node*clause);
8687
staticboolbtree_predicate_proof(Expr*predicate,Node*clause,
8788
boolrefute_it);
@@ -987,7 +988,10 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause)
987988
*
988989
* When the predicate is of the form "foo IS NULL", we can conclude that
989990
* the predicate is refuted if the clause is a strict operator or function
990-
* that has "foo" as an input.See notes for implication case.
991+
* that has "foo" as an input (see notes for implication case), or if the
992+
* clause is "foo IS NOT NULL". Conversely a clause "foo IS NULL" refutes
993+
* predicates of those types. (The motivation for covering these cases is
994+
* to support using IS NULL/IS NOT NULL as partition-defining constraints.)
991995
*
992996
* Finally, we may be able to deduce something using knowledge about btree
993997
* operator families; this is encapsulated in btree_predicate_proof().
@@ -1001,24 +1005,21 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
10011005
if ((Node*)predicate==clause)
10021006
return false;
10031007

1004-
/* Try theISNULL case */
1008+
/* Try thepredicate-IS-NULL case */
10051009
if (predicate&&IsA(predicate,NullTest)&&
10061010
((NullTest*)predicate)->nulltesttype==IS_NULL)
10071011
{
1008-
Expr*isnullarg= ((NullTest*)predicate)->arg;
1012+
if (is_null_contradicts((NullTest*)predicate,clause))
1013+
return true;
1014+
return false;/* we can't succeed below... */
1015+
}
10091016

1010-
/* row IS NULL does not act in the simple way we have in mind */
1011-
if (!type_is_rowtype(exprType((Node*)isnullarg)))
1012-
{
1013-
if (is_opclause(clause)&&
1014-
list_member(((OpExpr*)clause)->args,isnullarg)&&
1015-
op_strict(((OpExpr*)clause)->opno))
1016-
return true;
1017-
if (is_funcclause(clause)&&
1018-
list_member(((FuncExpr*)clause)->args,isnullarg)&&
1019-
func_strict(((FuncExpr*)clause)->funcid))
1020-
return true;
1021-
}
1017+
/* Try the clause-IS-NULL case */
1018+
if (clause&&IsA(clause,NullTest)&&
1019+
((NullTest*)clause)->nulltesttype==IS_NULL)
1020+
{
1021+
if (is_null_contradicts((NullTest*)clause, (Node*)predicate))
1022+
return true;
10221023
return false;/* we can't succeed below... */
10231024
}
10241025

@@ -1027,6 +1028,40 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
10271028
}
10281029

10291030

1031+
/*
1032+
* Check whether a "foo IS NULL" test contradicts clause. (We say
1033+
* "contradicts" rather than "refutes" because the refutation goes
1034+
* both ways.)
1035+
*/
1036+
staticbool
1037+
is_null_contradicts(NullTest*ntest,Node*clause)
1038+
{
1039+
Expr*isnullarg=ntest->arg;
1040+
1041+
/* row IS NULL does not act in the simple way we have in mind */
1042+
if (type_is_rowtype(exprType((Node*)isnullarg)))
1043+
return false;
1044+
1045+
/* foo IS NULL contradicts any strict op/func on foo */
1046+
if (is_opclause(clause)&&
1047+
list_member(((OpExpr*)clause)->args,isnullarg)&&
1048+
op_strict(((OpExpr*)clause)->opno))
1049+
return true;
1050+
if (is_funcclause(clause)&&
1051+
list_member(((FuncExpr*)clause)->args,isnullarg)&&
1052+
func_strict(((FuncExpr*)clause)->funcid))
1053+
return true;
1054+
1055+
/* foo IS NULL contradicts foo IS NOT NULL */
1056+
if (clause&&IsA(clause,NullTest)&&
1057+
((NullTest*)clause)->nulltesttype==IS_NOT_NULL&&
1058+
equal(((NullTest*)clause)->arg,isnullarg))
1059+
return true;
1060+
1061+
return false;
1062+
}
1063+
1064+
10301065
/*
10311066
* If clause asserts the non-truth of a subclause, return that subclause;
10321067
* otherwise return NULL.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp