0001-move-trivial-node-support.patch
text/x-diff
Filename: 0001-move-trivial-node-support.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
Series: patch 0001
| File | + | − |
|---|---|---|
| src/backend/commands/explain.c | 1 | 0 |
| src/backend/executor/nodeSubplan.c | 2 | 2 |
| src/backend/executor/nodeTidscan.c | 1 | 1 |
| src/backend/nodes/makefuncs.c | 135 | 0 |
| src/backend/nodes/print.c | 2 | 1 |
| src/backend/optimizer/path/clausesel.c | 4 | 3 |
| src/backend/optimizer/path/costsize.c | 1 | 0 |
| src/backend/optimizer/path/indxpath.c | 3 | 3 |
| src/backend/optimizer/path/joinrels.c | 2 | 2 |
| src/backend/optimizer/path/tidpath.c | 1 | 1 |
| src/backend/optimizer/plan/initsplan.c | 1 | 0 |
| src/backend/optimizer/plan/subselect.c | 5 | 5 |
| src/backend/optimizer/prep/prepjointree.c | 2 | 2 |
| src/backend/optimizer/prep/prepqual.c | 8 | 7 |
| src/backend/optimizer/util/clauses.c | 4 | 242 |
| src/backend/optimizer/util/orclauses.c | 5 | 3 |
| src/backend/optimizer/util/predtest.c | 3 | 2 |
| src/backend/optimizer/util/restrictinfo.c | 6 | 4 |
| src/backend/partitioning/partprune.c | 3 | 3 |
| src/backend/statistics/dependencies.c | 2 | 1 |
| src/backend/utils/cache/relcache.c | 1 | 0 |
| src/include/nodes/makefuncs.h | 12 | 0 |
| src/include/nodes/nodeFuncs.h | 72 | 0 |
| src/include/optimizer/clauses.h | 0 | 22 |
| src/test/modules/test_predtest/test_predtest.c | 1 | 0 |
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index ae7f038..5d859b7 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -22,6 +22,7 @@
#include "foreign/fdwapi.h"
#include "jit/jit.h"
#include "nodes/extensible.h"
+#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/planmain.h"
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index 574e7bc..1526960 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -33,8 +33,8 @@
#include "executor/executor.h"
#include "executor/nodeSubplan.h"
#include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
#include "miscadmin.h"
-#include "optimizer/clauses.h"
#include "utils/array.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -888,7 +888,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
/* single combining operator */
oplist = list_make1(subplan->testexpr);
}
- else if (and_clause((Node *) subplan->testexpr))
+ else if (is_andclause(subplan->testexpr))
{
/* multiple combining operators */
oplist = castNode(BoolExpr, subplan->testexpr)->args;
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index b7a8725..8daf09c 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -28,7 +28,7 @@
#include "executor/execdebug.h"
#include "executor/nodeTidscan.h"
#include "miscadmin.h"
-#include "optimizer/clauses.h"
+#include "nodes/nodeFuncs.h"
#include "storage/bufmgr.h"
#include "utils/array.h"
#include "utils/rel.h"
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 079d016..7085ed2 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -599,6 +599,141 @@ makeFuncCall(List *name, List *args, int location)
}
/*
+ * make_opclause
+ * Creates an operator clause given its operator info, left operand
+ * and right operand (pass NULL to create single-operand clause),
+ * and collation info.
+ */
+Expr *
+make_opclause(Oid opno, Oid opresulttype, bool opretset,
+ Expr *leftop, Expr *rightop,
+ Oid opcollid, Oid inputcollid)
+{
+ OpExpr *expr = makeNode(OpExpr);
+
+ expr->opno = opno;
+ expr->opfuncid = InvalidOid;
+ expr->opresulttype = opresulttype;
+ expr->opretset = opretset;
+ expr->opcollid = opcollid;
+ expr->inputcollid = inputcollid;
+ if (rightop)
+ expr->args = list_make2(leftop, rightop);
+ else
+ expr->args = list_make1(leftop);
+ expr->location = -1;
+ return (Expr *) expr;
+}
+
+/*
+ * make_andclause
+ *
+ * Creates an 'and' clause given a list of its subclauses.
+ */
+Expr *
+make_andclause(List *andclauses)
+{
+ BoolExpr *expr = makeNode(BoolExpr);
+
+ expr->boolop = AND_EXPR;
+ expr->args = andclauses;
+ expr->location = -1;
+ return (Expr *) expr;
+}
+
+/*
+ * make_orclause
+ *
+ * Creates an 'or' clause given a list of its subclauses.
+ */
+Expr *
+make_orclause(List *orclauses)
+{
+ BoolExpr *expr = makeNode(BoolExpr);
+
+ expr->boolop = OR_EXPR;
+ expr->args = orclauses;
+ expr->location = -1;
+ return (Expr *) expr;
+}
+
+/*
+ * make_notclause
+ *
+ * Create a 'not' clause given the expression to be negated.
+ */
+Expr *
+make_notclause(Expr *notclause)
+{
+ BoolExpr *expr = makeNode(BoolExpr);
+
+ expr->boolop = NOT_EXPR;
+ expr->args = list_make1(notclause);
+ expr->location = -1;
+ return (Expr *) expr;
+}
+
+/*
+ * make_and_qual
+ *
+ * Variant of make_andclause for ANDing two qual conditions together.
+ * Qual conditions have the property that a NULL nodetree is interpreted
+ * as 'true'.
+ *
+ * NB: this makes no attempt to preserve AND/OR flatness; so it should not
+ * be used on a qual that has already been run through prepqual.c.
+ */
+Node *
+make_and_qual(Node *qual1, Node *qual2)
+{
+ if (qual1 == NULL)
+ return qual2;
+ if (qual2 == NULL)
+ return qual1;
+ return (Node *) make_andclause(list_make2(qual1, qual2));
+}
+
+/*
+ * The planner and executor usually represent qualification expressions
+ * as lists of boolean expressions with implicit AND semantics.
+ *
+ * These functions convert between an AND-semantics expression list and the
+ * ordinary representation of a boolean expression.
+ *
+ * Note that an empty list is considered equivalent to TRUE.
+ */
+Expr *
+make_ands_explicit(List *andclauses)
+{
+ if (andclauses == NIL)
+ return (Expr *) makeBoolConst(true, false);
+ else if (list_length(andclauses) == 1)
+ return (Expr *) linitial(andclauses);
+ else
+ return make_andclause(andclauses);
+}
+
+List *
+make_ands_implicit(Expr *clause)
+{
+ /*
+ * NB: because the parser sets the qual field to NULL in a query that has
+ * no WHERE clause, we must consider a NULL input clause as TRUE, even
+ * though one might more reasonably think it FALSE.
+ */
+ if (clause == NULL)
+ return NIL; /* NULL -> NIL list == TRUE */
+ else if (is_andclause(clause))
+ return ((BoolExpr *) clause)->args;
+ else if (IsA(clause, Const) &&
+ !((Const *) clause)->constisnull &&
+ DatumGetBool(((Const *) clause)->constvalue))
+ return NIL; /* constant TRUE input -> NIL list */
+ else
+ return list_make1(clause);
+}
+
+/*
* makeGroupingSet
*
*/
diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c
index 0278108..c5b6a0b 100644
--- a/src/backend/nodes/print.c
+++ b/src/backend/nodes/print.c
@@ -21,8 +21,9 @@
#include "access/printtup.h"
#include "lib/stringinfo.h"
+#include "nodes/nodeFuncs.h"
#include "nodes/print.h"
-#include "optimizer/clauses.h"
+#include "nodes/relation.h"
#include "parser/parsetree.h"
#include "utils/lsyscache.h"
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index 3739b98..5045270 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -15,6 +15,7 @@
#include "postgres.h"
#include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
@@ -688,7 +689,7 @@ clause_selectivity(PlannerInfo *root,
/* XXX any way to do better than default? */
}
}
- else if (not_clause(clause))
+ else if (is_notclause(clause))
{
/* inverse of the selectivity of the underlying clause */
s1 = 1.0 - clause_selectivity(root,
@@ -697,7 +698,7 @@ clause_selectivity(PlannerInfo *root,
jointype,
sjinfo);
}
- else if (and_clause(clause))
+ else if (is_andclause(clause))
{
/* share code with clauselist_selectivity() */
s1 = clauselist_selectivity(root,
@@ -706,7 +707,7 @@ clause_selectivity(PlannerInfo *root,
jointype,
sjinfo);
}
- else if (or_clause(clause))
+ else if (is_orclause(clause))
{
/*
* Selectivities for an OR clause are computed as s1+s2 - s1*s2 to
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 99c5ad9..e288804 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -79,6 +79,7 @@
#include "executor/executor.h"
#include "executor/nodeHash.h"
#include "miscadmin.h"
+#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index f8e674c..be50d56 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -1297,7 +1297,7 @@ generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel,
List *indlist;
/* OR arguments should be ANDs or sub-RestrictInfos */
- if (and_clause(orarg))
+ if (is_andclause(orarg))
{
List *andargs = ((BoolExpr *) orarg)->args;
@@ -3368,7 +3368,7 @@ match_boolean_index_clause(Node *clause,
if (match_index_to_operand(clause, indexcol, index))
return true;
/* NOT clause? */
- if (not_clause(clause))
+ if (is_notclause(clause))
{
if (match_index_to_operand((Node *) get_notclausearg((Expr *) clause),
indexcol, index))
@@ -3680,7 +3680,7 @@ expand_boolean_index_clause(Node *clause,
InvalidOid, InvalidOid);
}
/* NOT clause? */
- if (not_clause(clause))
+ if (is_notclause(clause))
{
Node *arg = (Node *) get_notclausearg((Expr *) clause);
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 8bfe9c3..dfbbfda 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -15,6 +15,7 @@
#include "postgres.h"
#include "miscadmin.h"
+#include "nodes/nodeFuncs.h"
#include "optimizer/appendinfo.h"
#include "optimizer/clauses.h"
#include "optimizer/joininfo.h"
@@ -1554,8 +1555,7 @@ have_partkey_equi_join(RelOptInfo *joinrel,
if (!rinfo->mergeopfamilies && !OidIsValid(rinfo->hashjoinoperator))
continue;
- opexpr = (OpExpr *) rinfo->clause;
- Assert(is_opclause(opexpr));
+ opexpr = castNode(OpExpr, rinfo->clause);
/*
* The equi-join between partition keys is strict if equi-join between
diff --git a/src/backend/optimizer/path/tidpath.c b/src/backend/optimizer/path/tidpath.c
index 74b5a15..94c88bd 100644
--- a/src/backend/optimizer/path/tidpath.c
+++ b/src/backend/optimizer/path/tidpath.c
@@ -250,7 +250,7 @@ TidQualFromRestrictInfoList(List *rlist, RelOptInfo *rel)
List *sublist;
/* OR arguments should be ANDs or sub-RestrictInfos */
- if (and_clause(orarg))
+ if (is_andclause(orarg))
{
List *andargs = ((BoolExpr *) orarg)->args;
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index a663740..06ed32a 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -16,6 +16,7 @@
#include "catalog/pg_type.h"
#include "catalog/pg_class.h"
+#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 64272dd..da65d04 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -739,7 +739,7 @@ testexpr_is_hashable(Node *testexpr)
if (hash_ok_operator((OpExpr *) testexpr))
return true;
}
- else if (and_clause(testexpr))
+ else if (is_andclause(testexpr))
{
ListCell *l;
@@ -1694,7 +1694,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
* propagates down in both cases. (Note that this is unlike the meaning
* of "top level qual" used in most other places in Postgres.)
*/
- if (and_clause(node))
+ if (is_andclause(node))
{
List *newargs = NIL;
ListCell *l;
@@ -1707,7 +1707,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
Node *newarg;
newarg = process_sublinks_mutator(lfirst(l), &locContext);
- if (and_clause(newarg))
+ if (is_andclause(newarg))
newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
else
newargs = lappend(newargs, newarg);
@@ -1715,7 +1715,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
return (Node *) make_andclause(newargs);
}
- if (or_clause(node))
+ if (is_orclause(node))
{
List *newargs = NIL;
ListCell *l;
@@ -1728,7 +1728,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
Node *newarg;
newarg = process_sublinks_mutator(lfirst(l), &locContext);
- if (or_clause(newarg))
+ if (is_orclause(newarg))
newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
else
newargs = lappend(newargs, newarg);
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 77dbf4e..3bef60a 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -452,7 +452,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
/* Else return it unmodified */
return node;
}
- if (not_clause(node))
+ if (is_notclause(node))
{
/* If the immediate argument of NOT is EXISTS, try to convert */
SubLink *sublink = (SubLink *) get_notclausearg((Expr *) node);
@@ -519,7 +519,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
/* Else return it unmodified */
return node;
}
- if (and_clause(node))
+ if (is_andclause(node))
{
/* Recurse into AND clause */
List *newclauses = NIL;
diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c
index 234dc5b..2bd6c20 100644
--- a/src/backend/optimizer/prep/prepqual.c
+++ b/src/backend/optimizer/prep/prepqual.c
@@ -32,6 +32,7 @@
#include "postgres.h"
#include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/prep.h"
#include "utils/lsyscache.h"
@@ -333,7 +334,7 @@ pull_ands(List *andlist)
* built a new arglist not shared with any other expr. Otherwise we'd
* need a list_copy here.
*/
- if (and_clause(subexpr))
+ if (is_andclause(subexpr))
out_list = list_concat(out_list,
pull_ands(((BoolExpr *) subexpr)->args));
else
@@ -365,7 +366,7 @@ pull_ors(List *orlist)
* built a new arglist not shared with any other expr. Otherwise we'd
* need a list_copy here.
*/
- if (or_clause(subexpr))
+ if (is_orclause(subexpr))
out_list = list_concat(out_list,
pull_ors(((BoolExpr *) subexpr)->args));
else
@@ -415,7 +416,7 @@ pull_ors(List *orlist)
static Expr *
find_duplicate_ors(Expr *qual, bool is_check)
{
- if (or_clause((Node *) qual))
+ if (is_orclause(qual))
{
List *orlist = NIL;
ListCell *temp;
@@ -459,7 +460,7 @@ find_duplicate_ors(Expr *qual, bool is_check)
/* Now we can look for duplicate ORs */
return process_duplicate_ors(orlist);
}
- else if (and_clause((Node *) qual))
+ else if (is_andclause(qual))
{
List *andlist = NIL;
ListCell *temp;
@@ -550,7 +551,7 @@ process_duplicate_ors(List *orlist)
{
Expr *clause = (Expr *) lfirst(temp);
- if (and_clause((Node *) clause))
+ if (is_andclause(clause))
{
List *subclauses = ((BoolExpr *) clause)->args;
int nclauses = list_length(subclauses);
@@ -588,7 +589,7 @@ process_duplicate_ors(List *orlist)
{
Expr *clause = (Expr *) lfirst(temp2);
- if (and_clause((Node *) clause))
+ if (is_andclause(clause))
{
if (!list_member(((BoolExpr *) clause)->args, refclause))
{
@@ -631,7 +632,7 @@ process_duplicate_ors(List *orlist)
{
Expr *clause = (Expr *) lfirst(temp);
- if (and_clause((Node *) clause))
+ if (is_andclause(clause))
{
List *subclauses = ((BoolExpr *) clause)->args;
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 94b8fa0..816aa86 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -158,244 +158,6 @@ static bool tlist_matches_coltypelist(List *tlist, List *coltypelist);
/*****************************************************************************
- * OPERATOR clause functions
- *****************************************************************************/
-
-/*
- * make_opclause
- * Creates an operator clause given its operator info, left operand
- * and right operand (pass NULL to create single-operand clause),
- * and collation info.
- */
-Expr *
-make_opclause(Oid opno, Oid opresulttype, bool opretset,
- Expr *leftop, Expr *rightop,
- Oid opcollid, Oid inputcollid)
-{
- OpExpr *expr = makeNode(OpExpr);
-
- expr->opno = opno;
- expr->opfuncid = InvalidOid;
- expr->opresulttype = opresulttype;
- expr->opretset = opretset;
- expr->opcollid = opcollid;
- expr->inputcollid = inputcollid;
- if (rightop)
- expr->args = list_make2(leftop, rightop);
- else
- expr->args = list_make1(leftop);
- expr->location = -1;
- return (Expr *) expr;
-}
-
-/*
- * get_leftop
- *
- * Returns the left operand of a clause of the form (op expr expr)
- * or (op expr)
- */
-Node *
-get_leftop(const Expr *clause)
-{
- const OpExpr *expr = (const OpExpr *) clause;
-
- if (expr->args != NIL)
- return linitial(expr->args);
- else
- return NULL;
-}
-
-/*
- * get_rightop
- *
- * Returns the right operand in a clause of the form (op expr expr).
- * NB: result will be NULL if applied to a unary op clause.
- */
-Node *
-get_rightop(const Expr *clause)
-{
- const OpExpr *expr = (const OpExpr *) clause;
-
- if (list_length(expr->args) >= 2)
- return lsecond(expr->args);
- else
- return NULL;
-}
-
-/*****************************************************************************
- * NOT clause functions
- *****************************************************************************/
-
-/*
- * not_clause
- *
- * Returns t iff this is a 'not' clause: (NOT expr).
- */
-bool
-not_clause(Node *clause)
-{
- return (clause != NULL &&
- IsA(clause, BoolExpr) &&
- ((BoolExpr *) clause)->boolop == NOT_EXPR);
-}
-
-/*
- * make_notclause
- *
- * Create a 'not' clause given the expression to be negated.
- */
-Expr *
-make_notclause(Expr *notclause)
-{
- BoolExpr *expr = makeNode(BoolExpr);
-
- expr->boolop = NOT_EXPR;
- expr->args = list_make1(notclause);
- expr->location = -1;
- return (Expr *) expr;
-}
-
-/*
- * get_notclausearg
- *
- * Retrieve the clause within a 'not' clause
- */
-Expr *
-get_notclausearg(Expr *notclause)
-{
- return linitial(((BoolExpr *) notclause)->args);
-}
-
-/*****************************************************************************
- * OR clause functions
- *****************************************************************************/
-
-/*
- * or_clause
- *
- * Returns t iff the clause is an 'or' clause: (OR { expr }).
- */
-bool
-or_clause(Node *clause)
-{
- return (clause != NULL &&
- IsA(clause, BoolExpr) &&
- ((BoolExpr *) clause)->boolop == OR_EXPR);
-}
-
-/*
- * make_orclause
- *
- * Creates an 'or' clause given a list of its subclauses.
- */
-Expr *
-make_orclause(List *orclauses)
-{
- BoolExpr *expr = makeNode(BoolExpr);
-
- expr->boolop = OR_EXPR;
- expr->args = orclauses;
- expr->location = -1;
- return (Expr *) expr;
-}
-
-/*****************************************************************************
- * AND clause functions
- *****************************************************************************/
-
-
-/*
- * and_clause
- *
- * Returns t iff its argument is an 'and' clause: (AND { expr }).
- */
-bool
-and_clause(Node *clause)
-{
- return (clause != NULL &&
- IsA(clause, BoolExpr) &&
- ((BoolExpr *) clause)->boolop == AND_EXPR);
-}
-
-/*
- * make_andclause
- *
- * Creates an 'and' clause given a list of its subclauses.
- */
-Expr *
-make_andclause(List *andclauses)
-{
- BoolExpr *expr = makeNode(BoolExpr);
-
- expr->boolop = AND_EXPR;
- expr->args = andclauses;
- expr->location = -1;
- return (Expr *) expr;
-}
-
-/*
- * make_and_qual
- *
- * Variant of make_andclause for ANDing two qual conditions together.
- * Qual conditions have the property that a NULL nodetree is interpreted
- * as 'true'.
- *
- * NB: this makes no attempt to preserve AND/OR flatness; so it should not
- * be used on a qual that has already been run through prepqual.c.
- */
-Node *
-make_and_qual(Node *qual1, Node *qual2)
-{
- if (qual1 == NULL)
- return qual2;
- if (qual2 == NULL)
- return qual1;
- return (Node *) make_andclause(list_make2(qual1, qual2));
-}
-
-/*
- * The planner frequently prefers to represent qualification expressions
- * as lists of boolean expressions with implicit AND semantics.
- *
- * These functions convert between an AND-semantics expression list and the
- * ordinary representation of a boolean expression.
- *
- * Note that an empty list is considered equivalent to TRUE.
- */
-Expr *
-make_ands_explicit(List *andclauses)
-{
- if (andclauses == NIL)
- return (Expr *) makeBoolConst(true, false);
- else if (list_length(andclauses) == 1)
- return (Expr *) linitial(andclauses);
- else
- return make_andclause(andclauses);
-}
-
-List *
-make_ands_implicit(Expr *clause)
-{
- /*
- * NB: because the parser sets the qual field to NULL in a query that has
- * no WHERE clause, we must consider a NULL input clause as TRUE, even
- * though one might more reasonably think it FALSE. Grumble. If this
- * causes trouble, consider changing the parser's behavior.
- */
- if (clause == NULL)
- return NIL; /* NULL -> NIL list == TRUE */
- else if (and_clause((Node *) clause))
- return ((BoolExpr *) clause)->args;
- else if (IsA(clause, Const) &&
- !((Const *) clause)->constisnull &&
- DatumGetBool(((Const *) clause)->constvalue))
- return NIL; /* constant TRUE input -> NIL list */
- else
- return list_make1(clause);
-}
-
-
-/*****************************************************************************
* Aggregate-function clause manipulation
*****************************************************************************/
@@ -3962,7 +3724,7 @@ simplify_or_arguments(List *args,
unprocessed_args = list_delete_first(unprocessed_args);
/* flatten nested ORs as per above comment */
- if (or_clause(arg))
+ if (is_orclause(arg))
{
List *subargs = list_copy(((BoolExpr *) arg)->args);
@@ -3988,7 +3750,7 @@ simplify_or_arguments(List *args,
* since it's not a mainstream case. In particular we don't worry
* about const-simplifying the input twice.
*/
- if (or_clause(arg))
+ if (is_orclause(arg))
{
List *subargs = list_copy(((BoolExpr *) arg)->args);
@@ -4064,7 +3826,7 @@ simplify_and_arguments(List *args,
unprocessed_args = list_delete_first(unprocessed_args);
/* flatten nested ANDs as per above comment */
- if (and_clause(arg))
+ if (is_andclause(arg))
{
List *subargs = list_copy(((BoolExpr *) arg)->args);
@@ -4090,7 +3852,7 @@ simplify_and_arguments(List *args,
* since it's not a mainstream case. In particular we don't worry
* about const-simplifying the input twice.
*/
- if (and_clause(arg))
+ if (is_andclause(arg))
{
List *subargs = list_copy(((BoolExpr *) arg)->args);
diff --git a/src/backend/optimizer/util/orclauses.c b/src/backend/optimizer/util/orclauses.c
index 9420f13..c62ba88 100644
--- a/src/backend/optimizer/util/orclauses.c
+++ b/src/backend/optimizer/util/orclauses.c
@@ -15,6 +15,8 @@
#include "postgres.h"
+#include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/orclauses.h"
@@ -173,7 +175,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel)
* selectivity and other cached data is computed exactly the same way for
* a restriction clause as for a join clause, which seems undesirable.
*/
- Assert(or_clause((Node *) or_rinfo->orclause));
+ Assert(is_orclause(or_rinfo->orclause));
foreach(lc, ((BoolExpr *) or_rinfo->orclause)->args)
{
Node *orarg = (Node *) lfirst(lc);
@@ -181,7 +183,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel)
Node *subclause;
/* OR arguments should be ANDs or sub-RestrictInfos */
- if (and_clause(orarg))
+ if (is_andclause(orarg))
{
List *andargs = ((BoolExpr *) orarg)->args;
ListCell *lc2;
@@ -231,7 +233,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel)
* to preserve AND/OR flatness (ie, no OR directly underneath OR).
*/
subclause = (Node *) make_ands_explicit(subclauses);
- if (or_clause(subclause))
+ if (is_orclause(subclause))
clauselist = list_concat(clauselist,
list_copy(((BoolExpr *) subclause)->args));
else
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index 3d5ef69..ecbb0db 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -19,6 +19,7 @@
#include "catalog/pg_type.h"
#include "executor/executor.h"
#include "miscadmin.h"
+#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/predtest.h"
@@ -839,14 +840,14 @@ predicate_classify(Node *clause, PredIterInfo info)
}
/* Handle normal AND and OR boolean clauses */
- if (and_clause(clause))
+ if (is_andclause(clause))
{
info->startup_fn = boolexpr_startup_fn;
info->next_fn = list_next_fn;
info->cleanup_fn = list_cleanup_fn;
return CLASS_AND;
}
- if (or_clause(clause))
+ if (is_orclause(clause))
{
info->startup_fn = boolexpr_startup_fn;
info->next_fn = list_next_fn;
diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c
index e633881..c1bda81 100644
--- a/src/backend/optimizer/util/restrictinfo.c
+++ b/src/backend/optimizer/util/restrictinfo.c
@@ -14,6 +14,8 @@
*/
#include "postgres.h"
+#include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/restrictinfo.h"
#include "optimizer/var.h"
@@ -67,7 +69,7 @@ make_restrictinfo(Expr *clause,
* If it's an OR clause, build a modified copy with RestrictInfos inserted
* above each subclause of the top-level AND/OR structure.
*/
- if (or_clause((Node *) clause))
+ if (is_orclause(clause))
return (RestrictInfo *) make_sub_restrictinfos(clause,
is_pushed_down,
outerjoin_delayed,
@@ -78,7 +80,7 @@ make_restrictinfo(Expr *clause,
nullable_relids);
/* Shouldn't be an AND clause, else AND/OR flattening messed up */
- Assert(!and_clause((Node *) clause));
+ Assert(!is_andclause(clause));
return make_restrictinfo_internal(clause,
NULL,
@@ -232,7 +234,7 @@ make_sub_restrictinfos(Expr *clause,
Relids outer_relids,
Relids nullable_relids)
{
- if (or_clause((Node *) clause))
+ if (is_orclause(clause))
{
List *orlist = NIL;
ListCell *temp;
@@ -257,7 +259,7 @@ make_sub_restrictinfos(Expr *clause,
outer_relids,
nullable_relids);
}
- else if (and_clause((Node *) clause))
+ else if (is_andclause(clause))
{
List *andlist = NIL;
ListCell *temp;
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index 901433c..f5155fe 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -775,7 +775,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context,
* independently, collect their step IDs to be stored in the
* combine step we'll be creating.
*/
- if (or_clause((Node *) clause))
+ if (is_orclause(clause))
{
List *arg_stepids = NIL;
bool all_args_contradictory = true;
@@ -865,7 +865,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context,
}
continue;
}
- else if (and_clause((Node *) clause))
+ else if (is_andclause(clause))
{
List *args = ((BoolExpr *) clause)->args;
List *argsteps,
@@ -3262,7 +3262,7 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
}
else
{
- bool is_not_clause = not_clause((Node *) clause);
+ bool is_not_clause = is_notclause(clause);
leftop = is_not_clause ? get_notclausearg(clause) : clause;
diff --git a/src/backend/statistics/dependencies.c b/src/backend/statistics/dependencies.c
index 1d7e028..a8e9f72 100644
--- a/src/backend/statistics/dependencies.c
+++ b/src/backend/statistics/dependencies.c
@@ -18,6 +18,7 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_statistic_ext.h"
#include "lib/stringinfo.h"
+#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/var.h"
@@ -802,7 +803,7 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum)
/* OK to proceed with checking "var" */
}
- else if (not_clause((Node *) rinfo->clause))
+ else if (is_notclause(rinfo->clause))
{
/*
* "NOT x" can be interpreted as "x = false", so get the argument and
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index bcf4f10..12bba1b 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -69,6 +69,7 @@
#include "commands/policy.h"
#include "commands/trigger.h"
#include "miscadmin.h"
+#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/prep.h"
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index 5b5aa2d..aa25fab 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -80,6 +80,18 @@ extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype, List *args,
extern FuncCall *makeFuncCall(List *name, List *args, int location);
+extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset,
+ Expr *leftop, Expr *rightop,
+ Oid opcollid, Oid inputcollid);
+
+extern Expr *make_andclause(List *andclauses);
+extern Expr *make_orclause(List *orclauses);
+extern Expr *make_notclause(Expr *notclause);
+
+extern Node *make_and_qual(Node *qual1, Node *qual2);
+extern Expr *make_ands_explicit(List *andclauses);
+extern List *make_ands_implicit(Expr *clause);
+
extern DefElem *makeDefElem(char *name, Node *arg, int location);
extern DefElem *makeDefElemExtended(char *nameSpace, char *name, Node *arg,
DefElemAction defaction, int location);
diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h
index a9f76bb..9875934 100644
--- a/src/include/nodes/nodeFuncs.h
+++ b/src/include/nodes/nodeFuncs.h
@@ -50,6 +50,78 @@ extern void fix_opfuncids(Node *node);
extern void set_opfuncid(OpExpr *opexpr);
extern void set_sa_opfuncid(ScalarArrayOpExpr *opexpr);
+/* Is clause a FuncExpr clause? */
+static inline bool
+is_funcclause(const void *clause)
+{
+ return clause != NULL && IsA(clause, FuncExpr);
+}
+
+/* Is clause an OpExpr clause? */
+static inline bool
+is_opclause(const void *clause)
+{
+ return clause != NULL && IsA(clause, OpExpr);
+}
+
+/* Extract left arg of a binary opclause, or only arg of a unary opclause */
+static inline Node *
+get_leftop(const void *clause)
+{
+ const OpExpr *expr = (const OpExpr *) clause;
+
+ if (expr->args != NIL)
+ return (Node *) linitial(expr->args);
+ else
+ return NULL;
+}
+
+/* Extract right arg of a binary opclause (NULL if it's a unary opclause) */
+static inline Node *
+get_rightop(const void *clause)
+{
+ const OpExpr *expr = (const OpExpr *) clause;
+
+ if (list_length(expr->args) >= 2)
+ return (Node *) lsecond(expr->args);
+ else
+ return NULL;
+}
+
+/* Is clause an AND clause? */
+static inline bool
+is_andclause(const void *clause)
+{
+ return (clause != NULL &&
+ IsA(clause, BoolExpr) &&
+ ((const BoolExpr *) clause)->boolop == AND_EXPR);
+}
+
+/* Is clause an OR clause? */
+static inline bool
+is_orclause(const void *clause)
+{
+ return (clause != NULL &&
+ IsA(clause, BoolExpr) &&
+ ((const BoolExpr *) clause)->boolop == OR_EXPR);
+}
+
+/* Is clause a NOT clause? */
+static inline bool
+is_notclause(const void *clause)
+{
+ return (clause != NULL &&
+ IsA(clause, BoolExpr) &&
+ ((const BoolExpr *) clause)->boolop == NOT_EXPR);
+}
+
+/* Extract argument from a clause known to be a NOT clause */
+static inline Expr *
+get_notclausearg(const void *notclause)
+{
+ return (Expr *) linitial(((const BoolExpr *) notclause)->args);
+}
+
extern bool check_functions_in_node(Node *node, check_function_callback checker,
void *context);
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 6891d0d..3f53428 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -17,9 +17,6 @@
#include "access/htup.h"
#include "nodes/relation.h"
-#define is_opclause(clause) ((clause) != NULL && IsA(clause, OpExpr))
-#define is_funcclause(clause) ((clause) != NULL && IsA(clause, FuncExpr))
-
typedef struct
{
int numWindowFuncs; /* total number of WindowFuncs found */
@@ -27,25 +24,6 @@ typedef struct
List **windowFuncs; /* lists of WindowFuncs for each winref */
} WindowFuncLists;
-extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset,
- Expr *leftop, Expr *rightop,
- Oid opcollid, Oid inputcollid);
-extern Node *get_leftop(const Expr *clause);
-extern Node *get_rightop(const Expr *clause);
-
-extern bool not_clause(Node *clause);
-extern Expr *make_notclause(Expr *notclause);
-extern Expr *get_notclausearg(Expr *notclause);
-
-extern bool or_clause(Node *clause);
-extern Expr *make_orclause(List *orclauses);
-
-extern bool and_clause(Node *clause);
-extern Expr *make_andclause(List *andclauses);
-extern Node *make_and_qual(Node *qual1, Node *qual2);
-extern Expr *make_ands_explicit(List *andclauses);
-extern List *make_ands_implicit(Expr *clause);
-
extern bool contain_agg_clause(Node *clause);
extern void get_agg_clause_costs(PlannerInfo *root, Node *clause,
AggSplit aggsplit, AggClauseCosts *costs);
diff --git a/src/test/modules/test_predtest/test_predtest.c b/src/test/modules/test_predtest/test_predtest.c
index 6c9ed9d..c03748c 100644
--- a/src/test/modules/test_predtest/test_predtest.c
+++ b/src/test/modules/test_predtest/test_predtest.c
@@ -17,6 +17,7 @@
#include "catalog/pg_type.h"
#include "executor/spi.h"
#include "funcapi.h"
+#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/predtest.h"
#include "utils/builtins.h"