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

Commita43f430

Browse files
committed
Improve has_nullable_targetlist() to allow strict functions of simple
variables, not just simple variables. This was foreseen in the originalcoding of this routine, but not implemented until now. Responds toperformance gripe from Laurent Perez.
1 parent47f8f33 commita43f430

File tree

2 files changed

+36
-28
lines changed

2 files changed

+36
-28
lines changed

‎src/backend/optimizer/prep/prepjointree.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
*
1818
* IDENTIFICATION
19-
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.15 2004/01/1000:30:21 tgl Exp $
19+
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.16 2004/01/1018:13:53 tgl Exp $
2020
*
2121
*-------------------------------------------------------------------------
2222
*/
@@ -439,11 +439,13 @@ is_simple_subquery(Query *subquery)
439439
/*
440440
* has_nullable_targetlist
441441
* Check a subquery in the range table to see if all the non-junk
442-
* targetlist items are simple variables (and, hence, will correctly
443-
* go to NULL when examined above the point of an outer join).
442+
* targetlist items are simple variables or strict functions of simple
443+
* variables (and, hence, will correctly go to NULL when examined above
444+
* the point of an outer join).
444445
*
445-
* A possible future extension is to accept strict functions of simple
446-
* variables, eg, "x + 1".
446+
* NOTE: it would be correct (and useful) to ignore output columns that aren't
447+
* actually referenced by the enclosing query ... but we do not have that
448+
* information available at this point.
447449
*/
448450
staticbool
449451
has_nullable_targetlist(Query*subquery)
@@ -458,11 +460,15 @@ has_nullable_targetlist(Query *subquery)
458460
if (tle->resdom->resjunk)
459461
continue;
460462

461-
/*Okay if tlist item is a simple Var */
462-
if (tle->expr&&IsA(tle->expr,Var))
463-
continue;
463+
/*Must contain a Var of current level */
464+
if (!contain_vars_of_level((Node*)tle->expr,0))
465+
return false;
464466

465-
return false;
467+
/* Must not contain any non-strict constructs */
468+
if (contain_nonstrict_functions((Node*)tle->expr))
469+
return false;
470+
471+
/* This one's OK, keep scanning */
466472
}
467473
return true;
468474
}

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

Lines changed: 21 additions & 19 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.160 2004/01/05 18:04:39 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.161 2004/01/10 18:13:53 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHORDATEMAJOR EVENT
@@ -697,10 +697,10 @@ contain_volatile_functions_walker(Node *node, void *context)
697697
* Returns true if any nonstrict construct is found --- ie, anything that
698698
* could produce non-NULL output with a NULL input.
699699
*
700-
*XXX we do not examine sub-selects to see if they contain uses of
701-
*nonstrict functions. It's not real clear if that is correct or not...
702-
*forthecurrent usage it does not matter, since inline_function()
703-
*rejects cases with sublinks.
700+
*The idea here is that the caller has verified that the expression contains
701+
*one or more Var or Param nodes (as appropriate for the caller's need), and
702+
*now wishes to prove thattheexpression result will be NULL if any of these
703+
*inputs is NULL. If we return false, then the proof succeeded.
704704
*/
705705
bool
706706
contain_nonstrict_functions(Node*clause)
@@ -713,6 +713,11 @@ contain_nonstrict_functions_walker(Node *node, void *context)
713713
{
714714
if (node==NULL)
715715
return false;
716+
if (IsA(node,Aggref))
717+
{
718+
/* an aggregate could return non-null with null input */
719+
return true;
720+
}
716721
if (IsA(node,FuncExpr))
717722
{
718723
FuncExpr*expr= (FuncExpr*)node;
@@ -745,16 +750,25 @@ contain_nonstrict_functions_walker(Node *node, void *context)
745750

746751
switch (expr->boolop)
747752
{
748-
caseOR_EXPR:
749753
caseAND_EXPR:
750-
/* OR, AND are inherently non-strict */
754+
caseOR_EXPR:
755+
/* AND, OR are inherently non-strict */
751756
return true;
752757
default:
753758
break;
754759
}
755760
}
761+
if (IsA(node,SubLink))
762+
{
763+
/* In some cases a sublink might be strict, but in general not */
764+
return true;
765+
}
766+
if (IsA(node,SubPlan))
767+
return true;
756768
if (IsA(node,CaseExpr))
757769
return true;
770+
if (IsA(node,CaseWhen))
771+
return true;
758772
/* NB: ArrayExpr might someday be nonstrict */
759773
if (IsA(node,CoalesceExpr))
760774
return true;
@@ -764,18 +778,6 @@ contain_nonstrict_functions_walker(Node *node, void *context)
764778
return true;
765779
if (IsA(node,BooleanTest))
766780
return true;
767-
if (IsA(node,SubLink))
768-
{
769-
SubLink*sublink= (SubLink*)node;
770-
List*opid;
771-
772-
foreach(opid,sublink->operOids)
773-
{
774-
if (!op_strict(lfirsto(opid)))
775-
return true;
776-
}
777-
/* else fall through to check args */
778-
}
779781
returnexpression_tree_walker(node,contain_nonstrict_functions_walker,
780782
context);
781783
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp