Hello

I was surprised so PostgreSQL doesn't support this basic output format.

Regards
Pavel Stehule
*** ./src/backend/utils/adt/formatting.c.orig	2009-04-10 11:31:17.000000000 +0200
--- ./src/backend/utils/adt/formatting.c	2009-04-10 18:05:14.000000000 +0200
***************
*** 335,340 ****
--- 335,341 ----
  #define NUM_F_MULTI			(1 << 11)
  #define NUM_F_PLUS_POST		(1 << 12)
  #define NUM_F_MINUS_POST	(1 << 13)
+ #define NUM_F_EEEE		(1 << 14)
  
  #define NUM_LSIGN_PRE	(-1)
  #define NUM_LSIGN_POST	1
***************
*** 355,360 ****
--- 356,362 ----
  #define IS_PLUS(_f) ((_f)->flag & NUM_F_PLUS)
  #define IS_ROMAN(_f)	((_f)->flag & NUM_F_ROMAN)
  #define IS_MULTI(_f)	((_f)->flag & NUM_F_MULTI)
+ #define IS_EEEE(_f)	((_f)->flag & NUM_F_EEEE)
  
  /* ----------
   * Format picture cache
***************
*** 821,827 ****
  	{"B", 1, NUM_B},		/* B */
  	{"C", 1, NUM_C},		/* C */
  	{"D", 1, NUM_D},		/* D */
! 	{"E", 1, NUM_E},		/* E */
  	{"FM", 2, NUM_FM},		/* F */
  	{"G", 1, NUM_G},		/* G */
  	{"L", 1, NUM_L},		/* L */
--- 823,829 ----
  	{"B", 1, NUM_B},		/* B */
  	{"C", 1, NUM_C},		/* C */
  	{"D", 1, NUM_D},		/* D */
! 	{"EEEE", 4, NUM_E},		/* E */
  	{"FM", 2, NUM_FM},		/* F */
  	{"G", 1, NUM_G},		/* G */
  	{"L", 1, NUM_L},		/* L */
***************
*** 1043,1048 ****
--- 1045,1058 ----
  
  	if (n->type != NODE_TYPE_ACTION)
  		return;
+ 		
+ 	if (IS_EEEE(num) && n->key->id != NUM_E)
+ 	{
+ 		NUM_cache_remove(last_NUMCacheEntry);
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_SYNTAX_ERROR),
+ 				 errmsg("cannot use \"EEEE\" and others")));
+ 	}
  
  	switch (n->key->id)
  	{
***************
*** 1217,1226 ****
  			break;
  
  		case NUM_E:
! 			NUM_cache_remove(last_NUMCacheEntry);
! 			ereport(ERROR,
! 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! 					 errmsg("\"E\" is not supported")));
  	}
  
  	return;
--- 1227,1249 ----
  			break;
  
  		case NUM_E:
! 			if (IS_EEEE(num))
! 			{
! 				NUM_cache_remove(last_NUMCacheEntry);
! 				ereport(ERROR,
! 						(errcode(ERRCODE_SYNTAX_ERROR),
! 						 errmsg("cannot use \"EEEE\" twice")));
! 			}
! 			if (IS_BLANK(num) || IS_FILLMODE(num) || IS_LSIGN(num) || IS_BRACKET(num)
! 				|| IS_MINUS(num) || IS_PLUS(num) || IS_ROMAN(num) || IS_MULTI(num))
! 			{
! 				NUM_cache_remove(last_NUMCacheEntry);
! 				ereport(ERROR,
! 						(errcode(ERRCODE_SYNTAX_ERROR),
! 						 errmsg("cannot use \"EEEE\" and others")));
! 			}
! 			num->flag |= NUM_F_EEEE;
! 			break;
  	}
  
  	return;
***************
*** 4138,4143 ****
--- 4161,4178 ----
  		--Np->Num->zero_start;
  
  	/*
+ 	 * Short code for EEEE format
+ 	 */
+ 	if (IS_EEEE(Np->Num))
+ 	{
+ 		if (!Np->is_to_char)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 					 errmsg("\"EEEE\" not supported")));
+ 		return strcpy(inout, number);
+ 	}
+ 
+ 	/*
  	 * Roman correction
  	 */
  	if (IS_ROMAN(Np->Num))
***************
*** 4232,4238 ****
  
  #ifdef DEBUG_TO_FROM_CHAR
  	elog(DEBUG_elog_output,
! 		 "\n\tSIGN: '%c'\n\tNUM: '%s'\n\tPRE: %d\n\tPOST: %d\n\tNUM_COUNT: %d\n\tNUM_PRE: %d\n\tSIGN_WROTE: %s\n\tZERO: %s\n\tZERO_START: %d\n\tZERO_END: %d\n\tLAST_RELEVANT: %s\n\tBRACKET: %s\n\tPLUS: %s\n\tMINUS: %s\n\tFILLMODE: %s\n\tROMAN: %s",
  		 Np->sign,
  		 Np->number,
  		 Np->Num->pre,
--- 4267,4273 ----
  
  #ifdef DEBUG_TO_FROM_CHAR
  	elog(DEBUG_elog_output,
! 		 "\n\tSIGN: '%c'\n\tNUM: '%s'\n\tPRE: %d\n\tPOST: %d\n\tNUM_COUNT: %d\n\tNUM_PRE: %d\n\tSIGN_WROTE: %s\n\tZERO: %s\n\tZERO_START: %d\n\tZERO_END: %d\n\tLAST_RELEVANT: %s\n\tBRACKET: %s\n\tPLUS: %s\n\tMINUS: %s\n\tFILLMODE: %s\n\tROMAN: %s\n\tEEEE: %s",
  		 Np->sign,
  		 Np->number,
  		 Np->Num->pre,
***************
*** 4248,4254 ****
  		 IS_PLUS(Np->Num) ? "Yes" : "No",
  		 IS_MINUS(Np->Num) ? "Yes" : "No",
  		 IS_FILLMODE(Np->Num) ? "Yes" : "No",
! 		 IS_ROMAN(Np->Num) ? "Yes" : "No"
  		);
  #endif
  
--- 4283,4290 ----
  		 IS_PLUS(Np->Num) ? "Yes" : "No",
  		 IS_MINUS(Np->Num) ? "Yes" : "No",
  		 IS_FILLMODE(Np->Num) ? "Yes" : "No",
! 		 IS_ROMAN(Np->Num) ? "Yes" : "No",
! 		 IS_EEEE(Np->Num) ? "Yes" : "No"
  		);
  #endif
  
***************
*** 4618,4623 ****
--- 4654,4680 ----
  			int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4,
  													   NumericGetDatum(x))));
  	}
+ 	else if (IS_EEEE(&Num))
+ 	{
+ 		float8 val;
+ 		
+ 		if (Num.pre != 1)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_SYNTAX_ERROR),
+ 					 errmsg("invalid using of format EEEE")));
+ 		
+ 		val = DatumGetFloat8(DirectFunctionCall1(numeric_float8,
+ 										NumericGetDatum(value)));
+ 		
+ 		numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
+ 		len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*e", Num.post, val);
+ 		if (len > Num.pre + Num.post + 5)
+ 		{
+ 			numstr = (char *) palloc(Num.pre + Num.post + 6);
+ 			fill_str(numstr, '#', Num.pre + Num.post + 5);
+ 			*(numstr + Num.pre) = '.';
+ 		}
+ 	}
  	else
  	{
  		Numeric		val = value;
***************
*** 4699,4704 ****
--- 4756,4773 ----
  	 */
  	if (IS_ROMAN(&Num))
  		numstr = orgnum = int_to_roman(value);
+ 	else if (IS_EEEE(&Num))
+ 	{
+ 		float8 val = (float8) value;
+ 		
+ 		numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
+ 		if (Num.pre != 1)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_SYNTAX_ERROR),
+ 					 errmsg("invalid using of format EEEE")));
+ 		
+ 		snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*e", Num.post, val);
+ 	}
  	else
  	{
  		if (IS_MULTI(&Num))
***************
*** 4777,4782 ****
--- 4846,4870 ----
  		numstr = orgnum = int_to_roman(DatumGetInt32(
  						  DirectFunctionCall1(int84, Int64GetDatum(value))));
  	}
+ 	else if (IS_EEEE(&Num))
+ 	{
+ 		float8 val = (float8) value;
+ 		
+ 		numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
+ 		if (Num.pre != 1)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_SYNTAX_ERROR),
+ 					 errmsg("invalid using of format EEEE")));
+ 		
+ 		len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*e", Num.post, value);
+ 		
+ 		if (len > Num.pre + Num.post + 5)
+ 		{
+ 			numstr = (char *) palloc(Num.pre + Num.post + 6);
+ 			fill_str(numstr, '#', Num.pre + Num.post + 5);
+ 			*(numstr + Num.pre) = '.';
+ 		}
+ 	}
  	else
  	{
  		if (IS_MULTI(&Num))
***************
*** 4851,4856 ****
--- 4939,4962 ----
  
  	if (IS_ROMAN(&Num))
  		numstr = orgnum = int_to_roman((int) rint(value));
+ 	else if (IS_EEEE(&Num))
+ 	{
+ 		numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
+ 		if (Num.pre != 1)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_SYNTAX_ERROR),
+ 					 errmsg("invalid using of format EEEE")));
+ 		
+ 		if (isnan(value) || is_infinite(value))
+ 		{
+ 			numstr = (char *) palloc(Num.pre + Num.post + 6);
+ 			fill_str(numstr, '#', Num.pre + Num.post + 5);
+ 			*(numstr + Num.pre) = '.';
+ 		}
+ 		else
+ 			snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*e", Num.post, value);
+ 		
+ 	}
  	else
  	{
  		float4		val = value;
***************
*** 4922,4932 ****
  	char	   *numstr,
  			   *orgnum,
  			   *p;
- 
  	NUM_TOCHAR_prepare;
  
  	if (IS_ROMAN(&Num))
  		numstr = orgnum = int_to_roman((int) rint(value));
  	else
  	{
  		float8		val = value;
--- 5028,5054 ----
  	char	   *numstr,
  			   *orgnum,
  			   *p;
  	NUM_TOCHAR_prepare;
  
  	if (IS_ROMAN(&Num))
  		numstr = orgnum = int_to_roman((int) rint(value));
+ 	else if (IS_EEEE(&Num))
+ 	{
+ 		numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
+ 		if (Num.pre != 1)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_SYNTAX_ERROR),
+ 					 errmsg("invalid using of format EEEE")));
+ 		
+ 		len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*e", Num.post, value);
+ 		
+ 		if (isnan(value) || is_infinite(value) || len > Num.pre + Num.post + 5)
+ 		{
+ 			numstr = (char *) palloc(Num.pre + Num.post + 6);
+ 			fill_str(numstr, '#', Num.pre + Num.post + 5);
+ 			*(numstr + Num.pre) = '.';
+ 		}
+ 	}
  	else
  	{
  		float8		val = value;
*** ./src/test/regress/expected/float8.out.orig	2009-04-10 18:09:10.000000000 +0200
--- ./src/test/regress/expected/float8.out	2009-04-10 18:10:09.000000000 +0200
***************
*** 438,440 ****
--- 438,453 ----
        | -1.2345678901234e-200
  (5 rows)
  
+ -- support for EEEE format
+ SELECT to_char(1.2345678901,'9.999999EEEE');
+    to_char    
+ --------------
+  1.234568e+00
+ (1 row)
+ 
+ SELECT to_char(1.234567,'9.999EEEE');
+   to_char  
+ -----------
+  1.235e+00
+ (1 row)
+ 
*** ./src/test/regress/sql/float8.sql.orig	2009-04-10 18:07:52.000000000 +0200
--- ./src/test/regress/sql/float8.sql	2009-04-10 18:09:49.000000000 +0200
***************
*** 167,169 ****
--- 167,172 ----
  
  SELECT '' AS five, * FROM FLOAT8_TBL;
  
+ -- support for EEEE format
+ SELECT to_char(1.2345678901,'9.999999EEEE');
+ SELECT to_char(1.234567,'9.999EEEE');
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to