diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-03-23 17:29:57 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-03-23 17:29:57 -0400 |
commit | 0339047bc93147c1c6f78f867ae6b0c215406235 (patch) | |
tree | 116a4cd10a9eb1b0b6beb4cf871bc126c504572a /src/backend/nodes/nodeFuncs.c | |
parent | e08b4101e1daa2f4e6644330918177a10cac0aab (diff) | |
download | postgresql-0339047bc93147c1c6f78f867ae6b0c215406235.tar.gz postgresql-0339047bc93147c1c6f78f867ae6b0c215406235.zip |
Code review for protransform patches.
Fix loss of previous expression-simplification work when a transform
function fires: we must not simply revert to untransformed input tree.
Instead build a dummy FuncExpr node to pass to the transform function.
This has the additional advantage of providing a simpler, more uniform
API for transform functions.
Move documentation to a somewhat less buried spot, relocate some
poorly-placed code, be more wary of null constants and invalid typmod
values, add an opr_sanity check on protransform function signatures,
and some other minor cosmetic adjustments.
Note: although this patch touches pg_proc.h, no need for catversion
bump, because the changes are cosmetic and don't actually change the
intended catalog contents.
Diffstat (limited to 'src/backend/nodes/nodeFuncs.c')
-rw-r--r-- | src/backend/nodes/nodeFuncs.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 51459c4a43f..6f9e0536694 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -17,6 +17,7 @@ #include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "nodes/relation.h" #include "utils/builtins.h" @@ -548,6 +549,30 @@ exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod) } /* + * relabel_to_typmod + * Add a RelabelType node that changes just the typmod of the expression. + * + * This is primarily intended to be used during planning. Therefore, it + * strips any existing RelabelType nodes to maintain the planner's invariant + * that there are not adjacent RelabelTypes, and it uses COERCE_DONTCARE + * which would typically be inappropriate earlier. + */ +Node * +relabel_to_typmod(Node *expr, int32 typmod) +{ + Oid type = exprType(expr); + Oid coll = exprCollation(expr); + + /* Strip any existing RelabelType node(s) */ + while (expr && IsA(expr, RelabelType)) + expr = (Node *) ((RelabelType *) expr)->arg; + + /* Apply new typmod, preserving the previous exposed type and collation */ + return (Node *) makeRelabelType((Expr *) expr, type, typmod, coll, + COERCE_DONTCARE); +} + +/* * expression_returns_set * Test whether an expression returns a set result. * @@ -2694,7 +2719,9 @@ query_or_expression_tree_mutator(Node *node, * that could appear under it, but not other statement types. */ bool - raw_expression_tree_walker(Node *node, bool (*walker) (), void *context) +raw_expression_tree_walker(Node *node, + bool (*walker) (), + void *context) { ListCell *temp; |