diff options
Diffstat (limited to 'src/backend/nodes/makefuncs.c')
| -rw-r--r-- | src/backend/nodes/makefuncs.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 079d0160a8b..7085ed2c4c8 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 * */ |
