/* Target type when converting whole-row vars */
Oid to_rowtype;
bool *found_whole_row; /* output flag */
+ bool coerced_var; /* var is under ConvertRowTypeExpr */
} map_variable_attnos_context;
static Node *
/* Don't convert unless necessary. */
if (context->to_rowtype != var->vartype)
{
- ConvertRowtypeExpr *r;
-
/* Var itself is converted to the requested type. */
newvar->vartype = context->to_rowtype;
/*
- * And a conversion node on top to convert back to the
- * original type.
+ * If this var is already under a ConvertRowtypeExpr,
+ * we don't have to add another one.
*/
- r = makeNode(ConvertRowtypeExpr);
- r->arg = (Expr *) newvar;
- r->resulttype = var->vartype;
- r->convertformat = COERCE_IMPLICIT_CAST;
- r->location = -1;
-
- return (Node *) r;
+ if (!context->coerced_var)
+ {
+ ConvertRowtypeExpr *r;
+
+ /*
+ * And a conversion node on top to convert back to
+ * the original type.
+ */
+ r = makeNode(ConvertRowtypeExpr);
+ r->arg = (Expr *) newvar;
+ r->resulttype = var->vartype;
+ r->convertformat = COERCE_IMPLICIT_CAST;
+ r->location = -1;
+
+ return (Node *) r;
+ }
}
}
}
}
/* otherwise fall through to copy the var normally */
}
+ else if (IsA(node, ConvertRowtypeExpr))
+ {
+ ConvertRowtypeExpr *r = (ConvertRowtypeExpr *) node;
+
+ /*
+ * If this is coercing a var (which is typical), convert only the var,
+ * as against adding another ConvertRowtypeExpr over it.
+ */
+ if (IsA(r->arg, Var))
+ {
+ ConvertRowtypeExpr *newnode;
+
+ newnode = (ConvertRowtypeExpr *) palloc(sizeof(ConvertRowtypeExpr));
+ *newnode = *r;
+ context->coerced_var = true;
+ newnode->arg = (Expr *) map_variable_attnos_mutator((Node *) r->arg, context);
+ context->coerced_var = false;
+
+ return (Node *) newnode;
+ }
+ /* Else fall through the expression tree mutator */
+ }
else if (IsA(node, Query))
{
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
context.map_length = map_length;
context.to_rowtype = to_rowtype;
context.found_whole_row = found_whole_row;
+ context.coerced_var = false;
*found_whole_row = false;