diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-06-29 00:33:44 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-06-29 00:33:44 +0000 |
commit | bee217924d51af8cf0411167bfc8a7eb55122577 (patch) | |
tree | ab6d3f311de5fd6b415e0bdf032205ed503ba95c /src/backend/optimizer/plan/setrefs.c | |
parent | df7618020b3845a51d1ba80cb9abfc6df5dfeaff (diff) |
Support expressions of the form 'scalar op ANY (array)' and
'scalar op ALL (array)', where the operator is applied between the
lefthand scalar and each element of the array. The operator must
yield boolean; the result of the construct is the OR or AND of the
per-element results, respectively.
Original coding by Joe Conway, after an idea of Peter's. Rewritten
by Tom to keep the implementation strictly separate from subqueries.
Diffstat (limited to 'src/backend/optimizer/plan/setrefs.c')
-rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 4e17a85eb4b..1da186e0aaa 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -9,20 +9,19 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.92 2003/02/16 02:30:38 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.93 2003/06/29 00:33:43 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" - #include "nodes/makefuncs.h" -#include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/planmain.h" #include "optimizer/tlist.h" #include "optimizer/var.h" #include "parser/parsetree.h" +#include "utils/lsyscache.h" typedef struct @@ -61,6 +60,8 @@ static Node *replace_vars_with_subplan_refs(Node *node, static Node *replace_vars_with_subplan_refs_mutator(Node *node, replace_vars_with_subplan_refs_context *context); static bool fix_opfuncids_walker(Node *node, void *context); +static void set_sa_opfuncid(ScalarArrayOpExpr *opexpr); + /***************************************************************************** * @@ -284,6 +285,8 @@ fix_expr_references_walker(Node *node, void *context) set_opfuncid((OpExpr *) node); else if (IsA(node, DistinctExpr)) set_opfuncid((OpExpr *) node); /* rely on struct equivalence */ + else if (IsA(node, ScalarArrayOpExpr)) + set_sa_opfuncid((ScalarArrayOpExpr *) node); else if (IsA(node, NullIfExpr)) set_opfuncid((OpExpr *) node); /* rely on struct equivalence */ else if (IsA(node, SubPlan)) @@ -738,7 +741,35 @@ fix_opfuncids_walker(Node *node, void *context) set_opfuncid((OpExpr *) node); else if (IsA(node, DistinctExpr)) set_opfuncid((OpExpr *) node); /* rely on struct equivalence */ + else if (IsA(node, ScalarArrayOpExpr)) + set_sa_opfuncid((ScalarArrayOpExpr *) node); else if (IsA(node, NullIfExpr)) set_opfuncid((OpExpr *) node); /* rely on struct equivalence */ return expression_tree_walker(node, fix_opfuncids_walker, context); } + +/* + * set_opfuncid + * Set the opfuncid (procedure OID) in an OpExpr node, + * if it hasn't been set already. + * + * Because of struct equivalence, this can also be used for + * DistinctExpr and NullIfExpr nodes. + */ +void +set_opfuncid(OpExpr *opexpr) +{ + if (opexpr->opfuncid == InvalidOid) + opexpr->opfuncid = get_opcode(opexpr->opno); +} + +/* + * set_sa_opfuncid + * As above, for ScalarArrayOpExpr nodes. + */ +static void +set_sa_opfuncid(ScalarArrayOpExpr *opexpr) +{ + if (opexpr->opfuncid == InvalidOid) + opexpr->opfuncid = get_opcode(opexpr->opno); +} |