Hello,

I have included my patch attached to this mail.

I have made the changes to deal with locale settings from client
environment. So now you can start psql like this:

(export LC_ALL=ro_RO; psql -U user db)

and have numeric formatting with '.' as thousands separator and
',' as decimal point, or

(export LC_ALL=en_US; psql -U user db)

and have numeric formatting with ',' as thousands separator and
'.' as decimal point. This formatting is default when locale is 'C'

You can set any locale and numeric formatting code will take it in
consideration.

This patch is for version 7.3.2. The steps for install is:

1) cp thousands_comma.diff $POSTGRES_DIR/src/bin/psql
2) cd $POSTGRES_DIR/src/bin/psql
3) patch -p0 < thousands_comma.diff
4) ../../../configure && make


Best Regards,
Eugen
*** ./command.c.orig    Fri Jan 24 07:23:55 2003
--- ./command.c Fri Jun 17 12:10:12 2005
***************
*** 817,822 ****
--- 817,827 ----
        else if (strcmp(cmd, "x") == 0)
                success = do_pset("expanded", NULL, &pset.popt, quiet);
  
+       /* thousands comma patch */
+       /* \n -- toggle numeric formating */
+       else if (strcmp(cmd, "n") == 0)
+               success = do_pset("numeric", NULL, &pset.popt, quiet);
+       /* thousands comma patch */
  
        /* \z -- list table rights (equivalent to \dp) */
        else if (strcmp(cmd, "z") == 0)
***************
*** 1780,1785 ****
--- 1785,1802 ----
                                   : gettext("Expanded display is off.\n"));
        }
  
+
+       /* thousands comma patch */
+       else if ((strcmp(param, "n") == 0) || (strcmp(param, "numeric") == 0))
+       {
+               popt->topt.numeric = !popt->topt.numeric;
+               if (!quiet)
+                       printf(popt->topt.numeric
+                                  ? gettext("Numeric formating is on.\n")
+                                  : gettext("Numeric formating is off.\n"));
+       }
+       /* thousands comma patch */
+ 
        /* null display */
        else if (strcmp(param, "null") == 0)
        {
*** ./help.c.orig       Thu Oct 24 04:33:50 2002
--- ./help.c    Fri Jun 17 12:42:41 2005
***************
*** 224,229 ****
--- 224,231 ----
                        ON(pset.popt.topt.expanded));
        fprintf(output, _(" \\z [PATTERN]   list table access privileges (same 
as \\dp)\n"));
        fprintf(output, _(" \\! [COMMAND]   execute command in shell or start 
interactive shell\n"));
+       fprintf(output, _(" \\n             toggle numeric formating (currently 
%s)\n"),
+                       ON(pset.popt.topt.numeric));
  
        if (output != stdout)
        {
*** ./print.c.orig      Fri Nov  1 17:12:19 2002
--- ./print.c   Wed Jun 22 10:10:08 2005
***************
*** 19,24 ****
--- 19,114 ----
  
  #include "mbprint.h"
  
+ /* thousands comma patch */
+ # include "langinfo.h"
+ 
+ int get_nr_delim (char *);
+ int get_new_l (char *);
+ 
+ int get_nr_delim (char *my_str)
+ {
+     int old_l,dec_l,int_l,k,nr_delim;
+     old_l = strlen(my_str);
+     dec_l = (strstr(my_str, ".") ? strlen(strstr(my_str, ".")) : 0);
+     if (my_str[0] == '-')
+       int_l = old_l - dec_l - 1;
+     else
+       int_l = old_l - dec_l;
+       
+     k = int_l % 3;
+ 
+     if (k)
+       nr_delim = (int_l / 3);
+     else
+       nr_delim = (int_l / 3) - 1;
+ 
+     return nr_delim;
+ }
+ 
+ int get_new_l (char *my_str)
+ {
+     return (strlen(my_str) + get_nr_delim(my_str));
+ }
+ 
+ static void 
+ thousands_comma(char *my_str)
+ {
+     int i,j,k,old_l,new_l,dec_l,int_l;
+     
+     char *dec_point = nl_langinfo(__DECIMAL_POINT);
+     char *thou_sep;
+     
+     if (!strcmp(dec_point, "")) dec_point = ".";
+     if (!strcmp(dec_point, "."))
+       thou_sep = ",";
+     else
+       thou_sep = ".";
+     
+     if (my_str[0] == '-') my_str++;
+     
+     old_l = strlen(my_str);
+     dec_l = (strstr(my_str, ".") ? strlen(strstr(my_str, ".")) : 0);
+     int_l = old_l - dec_l;
+     k = int_l % 3;
+ 
+     if (k)
+       new_l = int_l + (int_l / 3) + dec_l;
+     else
+       new_l = int_l + (int_l / 3) - 1 + dec_l;
+ 
+     char new_str[new_l];
+ 
+     for (i=0,j=0;;i++,j++)
+     {
+       if (my_str[i] == '.')
+       {
+           new_str[j] = *dec_point;
+           new_str[j+1] = '\0';
+           char *dec_value = strstr(my_str, ".");
+           strcat(new_str, ++dec_value);
+           break;
+       }
+ 
+       if (my_str[i] == '\0')
+       {
+           new_str[j] = '\0';
+           break;
+       }
+ 
+       if ((j - (k ? k : 3)) % 4)
+           new_str[j] = my_str[i];
+       else
+       {
+           new_str[j] = *thou_sep;
+           i--;
+       }    
+     }
+         
+     strcpy(my_str, new_str);
+ }
+ 
+ /* thousands comma patch */
+ 
  /*************************/
  /* Unaligned text              */
  /*************************/
***************
*** 26,33 ****
  
  static void
  print_unaligned_text(const char *title, const char *const * headers,
!                                 const char *const * cells, const char *const 
* footers,
!  const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones,
                                         FILE *fout)
  {
        unsigned int col_count = 0;
--- 116,123 ----
  
  static void
  print_unaligned_text(const char *title, const char *const * headers,
!                                 const char *const * cells, const char *const 
* footers, const char *opt_align,
!  const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones, 
bool opt_numeric,
                                         FILE *fout)
  {
        unsigned int col_count = 0;
***************
*** 67,73 ****
                        fputs(opt_recordsep, fout);
                        need_recordsep = false;
                }
!               fputs(*ptr, fout);
                if ((i + 1) % col_count)
                        fputs(opt_fieldsep, fout);
                else
--- 157,173 ----
                        fputs(opt_recordsep, fout);
                        need_recordsep = false;
                }
!               /* thousands comma patch */
!               if ((opt_align[i % col_count] == 'r') && cells[i] != "" && 
opt_numeric)
!               {
!                   char my_cell[get_new_l(cells[i])];
!                   strcpy(my_cell, *ptr);
!                   thousands_comma(my_cell);
!                   fputs(my_cell, fout);
!               } else fputs(*ptr, fout);
!               /* thousands comma patch */
!               
!               /* fputs(*ptr, fout); */
                if ((i + 1) % col_count)
                        fputs(opt_fieldsep, fout);
                else
***************
*** 98,105 ****
  
  static void
  print_unaligned_vertical(const char *title, const char *const * headers,
!                                 const char *const * cells, const char *const 
* footers,
!  const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones,
                                                 FILE *fout)
  {
        unsigned int col_count = 0;
--- 198,205 ----
  
  static void
  print_unaligned_vertical(const char *title, const char *const * headers,
!                                 const char *const * cells, const char *const 
* footers, const char *opt_align,
!  const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones, 
bool opt_numeric,
                                                 FILE *fout)
  {
        unsigned int col_count = 0;
***************
*** 131,137 ****
  
                fputs(headers[i % col_count], fout);
                fputs(opt_fieldsep, fout);
!               fputs(*ptr, fout);
        }
  
        /* print footers */
--- 231,247 ----
  
                fputs(headers[i % col_count], fout);
                fputs(opt_fieldsep, fout);
!               /* thousands comma patch */
!               if ((opt_align[i % col_count] == 'r') && cells[i] != "" && 
opt_numeric)
!               {
!                   char my_cell[get_new_l(cells[i])];
!                   strcpy(my_cell, *ptr);
!                   thousands_comma(my_cell);
!                   fputs(my_cell, fout);
!               } else fputs(*ptr, fout);
!               /* thousands comma patch */
! 
!               /* fputs(*ptr, fout); */
        }
  
        /* print footers */
***************
*** 190,200 ****
  }
  
  
- 
  static void
  print_aligned_text(const char *title, const char *const * headers,
                                   const char *const * cells, const char *const 
* footers,
!                                  const char *opt_align, bool opt_barebones,
                                   unsigned short int opt_border,
                                   FILE *fout)
  {
--- 300,309 ----
  }
  
  
  static void
  print_aligned_text(const char *title, const char *const * headers,
                                   const char *const * cells, const char *const 
* footers,
!                                  const char *opt_align, bool opt_barebones, 
bool opt_numeric,
                                   unsigned short int opt_border,
                                   FILE *fout)
  {
***************
*** 261,267 ****
  
        for (i = 0, ptr = cells; *ptr; ptr++, i++)
        {
!               tmp = pg_wcswidth((unsigned char *) *ptr, strlen(*ptr));
                if (tmp > widths[i % col_count])
                        widths[i % col_count] = tmp;
                cell_w[i] = tmp;
--- 370,384 ----
  
        for (i = 0, ptr = cells; *ptr; ptr++, i++)
        {
!               /* thousands comma patch */
!               int nr_delim;
!               if ((opt_align[i % col_count] == 'r') && cells[i] != "" && 
opt_numeric)
!                   nr_delim = get_nr_delim(cells[i]);
!               else 
!                   nr_delim = 0;
!               /* thousands comma patch */
!               
!               tmp = pg_wcswidth((unsigned char *) *ptr, strlen(*ptr)) + 
nr_delim;
                if (tmp > widths[i % col_count])
                        widths[i % col_count] = tmp;
                cell_w[i] = tmp;
***************
*** 343,350 ****
                /* content */
                if (opt_align[i % col_count] == 'r')
                {
!                       fprintf(fout, "%*s%s",
!                                       widths[i % col_count] - cell_w[i], "", 
cells[i]);
                }
                else
                {
--- 460,475 ----
                /* content */
                if (opt_align[i % col_count] == 'r')
                {
!                   /* thousands comma patch */
!                   if (cells[i] != "" && opt_numeric)
!                   {
!                       char my_cell[cell_w[i]];
!                       strcpy(my_cell, cells[i]);
!                       thousands_comma(my_cell);
!                       fprintf(fout, "%*s%s", widths[i % col_count] - 
cell_w[i], "", my_cell);
!                   } else
!                       fprintf(fout, "%*s%s", widths[i % col_count] - 
cell_w[i], "", cells[i]);
!                   /* thousands comma patch */
                }
                else
                {
***************
*** 392,399 ****
  
  static void
  print_aligned_vertical(const char *title, const char *const * headers,
!                                 const char *const * cells, const char *const 
* footers,
!                                          bool opt_barebones, unsigned short 
int opt_border,
                                           FILE *fout)
  {
        unsigned int col_count = 0;
--- 517,524 ----
  
  static void
  print_aligned_vertical(const char *title, const char *const * headers,
!                                 const char *const * cells, const char *const 
* footers, const char *opt_align,
!                                          bool opt_barebones, bool 
opt_numeric, unsigned short int opt_border,
                                           FILE *fout)
  {
        unsigned int col_count = 0;
***************
*** 447,453 ****
        /* find longest data cell */
        for (i = 0, ptr = cells; *ptr; ptr++, i++)
        {
!               if ((tmp = pg_wcswidth((unsigned char *) *ptr, strlen(*ptr))) > 
dwidth)
                        dwidth = tmp;
                cell_w[i] = tmp;
        }
--- 572,586 ----
        /* find longest data cell */
        for (i = 0, ptr = cells; *ptr; ptr++, i++)
        {
!               /* thousands comma patch */
!               int nr_delim;
!               if ((opt_align[i % col_count] == 'r') && cells[i] != "" && 
opt_numeric)
!                   nr_delim = get_nr_delim(cells[i]);
!               else 
!                   nr_delim = 0;
!               /* thousands comma patch */
! 
!               if ((tmp = pg_wcswidth((unsigned char *) *ptr, strlen(*ptr)) + 
nr_delim) > dwidth)
                        dwidth = tmp;
                cell_w[i] = tmp;
        }
***************
*** 532,541 ****
--- 665,687 ----
                else
                        fputs(" ", fout);
  
+               /* thousands comma patch */
+               char my_cell[cell_w[i]];
+               strcpy(my_cell, *ptr);
+               if ((opt_align[i % col_count] == 'r') && (my_cell != "") && 
opt_numeric)
+                   thousands_comma(my_cell);
+               if (opt_border < 2)
+                       fprintf(fout, "%s\n", my_cell);
+               else
+                       fprintf(fout, "%-s%*s |\n", my_cell, dwidth - 
cell_w[i], "");
+               /* thousands comma patch */
+ 
+               /*
                if (opt_border < 2)
                        fprintf(fout, "%s\n", *ptr);
                else
                        fprintf(fout, "%-s%*s |\n", *ptr, dwidth - cell_w[i], 
"");
+               */
        }
  
        if (opt_border == 2)
***************
*** 598,604 ****
  static void
  print_html_text(const char *title, const char *const * headers,
                                const char *const * cells, const char *const * 
footers,
! const char *opt_align, bool opt_barebones, unsigned short int opt_border,
                                const char *opt_table_attr,
                                FILE *fout)
  {
--- 744,750 ----
  static void
  print_html_text(const char *title, const char *const * headers,
                                const char *const * cells, const char *const * 
footers,
! const char *opt_align, bool opt_barebones, bool opt_numeric, unsigned short 
int opt_border,
                                const char *opt_table_attr,
                                FILE *fout)
  {
***************
*** 646,652 ****
                                                                                
                                 * whitespace? */
                        fputs("&nbsp;", fout);
                else
!                       html_escaped_print(*ptr, fout);
                fputs("</td>\n", fout);
  
                if ((i + 1) % col_count == 0)
--- 792,808 ----
                                                                                
                                 * whitespace? */
                        fputs("&nbsp;", fout);
                else
!                       /* thousands comma patch */
!                       if ((opt_align[i % col_count] == 'r') && cells[i] != "" 
&& opt_numeric)
!                       {
!                           char my_cell[get_new_l(cells[i])];
!                           strcpy(my_cell, *ptr);
!                           thousands_comma(my_cell);
!                           html_escaped_print(my_cell, fout);
!                       } else html_escaped_print(*ptr, fout);
!                       /* thousands comma patch */
! 
!                       /* html_escaped_print(*ptr, fout); */
                fputs("</td>\n", fout);
  
                if ((i + 1) % col_count == 0)
***************
*** 672,678 ****
  static void
  print_html_vertical(const char *title, const char *const * headers,
                                  const char *const * cells, const char *const 
* footers,
! const char *opt_align, bool opt_barebones, unsigned short int opt_border,
                                        const char *opt_table_attr,
                                        FILE *fout)
  {
--- 828,834 ----
  static void
  print_html_vertical(const char *title, const char *const * headers,
                                  const char *const * cells, const char *const 
* footers,
! const char *opt_align, bool opt_barebones, bool opt_numeric, unsigned short 
int opt_border,
                                        const char *opt_table_attr,
                                        FILE *fout)
  {
***************
*** 718,724 ****
                                                                                
                                 * whitespace? */
                        fputs("&nbsp;", fout);
                else
!                       html_escaped_print(*ptr, fout);
                fputs("</td>\n  </tr>\n", fout);
        }
  
--- 874,892 ----
                                                                                
                                 * whitespace? */
                        fputs("&nbsp;", fout);
                else
!               {       /* thousands comma patch */
!                       if ((opt_align[i % col_count] == 'r') && cells[i] != "" 
&& opt_numeric)
!                       {
!                           char my_cell[get_new_l(cells[i])];
!                           strcpy(my_cell, *ptr);
!                           thousands_comma(my_cell);
!                           html_escaped_print(my_cell, fout);
!                       } else html_escaped_print(*ptr, fout);
!               }
!                       /* thousands comma patch */
! 
!                       /* html_escaped_print(*ptr, fout); */
!                       
                fputs("</td>\n  </tr>\n", fout);
        }
  
***************
*** 1017,1037 ****
        {
                case PRINT_UNALIGNED:
                        if (opt->expanded)
!                               print_unaligned_vertical(title, headers, cells, 
footers, opt->fieldSep, opt->recordSep, opt->tuples_only, output);
                        else
!                               print_unaligned_text(title, headers, cells, 
footers, opt->fieldSep, opt->recordSep, opt->tuples_only, output);
                        break;
                case PRINT_ALIGNED:
                        if (opt->expanded)
!                               print_aligned_vertical(title, headers, cells, 
footers, opt->tuples_only, border, output);
                        else
!                               print_aligned_text(title, headers, cells, 
footers, align, opt->tuples_only, border, output);
                        break;
                case PRINT_HTML:
                        if (opt->expanded)
!                               print_html_vertical(title, headers, cells, 
footers, align, opt->tuples_only, border, opt->tableAttr, output);
                        else
!                               print_html_text(title, headers, cells, footers, 
align, opt->tuples_only, border, opt->tableAttr, output);
                        break;
                case PRINT_LATEX:
                        if (opt->expanded)
--- 1185,1205 ----
        {
                case PRINT_UNALIGNED:
                        if (opt->expanded)
!                               print_unaligned_vertical(title, headers, cells, 
footers, align, opt->fieldSep, opt->recordSep, opt->tuples_only, opt->numeric, 
output);
                        else
!                               print_unaligned_text(title, headers, cells, 
footers, align, opt->fieldSep, opt->recordSep, opt->tuples_only, opt->numeric, 
output);
                        break;
                case PRINT_ALIGNED:
                        if (opt->expanded)
!                               print_aligned_vertical(title, headers, cells, 
footers, align, opt->tuples_only, opt->numeric, border, output);
                        else
!                               print_aligned_text(title, headers, cells, 
footers, align, opt->tuples_only, opt->numeric, border, output);
                        break;
                case PRINT_HTML:
                        if (opt->expanded)
!                               print_html_vertical(title, headers, cells, 
footers, align, opt->tuples_only, opt->numeric, border, opt->tableAttr, output);
                        else
!                               print_html_text(title, headers, cells, footers, 
align, opt->tuples_only, opt->numeric, border, opt->tableAttr, output);
                        break;
                case PRINT_LATEX:
                        if (opt->expanded)
*** ./print.h.orig      Wed Sep  4 23:31:36 2002
--- ./print.h   Fri Jun 17 12:38:26 2005
***************
*** 26,31 ****
--- 26,34 ----
        enum printFormat format;        /* one of the above */
        bool            expanded;               /* expanded/vertical output (if 
supported
                                                                 * by output 
format) */
+       /* thousands comma patch */
+       bool            numeric;        /* numeric format */
+       /* thousands comma patch */
        bool            pager;                  /* use pager for output (if to 
stdout and
                                                                 * stdout is a 
tty) */
        bool            tuples_only;    /* don't output headers, row counts, 
etc. */
*** ./startup.c.orig    Sat Oct 19 01:05:36 2002
--- ./startup.c Fri Jun 17 12:54:43 2005
***************
*** 138,143 ****
--- 138,146 ----
        pset.queryFout = stdout;
        pset.popt.topt.border = 1;
        pset.popt.topt.pager = true;
+       /* thousands comma patch */
+       pset.popt.topt.numeric = true;
+       /* thousands comma patch */
        pset.popt.default_footer = true;
  
        SetVariable(pset.vars, "VERSION", PG_VERSION_STR);
---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
       choose an index scan if your joining column's datatypes do not
       match

Reply via email to