From 1b81fd7793285d5651f5070b9b4161e10ade7846 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 24 Aug 1999 00:09:56 +0000
Subject: [PATCH] coerce_type() failed to guard against trying to convert a
 NULL constant to a different type.  Not sure that this could happen in
 ordinary parser usage, but it can in some new code I'm working on...

---
 src/backend/parser/parse_coerce.c | 34 +++++++++++++++----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 026c66168b..297337da4d 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.22 1999/08/05 02:33:53 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.23 1999/08/24 00:09:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -60,24 +60,24 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId,
 		 * whereas float-to-int type conversion will round to integer.
 		 */
 		Const	   *con = (Const *) node;
+		Const	   *newcon = makeNode(Const);
 		Type		targetType = typeidType(targetTypeId);
-		char	   *val;
 
-		/* We know the source constant is really of type 'text' */
-		val = textout((text *) con->constvalue);
+		newcon->consttype = targetTypeId;
+		newcon->constlen = typeLen(targetType);
+		newcon->constbyval = typeByVal(targetType);
+		newcon->constisnull = con->constisnull;
+		newcon->constisset = false;
 
-		/* now make a new const node */
-		con = makeNode(Const);
-		con->consttype = targetTypeId;
-		con->constlen = typeLen(targetType);
-		con->constvalue = stringTypeDatum(targetType, val, atttypmod);
-		con->constisnull = false;
-		con->constbyval = typeByVal(targetType);
-		con->constisset = false;
+		if (! con->constisnull)
+		{
+			/* We know the source constant is really of type 'text' */
+			char	   *val = textout((text *) con->constvalue);
+			newcon->constvalue = stringTypeDatum(targetType, val, atttypmod);
+			pfree(val);
+		}
 
-		pfree(val);
-
-		result = (Node *) con;
+		result = (Node *) newcon;
 	}
 	else
 	{
@@ -105,7 +105,7 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId,
 		 * such as coercing text 'now' to datetime?  Need a way to
 		 * know whether type conversion function is cacheable...
 		 */
-		if (IsA(node, Const))
+		if (IsA(node, Const) && ! ((Const *) node)->constisnull)
 		{
 			Const	   *con = (Const *) node;
 			Oid			convertFuncid;
@@ -122,9 +122,9 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId,
 			con = makeNode(Const);
 			con->consttype = targetTypeId;
 			con->constlen = typeLen(targetType);
+			con->constbyval = typeByVal(targetType);
 			con->constvalue = val;
 			con->constisnull = false;
-			con->constbyval = typeByVal(targetType);
 			con->constisset = false;
 
 			result = (Node *) con;