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

Commit72153c0

Browse files
committed
Improve the tests to see if ScalarArrayOpExpr is strict. Original coding
would basically punt in all cases for 'foo <> ALL (array)', which resultedin a performance regression for NOT IN compared to what we were doing in8.1 and before. Per report from Pavel Stehule.
1 parenta6fefc8 commit72153c0

File tree

1 file changed

+59
-5
lines changed

1 file changed

+59
-5
lines changed

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

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.207 2006/01/3121:39:24 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.208 2006/02/06 22:21:12 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHORDATEMAJOR EVENT
@@ -70,6 +70,7 @@ static bool contain_mutable_functions_walker(Node *node, void *context);
7070
staticboolcontain_volatile_functions_walker(Node*node,void*context);
7171
staticboolcontain_nonstrict_functions_walker(Node*node,void*context);
7272
staticRelidsfind_nonnullable_rels_walker(Node*node,booltop_level);
73+
staticboolis_strict_saop(ScalarArrayOpExpr*expr,boolfalseOK);
7374
staticboolset_coercionform_dontcare_walker(Node*node,void*context);
7475
staticNode*eval_const_expressions_mutator(Node*node,
7576
eval_const_expressions_context*context);
@@ -816,8 +817,11 @@ contain_nonstrict_functions_walker(Node *node, void *context)
816817
}
817818
if (IsA(node,ScalarArrayOpExpr))
818819
{
819-
/* inherently non-strict, consider null scalar and empty array */
820-
return true;
820+
ScalarArrayOpExpr*expr= (ScalarArrayOpExpr*)node;
821+
822+
if (!is_strict_saop(expr, false))
823+
return true;
824+
/* else fall through to check args */
821825
}
822826
if (IsA(node,BoolExpr))
823827
{
@@ -937,10 +941,9 @@ find_nonnullable_rels_walker(Node *node, bool top_level)
937941
}
938942
elseif (IsA(node,ScalarArrayOpExpr))
939943
{
940-
/* Strict if it's "foo op ANY array" and op is strict */
941944
ScalarArrayOpExpr*expr= (ScalarArrayOpExpr*)node;
942945

943-
if (expr->useOr&&op_strict(expr->opno))
946+
if (is_strict_saop(expr, true))
944947
result=find_nonnullable_rels_walker((Node*)expr->args, false);
945948
}
946949
elseif (IsA(node,BoolExpr))
@@ -991,6 +994,57 @@ find_nonnullable_rels_walker(Node *node, bool top_level)
991994
returnresult;
992995
}
993996

997+
/*
998+
* Can we treat a ScalarArrayOpExpr as strict?
999+
*
1000+
* If "falseOK" is true, then a "false" result can be considered strict,
1001+
* else we need to guarantee an actual NULL result for NULL input.
1002+
*
1003+
* "foo op ALL array" is strict if the op is strict *and* we can prove
1004+
* that the array input isn't an empty array. We can check that
1005+
* for the cases of an array constant and an ARRAY[] construct.
1006+
*
1007+
* "foo op ANY array" is strict in the falseOK sense if the op is strict.
1008+
* If not falseOK, the test is the same as for "foo op ALL array".
1009+
*/
1010+
staticbool
1011+
is_strict_saop(ScalarArrayOpExpr*expr,boolfalseOK)
1012+
{
1013+
Node*rightop;
1014+
1015+
/* The contained operator must be strict. */
1016+
if (!op_strict(expr->opno))
1017+
return false;
1018+
/* If ANY and falseOK, that's all we need to check. */
1019+
if (expr->useOr&&falseOK)
1020+
return true;
1021+
/* Else, we have to see if the array is provably non-empty. */
1022+
Assert(list_length(expr->args)==2);
1023+
rightop= (Node*)lsecond(expr->args);
1024+
if (rightop&&IsA(rightop,Const))
1025+
{
1026+
Datumarraydatum= ((Const*)rightop)->constvalue;
1027+
boolarrayisnull= ((Const*)rightop)->constisnull;
1028+
ArrayType*arrayval;
1029+
intnitems;
1030+
1031+
if (arrayisnull)
1032+
return false;
1033+
arrayval=DatumGetArrayTypeP(arraydatum);
1034+
nitems=ArrayGetNItems(ARR_NDIM(arrayval),ARR_DIMS(arrayval));
1035+
if (nitems>0)
1036+
return true;
1037+
}
1038+
elseif (rightop&&IsA(rightop,ArrayExpr))
1039+
{
1040+
ArrayExpr*arrayexpr= (ArrayExpr*)rightop;
1041+
1042+
if (arrayexpr->elements!=NIL&& !arrayexpr->multidims)
1043+
return true;
1044+
}
1045+
return false;
1046+
}
1047+
9941048

9951049
/*****************************************************************************
9961050
*Check for "pseudo-constant" clauses

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp