mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Further fix for psql's code for locale-aware formatting of numeric output.
(Third time's the charm, I hope.) Additional testing disclosed that this code could mangle already-localized output from the "money" datatype. We can't very easily skip applying it to "money" values, because the logic is tied to column right-justification and people expect "money" output to be right-justified. Short of decoupling that, we can fix it in what should be a safe enough way by testing to make sure the string doesn't contain any characters that would not be expected in plain numeric output.
This commit is contained in:
		@@ -185,18 +185,34 @@ additional_numeric_locale_len(const char *my_str)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 | 
					 * Format a numeric value per current LC_NUMERIC locale setting
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * Returns the appropriately formatted string in a new allocated block,
 | 
					 * Returns the appropriately formatted string in a new allocated block,
 | 
				
			||||||
 * caller must free
 | 
					 * caller must free.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * setDecimalLocale() must have been called earlier.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static char *
 | 
					static char *
 | 
				
			||||||
format_numeric_locale(const char *my_str)
 | 
					format_numeric_locale(const char *my_str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int			new_len = strlen(my_str) + additional_numeric_locale_len(my_str);
 | 
						char	   *new_str;
 | 
				
			||||||
	char	   *new_str = pg_local_malloc(new_len + 1);
 | 
						int			new_len,
 | 
				
			||||||
	int			int_len = integer_digits(my_str);
 | 
									int_len,
 | 
				
			||||||
	int			i,
 | 
									leading_digits,
 | 
				
			||||||
				leading_digits;
 | 
									i,
 | 
				
			||||||
	int			new_str_pos = 0;
 | 
									new_str_pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If the string doesn't look like a number, return it unchanged.  This
 | 
				
			||||||
 | 
						 * check is essential to avoid mangling already-localized "money" values.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (strspn(my_str, "0123456789+-.eE") != strlen(my_str))
 | 
				
			||||||
 | 
							return pg_strdup(my_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						new_len = strlen(my_str) + additional_numeric_locale_len(my_str);
 | 
				
			||||||
 | 
						new_str = pg_local_malloc(new_len + 1);
 | 
				
			||||||
 | 
						new_str_pos = 0;
 | 
				
			||||||
 | 
						int_len = integer_digits(my_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* number of digits in first thousands group */
 | 
						/* number of digits in first thousands group */
 | 
				
			||||||
	leading_digits = int_len % groupdigits;
 | 
						leading_digits = int_len % groupdigits;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user