Skip to content

Commit a1b8c41

Browse files
committed
Make some small planner API cleanups.
Move a few very simple node-creation and node-type-testing functions from the planner's clauses.c to nodes/makefuncs and nodes/nodeFuncs. There's nothing planner-specific about them, as evidenced by the number of other places that were using them. While at it, rename and_clause() etc to is_andclause() etc, to clarify that they are node-type-testing functions not node-creation functions. And use "static inline" implementations for the shortest ones. Also, modify flatten_join_alias_vars() and some subsidiary functions to take a Query not a PlannerInfo to define the join structure that Vars should be translated according to. They were only using the "parse" field of the PlannerInfo anyway, so this just requires removing one level of indirection. The advantage is that now parse_agg.c can use flatten_join_alias_vars() without the horrid kluge of creating an incomplete PlannerInfo, which will allow that file to be decoupled from relation.h in a subsequent patch. Discussion: https://postgr.es/m/11460.1548706639@sss.pgh.pa.us
1 parent e77cfa5 commit a1b8c41

File tree

30 files changed

+309
-345
lines changed

30 files changed

+309
-345
lines changed

src/backend/commands/explain.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "foreign/fdwapi.h"
2323
#include "jit/jit.h"
2424
#include "nodes/extensible.h"
25+
#include "nodes/makefuncs.h"
2526
#include "nodes/nodeFuncs.h"
2627
#include "optimizer/clauses.h"
2728
#include "optimizer/planmain.h"

src/backend/executor/nodeSubplan.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
#include "executor/executor.h"
3434
#include "executor/nodeSubplan.h"
3535
#include "nodes/makefuncs.h"
36+
#include "nodes/nodeFuncs.h"
3637
#include "miscadmin.h"
37-
#include "optimizer/clauses.h"
3838
#include "utils/array.h"
3939
#include "utils/lsyscache.h"
4040
#include "utils/memutils.h"
@@ -888,7 +888,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
888888
/* single combining operator */
889889
oplist = list_make1(subplan->testexpr);
890890
}
891-
else if (and_clause((Node *) subplan->testexpr))
891+
else if (is_andclause(subplan->testexpr))
892892
{
893893
/* multiple combining operators */
894894
oplist = castNode(BoolExpr, subplan->testexpr)->args;

src/backend/executor/nodeTidscan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#include "executor/execdebug.h"
2929
#include "executor/nodeTidscan.h"
3030
#include "miscadmin.h"
31-
#include "optimizer/clauses.h"
31+
#include "nodes/nodeFuncs.h"
3232
#include "storage/bufmgr.h"
3333
#include "utils/array.h"
3434
#include "utils/rel.h"

src/backend/nodes/makefuncs.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,141 @@ makeFuncCall(List *name, List *args, int location)
598598
return n;
599599
}
600600

601+
/*
602+
* make_opclause
603+
* Creates an operator clause given its operator info, left operand
604+
* and right operand (pass NULL to create single-operand clause),
605+
* and collation info.
606+
*/
607+
Expr *
608+
make_opclause(Oid opno, Oid opresulttype, bool opretset,
609+
Expr *leftop, Expr *rightop,
610+
Oid opcollid, Oid inputcollid)
611+
{
612+
OpExpr *expr = makeNode(OpExpr);
613+
614+
expr->opno = opno;
615+
expr->opfuncid = InvalidOid;
616+
expr->opresulttype = opresulttype;
617+
expr->opretset = opretset;
618+
expr->opcollid = opcollid;
619+
expr->inputcollid = inputcollid;
620+
if (rightop)
621+
expr->args = list_make2(leftop, rightop);
622+
else
623+
expr->args = list_make1(leftop);
624+
expr->location = -1;
625+
return (Expr *) expr;
626+
}
627+
628+
/*
629+
* make_andclause
630+
*
631+
* Creates an 'and' clause given a list of its subclauses.
632+
*/
633+
Expr *
634+
make_andclause(List *andclauses)
635+
{
636+
BoolExpr *expr = makeNode(BoolExpr);
637+
638+
expr->boolop = AND_EXPR;
639+
expr->args = andclauses;
640+
expr->location = -1;
641+
return (Expr *) expr;
642+
}
643+
644+
/*
645+
* make_orclause
646+
*
647+
* Creates an 'or' clause given a list of its subclauses.
648+
*/
649+
Expr *
650+
make_orclause(List *orclauses)
651+
{
652+
BoolExpr *expr = makeNode(BoolExpr);
653+
654+
expr->boolop = OR_EXPR;
655+
expr->args = orclauses;
656+
expr->location = -1;
657+
return (Expr *) expr;
658+
}
659+
660+
/*
661+
* make_notclause
662+
*
663+
* Create a 'not' clause given the expression to be negated.
664+
*/
665+
Expr *
666+
make_notclause(Expr *notclause)
667+
{
668+
BoolExpr *expr = makeNode(BoolExpr);
669+
670+
expr->boolop = NOT_EXPR;
671+
expr->args = list_make1(notclause);
672+
expr->location = -1;
673+
return (Expr *) expr;
674+
}
675+
676+
/*
677+
* make_and_qual
678+
*
679+
* Variant of make_andclause for ANDing two qual conditions together.
680+
* Qual conditions have the property that a NULL nodetree is interpreted
681+
* as 'true'.
682+
*
683+
* NB: this makes no attempt to preserve AND/OR flatness; so it should not
684+
* be used on a qual that has already been run through prepqual.c.
685+
*/
686+
Node *
687+
make_and_qual(Node *qual1, Node *qual2)
688+
{
689+
if (qual1 == NULL)
690+
return qual2;
691+
if (qual2 == NULL)
692+
return qual1;
693+
return (Node *) make_andclause(list_make2(qual1, qual2));
694+
}
695+
696+
/*
697+
* The planner and executor usually represent qualification expressions
698+
* as lists of boolean expressions with implicit AND semantics.
699+
*
700+
* These functions convert between an AND-semantics expression list and the
701+
* ordinary representation of a boolean expression.
702+
*
703+
* Note that an empty list is considered equivalent to TRUE.
704+
*/
705+
Expr *
706+
make_ands_explicit(List *andclauses)
707+
{
708+
if (andclauses == NIL)
709+
return (Expr *) makeBoolConst(true, false);
710+
else if (list_length(andclauses) == 1)
711+
return (Expr *) linitial(andclauses);
712+
else
713+
return make_andclause(andclauses);
714+
}
715+
716+
List *
717+
make_ands_implicit(Expr *clause)
718+
{
719+
/*
720+
* NB: because the parser sets the qual field to NULL in a query that has
721+
* no WHERE clause, we must consider a NULL input clause as TRUE, even
722+
* though one might more reasonably think it FALSE.
723+
*/
724+
if (clause == NULL)
725+
return NIL; /* NULL -> NIL list == TRUE */
726+
else if (is_andclause(clause))
727+
return ((BoolExpr *) clause)->args;
728+
else if (IsA(clause, Const) &&
729+
!((Const *) clause)->constisnull &&
730+
DatumGetBool(((Const *) clause)->constvalue))
731+
return NIL; /* constant TRUE input -> NIL list */
732+
else
733+
return list_make1(clause);
734+
}
735+
601736
/*
602737
* makeGroupingSet
603738
*

src/backend/nodes/print.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121

2222
#include "access/printtup.h"
2323
#include "lib/stringinfo.h"
24+
#include "nodes/nodeFuncs.h"
2425
#include "nodes/print.h"
25-
#include "optimizer/clauses.h"
26+
#include "nodes/relation.h"
2627
#include "parser/parsetree.h"
2728
#include "utils/lsyscache.h"
2829

src/backend/optimizer/path/clausesel.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "postgres.h"
1616

1717
#include "nodes/makefuncs.h"
18+
#include "nodes/nodeFuncs.h"
1819
#include "optimizer/clauses.h"
1920
#include "optimizer/cost.h"
2021
#include "optimizer/pathnode.h"
@@ -688,7 +689,7 @@ clause_selectivity(PlannerInfo *root,
688689
/* XXX any way to do better than default? */
689690
}
690691
}
691-
else if (not_clause(clause))
692+
else if (is_notclause(clause))
692693
{
693694
/* inverse of the selectivity of the underlying clause */
694695
s1 = 1.0 - clause_selectivity(root,
@@ -697,7 +698,7 @@ clause_selectivity(PlannerInfo *root,
697698
jointype,
698699
sjinfo);
699700
}
700-
else if (and_clause(clause))
701+
else if (is_andclause(clause))
701702
{
702703
/* share code with clauselist_selectivity() */
703704
s1 = clauselist_selectivity(root,
@@ -706,7 +707,7 @@ clause_selectivity(PlannerInfo *root,
706707
jointype,
707708
sjinfo);
708709
}
709-
else if (or_clause(clause))
710+
else if (is_orclause(clause))
710711
{
711712
/*
712713
* Selectivities for an OR clause are computed as s1+s2 - s1*s2 to

src/backend/optimizer/path/costsize.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#include "executor/executor.h"
8080
#include "executor/nodeHash.h"
8181
#include "miscadmin.h"
82+
#include "nodes/makefuncs.h"
8283
#include "nodes/nodeFuncs.h"
8384
#include "optimizer/clauses.h"
8485
#include "optimizer/cost.h"

src/backend/optimizer/path/indxpath.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel,
12971297
List *indlist;
12981298

12991299
/* OR arguments should be ANDs or sub-RestrictInfos */
1300-
if (and_clause(orarg))
1300+
if (is_andclause(orarg))
13011301
{
13021302
List *andargs = ((BoolExpr *) orarg)->args;
13031303

@@ -3368,7 +3368,7 @@ match_boolean_index_clause(Node *clause,
33683368
if (match_index_to_operand(clause, indexcol, index))
33693369
return true;
33703370
/* NOT clause? */
3371-
if (not_clause(clause))
3371+
if (is_notclause(clause))
33723372
{
33733373
if (match_index_to_operand((Node *) get_notclausearg((Expr *) clause),
33743374
indexcol, index))
@@ -3680,7 +3680,7 @@ expand_boolean_index_clause(Node *clause,
36803680
InvalidOid, InvalidOid);
36813681
}
36823682
/* NOT clause? */
3683-
if (not_clause(clause))
3683+
if (is_notclause(clause))
36843684
{
36853685
Node *arg = (Node *) get_notclausearg((Expr *) clause);
36863686

src/backend/optimizer/path/joinrels.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "postgres.h"
1616

1717
#include "miscadmin.h"
18+
#include "nodes/nodeFuncs.h"
1819
#include "optimizer/appendinfo.h"
1920
#include "optimizer/clauses.h"
2021
#include "optimizer/joininfo.h"
@@ -1554,8 +1555,7 @@ have_partkey_equi_join(RelOptInfo *joinrel,
15541555
if (!rinfo->mergeopfamilies && !OidIsValid(rinfo->hashjoinoperator))
15551556
continue;
15561557

1557-
opexpr = (OpExpr *) rinfo->clause;
1558-
Assert(is_opclause(opexpr));
1558+
opexpr = castNode(OpExpr, rinfo->clause);
15591559

15601560
/*
15611561
* The equi-join between partition keys is strict if equi-join between

src/backend/optimizer/path/tidpath.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ TidQualFromRestrictInfoList(List *rlist, RelOptInfo *rel)
250250
List *sublist;
251251

252252
/* OR arguments should be ANDs or sub-RestrictInfos */
253-
if (and_clause(orarg))
253+
if (is_andclause(orarg))
254254
{
255255
List *andargs = ((BoolExpr *) orarg)->args;
256256

0 commit comments

Comments
 (0)