From 2deef968f4dac488549d1e0b827e4abb2c524363 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun, 18 Apr 1999 17:35:51 +0000
Subject: [PATCH] After transforming a CASE expr with a default argument,
 delete the default argument from the node.  This prevents the executor from
 spitting up on the untransformed argument expression.  Typical failure was:
 select (case f1 when 'val' then 'subst' else f1 end) from t1; ERROR: 
 copyObject: don't know how to copy 704

---
 src/backend/parser/parse_expr.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 6de507bae04..d23d7214a34 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.40 1999/02/03 21:16:57 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.41 1999/04/18 17:35:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -345,9 +345,9 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 				foreach(args, c->args)
 				{
 					w = lfirst(args);
-					/* shorthand form was specified, so expand... */
 					if (c->arg != NULL)
 					{
+						/* shorthand form was specified, so expand... */
 						A_Expr *a = makeNode(A_Expr);
 						a->oper = OP;
 						a->opname = "=";
@@ -358,6 +358,13 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 					lfirst(args) = transformExpr(pstate, (Node *) w, precedence);
 				}
 
+				/* It's not shorthand anymore, so drop the implicit argument.
+				 * This is necessary to keep the executor from seeing an
+				 * untransformed expression...
+				 */
+				c->arg = NULL;
+
+				/* transform the default clause */
 				if (c->defresult == NULL)
 				{
 					A_Const *n = makeNode(A_Const);
@@ -365,9 +372,9 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 					c->defresult = (Node *)n;
 				}
 				c->defresult = transformExpr(pstate, (Node *) c->defresult, precedence);
-				c->casetype = exprType(c->defresult);
 
 				/* now check types across result clauses... */
+				c->casetype = exprType(c->defresult);
 				ptype = c->casetype;
 				pcategory = TypeCategory(ptype);
 				foreach(args, c->args)
-- 
GitLab