diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index e14d7bcc1319c1585b7509b89e7fc5752004ce6d..d5ff246c7bd4059ccd67656d2faa618262c7f2c1 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -917,7 +917,7 @@ typedef struct NUMProc
 				num_count,		/* number of write digits	*/
 				num_in,			/* is inside number		*/
 				num_curr,		/* current position in number	*/
-				num_pre,		/* space before first number	*/
+				out_pre_spaces,	/* spaces before first digit	*/
 
 				read_dec,		/* to_number - was read dec. point	*/
 				read_post,		/* to_number - number of dec. digit */
@@ -975,10 +975,11 @@ static FormatNode *NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *should
 static char *int_to_roman(int number);
 static void NUM_prepare_locale(NUMProc *Np);
 static char *get_last_relevant_decnum(char *num);
-static void NUM_numpart_from_char(NUMProc *Np, int id, int plen);
+static void NUM_numpart_from_char(NUMProc *Np, int id, int input_len);
 static void NUM_numpart_to_char(NUMProc *Np, int id);
-static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
-			  int plen, int sign, bool is_to_char, Oid collid);
+static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
+			  char *number, int from_char_input_len, int to_char_out_pre_spaces,
+			  int sign, bool is_to_char, Oid collid);
 static DCHCacheEntry *DCH_cache_search(char *str);
 static DCHCacheEntry *DCH_cache_getnew(char *str);
 
@@ -4054,7 +4055,7 @@ get_last_relevant_decnum(char *num)
  * ----------
  */
 static void
-NUM_numpart_from_char(NUMProc *Np, int id, int plen)
+NUM_numpart_from_char(NUMProc *Np, int id, int input_len)
 {
 	bool		isread = FALSE;
 
@@ -4066,8 +4067,8 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen)
 	if (*Np->inout_p == ' ')
 		Np->inout_p++;
 
-#define OVERLOAD_TEST	(Np->inout_p >= Np->inout + plen)
-#define AMOUNT_TEST(_s) (plen-(Np->inout_p-Np->inout) >= _s)
+#define OVERLOAD_TEST	(Np->inout_p >= Np->inout + input_len)
+#define AMOUNT_TEST(_s) (input_len-(Np->inout_p-Np->inout) >= _s)
 
 	if (*Np->inout_p == ' ')
 		Np->inout_p++;
@@ -4206,7 +4207,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen)
 		 * next char is not digit
 		 */
 		if (IS_LSIGN(Np->Num) && isread &&
-			(Np->inout_p + 1) <= Np->inout + plen &&
+			(Np->inout_p + 1) <= Np->inout + input_len &&
 			!isdigit((unsigned char) *(Np->inout_p + 1)))
 		{
 			int			x;
@@ -4301,7 +4302,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
 	 * handle "9.9" --> " .1"
 	 */
 	if (Np->sign_wrote == FALSE &&
-		(Np->num_curr >= Np->num_pre || (IS_ZERO(Np->Num) && Np->Num->zero_start == Np->num_curr)) &&
+		(Np->num_curr >= Np->out_pre_spaces || (IS_ZERO(Np->Num) && Np->Num->zero_start == Np->num_curr)) &&
 		(IS_PREDEC_SPACE(Np) == FALSE || (Np->last_relevant && *Np->last_relevant == '.')))
 	{
 		if (IS_LSIGN(Np->Num))
@@ -4345,7 +4346,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
 	 */
 	if (id == NUM_9 || id == NUM_0 || id == NUM_D || id == NUM_DEC)
 	{
-		if (Np->num_curr < Np->num_pre &&
+		if (Np->num_curr < Np->out_pre_spaces &&
 			(Np->Num->zero_start > Np->num_curr || !IS_ZERO(Np->Num)))
 		{
 			/*
@@ -4358,7 +4359,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
 			}
 		}
 		else if (IS_ZERO(Np->Num) &&
-				 Np->num_curr < Np->num_pre &&
+				 Np->num_curr < Np->out_pre_spaces &&
 				 Np->Num->zero_start <= Np->num_curr)
 		{
 			/*
@@ -4430,7 +4431,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
 			++Np->number_p;
 		}
 
-		end = Np->num_count + (Np->num_pre ? 1 : 0) + (IS_DECIMAL(Np->Num) ? 1 : 0);
+		end = Np->num_count + (Np->out_pre_spaces ? 1 : 0) + (IS_DECIMAL(Np->Num) ? 1 : 0);
 
 		if (Np->last_relevant && Np->last_relevant == Np->number_p)
 			end = Np->num_curr;
@@ -4456,13 +4457,10 @@ NUM_numpart_to_char(NUMProc *Np, int id)
 	++Np->num_curr;
 }
 
-/*
- * Note: 'plen' is used in FROM_CHAR conversion and it's length of
- * input (inout). In TO_CHAR conversion it's space before first number.
- */
 static char *
-NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
-			  int plen, int sign, bool is_to_char, Oid collid)
+NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
+			  char *number, int from_char_input_len, int to_char_out_pre_spaces,
+			  int sign, bool is_to_char, Oid collid)
 {
 	FormatNode *n;
 	NUMProc		_Np,
@@ -4502,7 +4500,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
 					 errmsg("\"RN\" not supported for input")));
 
 		Np->Num->lsign = Np->Num->pre_lsign_num = Np->Num->post =
-			Np->Num->pre = Np->num_pre = Np->sign = 0;
+			Np->Num->pre = Np->out_pre_spaces = Np->sign = 0;
 
 		if (IS_FILLMODE(Np->Num))
 		{
@@ -4560,7 +4558,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
 
 	if (is_to_char)
 	{
-		Np->num_pre = plen;
+		Np->out_pre_spaces = to_char_out_pre_spaces;
 
 		if (IS_FILLMODE(Np->Num) && IS_DECIMAL(Np->Num))
 		{
@@ -4570,22 +4568,22 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
 			 * If any '0' specifiers are present, make sure we don't strip
 			 * those digits.
 			 */
-			if (Np->last_relevant && Np->Num->zero_end > Np->num_pre)
+			if (Np->last_relevant && Np->Num->zero_end > Np->out_pre_spaces)
 			{
 				char	   *last_zero;
 
-				last_zero = Np->number + (Np->Num->zero_end - Np->num_pre);
+				last_zero = Np->number + (Np->Num->zero_end - Np->out_pre_spaces);
 				if (Np->last_relevant < last_zero)
 					Np->last_relevant = last_zero;
 			}
 		}
 
-		if (Np->sign_wrote == FALSE && Np->num_pre == 0)
+		if (Np->sign_wrote == FALSE && Np->out_pre_spaces == 0)
 			++Np->num_count;
 	}
 	else
 	{
-		Np->num_pre = 0;
+		Np->out_pre_spaces = 0;
 		*Np->number = ' ';		/* sign space */
 		*(Np->number + 1) = '\0';
 	}
@@ -4601,7 +4599,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
 		 Np->Num->pre,
 		 Np->Num->post,
 		 Np->num_count,
-		 Np->num_pre,
+		 Np->out_pre_spaces,
 		 Np->sign_wrote ? "Yes" : "No",
 		 IS_ZERO(Np->Num) ? "Yes" : "No",
 		 Np->Num->zero_start,
@@ -4636,7 +4634,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
 			/*
 			 * Check non-string inout end
 			 */
-			if (Np->inout_p >= Np->inout + plen)
+			if (Np->inout_p >= Np->inout + from_char_input_len)
 				break;
 		}
 
@@ -4666,7 +4664,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
 					}
 					else
 					{
-						NUM_numpart_from_char(Np, n->key->id, plen);
+						NUM_numpart_from_char(Np, n->key->id, from_char_input_len);
 						break;	/* switch() case: */
 					}
 
@@ -4891,7 +4889,7 @@ do { \
 do { \
 	int		len; \
 									\
-	NUM_processor(format, &Num, VARDATA(result), numstr, plen, sign, true, PG_GET_COLLATION()); \
+	NUM_processor(format, &Num, VARDATA(result), numstr, 0, out_pre_spaces, sign, true, PG_GET_COLLATION()); \
 									\
 	if (shouldFree)					\
 		pfree(format);				\
@@ -4933,7 +4931,7 @@ numeric_to_number(PG_FUNCTION_ARGS)
 	numstr = (char *) palloc((len * NUM_MAX_ITEM_SIZ) + 1);
 
 	NUM_processor(format, &Num, VARDATA(value), numstr,
-				  VARSIZE(value) - VARHDRSZ, 0, false, PG_GET_COLLATION());
+				  VARSIZE(value) - VARHDRSZ, 0, 0, false, PG_GET_COLLATION());
 
 	scale = Num.post;
 	precision = Max(0, Num.pre) + scale;
@@ -4962,7 +4960,7 @@ numeric_to_char(PG_FUNCTION_ARGS)
 	FormatNode *format;
 	text	   *result;
 	bool		shouldFree;
-	int			plen = 0,
+	int			out_pre_spaces = 0,
 				sign = 0;
 	char	   *numstr,
 			   *orgnum,
@@ -5016,7 +5014,7 @@ numeric_to_char(PG_FUNCTION_ARGS)
 	}
 	else
 	{
-		int			len;
+		int			numstr_pre_len;
 		Numeric		val = value;
 
 		if (IS_MULTI(&Num))
@@ -5051,14 +5049,17 @@ numeric_to_char(PG_FUNCTION_ARGS)
 			sign = '+';
 			numstr = orgnum;
 		}
+
 		if ((p = strchr(numstr, '.')))
-			len = p - numstr;
+			numstr_pre_len = p - numstr;
 		else
-			len = strlen(numstr);
+			numstr_pre_len = strlen(numstr);
 
-		if (Num.pre > len)
-			plen = Num.pre - len;
-		else if (len > Num.pre)
+		/* needs padding? */
+		if (numstr_pre_len < Num.pre)
+			out_pre_spaces = Num.pre - numstr_pre_len;
+		/* overflowed prefix digit format? */
+		else if (numstr_pre_len > Num.pre)
 		{
 			numstr = (char *) palloc(Num.pre + Num.post + 2);
 			fill_str(numstr, '#', Num.pre + Num.post + 1);
@@ -5083,7 +5084,7 @@ int4_to_char(PG_FUNCTION_ARGS)
 	FormatNode *format;
 	text	   *result;
 	bool		shouldFree;
-	int			plen = 0,
+	int			out_pre_spaces = 0,
 				sign = 0;
 	char	   *numstr,
 			   *orgnum;
@@ -5113,7 +5114,7 @@ int4_to_char(PG_FUNCTION_ARGS)
 	}
 	else
 	{
-		int			len;
+		int			numstr_pre_len;
 
 		if (IS_MULTI(&Num))
 		{
@@ -5134,22 +5135,26 @@ int4_to_char(PG_FUNCTION_ARGS)
 		}
 		else
 			sign = '+';
-		len = strlen(orgnum);
 
+		numstr_pre_len = strlen(orgnum);
+
+		/* post-decimal digits?  Pad out with zeros. */
 		if (Num.post)
 		{
-			numstr = (char *) palloc(len + Num.post + 2);
+			numstr = (char *) palloc(numstr_pre_len + Num.post + 2);
 			strcpy(numstr, orgnum);
-			*(numstr + len) = '.';
-			memset(numstr + len + 1, '0', Num.post);
-			*(numstr + len + Num.post + 1) = '\0';
+			*(numstr + numstr_pre_len) = '.';
+			memset(numstr + numstr_pre_len + 1, '0', Num.post);
+			*(numstr + numstr_pre_len + Num.post + 1) = '\0';
 		}
 		else
 			numstr = orgnum;
 
-		if (Num.pre > len)
-			plen = Num.pre - len;
-		else if (len > Num.pre)
+		/* needs padding? */
+		if (numstr_pre_len < Num.pre)
+			out_pre_spaces = Num.pre - numstr_pre_len;
+		/* overflowed prefix digit format? */
+		else if (numstr_pre_len > Num.pre)
 		{
 			numstr = (char *) palloc(Num.pre + Num.post + 2);
 			fill_str(numstr, '#', Num.pre + Num.post + 1);
@@ -5174,7 +5179,7 @@ int8_to_char(PG_FUNCTION_ARGS)
 	FormatNode *format;
 	text	   *result;
 	bool		shouldFree;
-	int			plen = 0,
+	int			out_pre_spaces = 0,
 				sign = 0;
 	char	   *numstr,
 			   *orgnum;
@@ -5217,7 +5222,7 @@ int8_to_char(PG_FUNCTION_ARGS)
 	}
 	else
 	{
-		int			len;
+		int			numstr_pre_len;
 
 		if (IS_MULTI(&Num))
 		{
@@ -5240,22 +5245,26 @@ int8_to_char(PG_FUNCTION_ARGS)
 		}
 		else
 			sign = '+';
-		len = strlen(orgnum);
 
+		numstr_pre_len = strlen(orgnum);
+
+		/* post-decimal digits?  Pad out with zeros. */
 		if (Num.post)
 		{
-			numstr = (char *) palloc(len + Num.post + 2);
+			numstr = (char *) palloc(numstr_pre_len + Num.post + 2);
 			strcpy(numstr, orgnum);
-			*(numstr + len) = '.';
-			memset(numstr + len + 1, '0', Num.post);
-			*(numstr + len + Num.post + 1) = '\0';
+			*(numstr + numstr_pre_len) = '.';
+			memset(numstr + numstr_pre_len + 1, '0', Num.post);
+			*(numstr + numstr_pre_len + Num.post + 1) = '\0';
 		}
 		else
 			numstr = orgnum;
 
-		if (Num.pre > len)
-			plen = Num.pre - len;
-		else if (len > Num.pre)
+		/* needs padding? */
+		if (numstr_pre_len < Num.pre)
+			out_pre_spaces = Num.pre - numstr_pre_len;
+		/* overflowed prefix digit format? */
+		else if (numstr_pre_len > Num.pre)
 		{
 			numstr = (char *) palloc(Num.pre + Num.post + 2);
 			fill_str(numstr, '#', Num.pre + Num.post + 1);
@@ -5280,7 +5289,7 @@ float4_to_char(PG_FUNCTION_ARGS)
 	FormatNode *format;
 	text	   *result;
 	bool		shouldFree;
-	int			plen = 0,
+	int			out_pre_spaces = 0,
 				sign = 0;
 	char	   *numstr,
 			   *orgnum,
@@ -5320,7 +5329,7 @@ float4_to_char(PG_FUNCTION_ARGS)
 	else
 	{
 		float4		val = value;
-		int			len;
+		int			numstr_pre_len;
 
 		if (IS_MULTI(&Num))
 		{
@@ -5332,13 +5341,13 @@ float4_to_char(PG_FUNCTION_ARGS)
 
 		orgnum = (char *) palloc(MAXFLOATWIDTH + 1);
 		snprintf(orgnum, MAXFLOATWIDTH + 1, "%.0f", fabs(val));
-		len = strlen(orgnum);
-		if (Num.pre > len)
-			plen = Num.pre - len;
-		if (len >= FLT_DIG)
+		numstr_pre_len = strlen(orgnum);
+
+		/* adjust post digits to fit max float digits */
+		if (numstr_pre_len >= FLT_DIG)
 			Num.post = 0;
-		else if (Num.post + len > FLT_DIG)
-			Num.post = FLT_DIG - len;
+		else if (numstr_pre_len + Num.post > FLT_DIG)
+			Num.post = FLT_DIG - numstr_pre_len;
 		snprintf(orgnum, MAXFLOATWIDTH + 1, "%.*f", Num.post, val);
 
 		if (*orgnum == '-')
@@ -5351,14 +5360,17 @@ float4_to_char(PG_FUNCTION_ARGS)
 			sign = '+';
 			numstr = orgnum;
 		}
+
 		if ((p = strchr(numstr, '.')))
-			len = p - numstr;
+			numstr_pre_len = p - numstr;
 		else
-			len = strlen(numstr);
+			numstr_pre_len = strlen(numstr);
 
-		if (Num.pre > len)
-			plen = Num.pre - len;
-		else if (len > Num.pre)
+		/* needs padding? */
+		if (numstr_pre_len < Num.pre)
+			out_pre_spaces = Num.pre - numstr_pre_len;
+		/* overflowed prefix digit format? */
+		else if (numstr_pre_len > Num.pre)
 		{
 			numstr = (char *) palloc(Num.pre + Num.post + 2);
 			fill_str(numstr, '#', Num.pre + Num.post + 1);
@@ -5383,7 +5395,7 @@ float8_to_char(PG_FUNCTION_ARGS)
 	FormatNode *format;
 	text	   *result;
 	bool		shouldFree;
-	int			plen = 0,
+	int			out_pre_spaces = 0,
 				sign = 0;
 	char	   *numstr,
 			   *orgnum,
@@ -5423,7 +5435,7 @@ float8_to_char(PG_FUNCTION_ARGS)
 	else
 	{
 		float8		val = value;
-		int			len;
+		int			numstr_pre_len;
 
 		if (IS_MULTI(&Num))
 		{
@@ -5433,13 +5445,13 @@ float8_to_char(PG_FUNCTION_ARGS)
 			Num.pre += Num.multi;
 		}
 		orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
-		len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.0f", fabs(val));
-		if (Num.pre > len)
-			plen = Num.pre - len;
-		if (len >= DBL_DIG)
+		numstr_pre_len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.0f", fabs(val));
+
+		/* adjust post digits to fit max double digits */
+		if (numstr_pre_len >= DBL_DIG)
 			Num.post = 0;
-		else if (Num.post + len > DBL_DIG)
-			Num.post = DBL_DIG - len;
+		else if (numstr_pre_len + Num.post > DBL_DIG)
+			Num.post = DBL_DIG - numstr_pre_len;
 		snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*f", Num.post, val);
 
 		if (*orgnum == '-')
@@ -5452,14 +5464,17 @@ float8_to_char(PG_FUNCTION_ARGS)
 			sign = '+';
 			numstr = orgnum;
 		}
+
 		if ((p = strchr(numstr, '.')))
-			len = p - numstr;
+			numstr_pre_len = p - numstr;
 		else
-			len = strlen(numstr);
+			numstr_pre_len = strlen(numstr);
 
-		if (Num.pre > len)
-			plen = Num.pre - len;
-		else if (len > Num.pre)
+		/* needs padding? */
+		if (numstr_pre_len < Num.pre)
+			out_pre_spaces = Num.pre - numstr_pre_len;
+		/* overflowed prefix digit format? */
+		else if (numstr_pre_len > Num.pre)
 		{
 			numstr = (char *) palloc(Num.pre + Num.post + 2);
 			fill_str(numstr, '#', Num.pre + Num.post + 1);