aboutsummaryrefslogtreecommitdiff
path: root/src/backend/nodes/nodeFuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-03-23 17:29:57 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-03-23 17:29:57 -0400
commit0339047bc93147c1c6f78f867ae6b0c215406235 (patch)
tree116a4cd10a9eb1b0b6beb4cf871bc126c504572a /src/backend/nodes/nodeFuncs.c
parente08b4101e1daa2f4e6644330918177a10cac0aab (diff)
downloadpostgresql-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.c29
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;