Thread: psql latex bugfixes

psql latex bugfixes

From
Roger Leigh
Date:
I have noticed that the latex format in psql has some bugs:

· "_" is not escaped, and causes TeX to abort, thinking it's a
  subscript outside of maths mode.  Most of my table and field names
  use underscores, so this is a really nasty one.
· The column count is calculated using the contents of opt_align.  But
  opt_align has one extra element, and so it's always one too many.  I
  changed it to count the column headings, like all the other output
  formats.  There may be a bug in computing opt_align that this patch
  does not address, but I'm not yet familiar enough with the psql
  source to fix this as well.
· The line drawing rules for each border setting (0-3) and expanded
  mode didn't always match the documented behaviour and what other
  formats (e.g. aligned) did.  I made it as conformant as possible,
  and also tidied the alignment of the first line of the footer, which
  was incorrectly indented.

I've attached some example output with this patch applied.

Regards,
Roger


Index: src/bin/psql/print.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.c,v
retrieving revision 1.48
diff -u -r1.48 print.c
--- src/bin/psql/print.c    23 May 2004 22:20:10 -0000    1.48
+++ src/bin/psql/print.c    1 Aug 2004 22:54:22 -0000
@@ -769,7 +769,7 @@


 /*************************/
-/* LaTeX                 */
+/* LaTeX         */
 /*************************/


@@ -790,6 +790,9 @@
             case '$':
                 fputs("\\$", fout);
                 break;
+            case '_':
+                fputs("\\_", fout);
+                break;
             case '{':
                 fputs("\\{", fout);
                 break;
@@ -817,7 +820,6 @@
 {
     unsigned int col_count = 0;
     unsigned int i;
-    const char *cp;
     const char *const * ptr;


@@ -829,42 +831,39 @@
         fputs("\n\\end{center}\n\n", fout);
     }

+    /* count columns */
+    for (ptr = headers; *ptr; ptr++)
+        col_count++;
+
     /* begin environment and set alignments and borders */
     fputs("\\begin{tabular}{", fout);
-    if (opt_border == 0)
-        fputs(opt_align, fout);
-    else if (opt_border == 1)
-    {
-        for (cp = opt_align; *cp; cp++)
-        {
-            if (cp != opt_align)
-                fputc('|', fout);
-            fputc(*cp, fout);
-        }
-    }
-    else if (opt_border == 2)
+
+    if (opt_border == 2)
+      fputs("| ", fout);
+        for (i = 0; i < col_count; i++)
     {
-        for (cp = opt_align; *cp; cp++)
-        {
-            fputc('|', fout);
-            fputc(*cp, fout);
-        }
-        fputc('|', fout);
+      fputc(*(opt_align + i), fout);
+      if (opt_border != 0 && i < col_count - 1)
+        fputs (" | ", fout);
     }
+    if (opt_border == 2)
+      fputs(" |", fout);
+
     fputs("}\n", fout);

     if (!opt_barebones && opt_border == 2)
         fputs("\\hline\n", fout);

     /* print headers and count columns */
-    for (i = 0, ptr = headers; *ptr; i++, ptr++)
+    for (i = 0, ptr = headers; i < col_count; i++, ptr++)
     {
-        col_count++;
         if (!opt_barebones)
         {
             if (i != 0)
                 fputs(" & ", fout);
+                        fputs("\\textit{", fout);
             latex_escaped_print(*ptr, fout);
+                        fputc('}', fout);
         }
     }

@@ -888,7 +887,7 @@
     if (opt_border == 2)
         fputs("\\hline\n", fout);

-    fputs("\\end{tabular}\n\n", fout);
+    fputs("\\end{tabular}\n\n\\noindent ", fout);


     /* print footers */
@@ -951,8 +950,12 @@
             if (!opt_barebones)
             {
                 if (opt_border == 2)
+                {
                     fputs("\\hline\n", fout);
-                fprintf(fout, "\\multicolumn{2}{c}{Record %d} \\\\\n", record++);
+                    fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %d}} \\\\\n", record++);
+                }
+                else
+                    fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %d}} \\\\\n", record++);
             }
             if (opt_border >= 1)
                 fputs("\\hline\n", fout);
@@ -967,7 +970,7 @@
     if (opt_border == 2)
         fputs("\\hline\n", fout);

-    fputs("\\end{tabular}\n\n", fout);
+    fputs("\\end{tabular}\n\n\\noindent ", fout);


     /* print footers */



--
Roger Leigh

                Printing on GNU/Linux?  http://gimp-print.sourceforge.net/
                GPG Public Key: 0x25BFB848.  Please sign and encrypt your mail.
\documentclass[a4paper]{article}

\begin{document}
\title{Test}
\maketitle

\section{Normal}

\begin{center}
Table "public.suites"
\end{center}

\begin{tabular}{lll}
\textit{Column} & \textit{Type} & \textit{Modifiers} \\
\hline
id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
name & text & not null \\
archive\_id & integer & not null \\
version & text &  \\
path & text &  \\
alias & text &  \\
description & text &  \\
\end{tabular}

\noindent Indexes: \\
    "suites\_pkey" PRIMARY KEY, btree (id) \\
    "suites\_alias\_key" UNIQUE, btree (alias) \\
    "suites\_name\_key" UNIQUE, btree (name) \\
Foreign-key constraints: \\
    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\

\begin{center}
Table "public.suites"
\end{center}

\begin{tabular}{l | l | l}
\textit{Column} & \textit{Type} & \textit{Modifiers} \\
\hline
id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
name & text & not null \\
archive\_id & integer & not null \\
version & text &  \\
path & text &  \\
alias & text &  \\
description & text &  \\
\end{tabular}

\noindent Indexes: \\
    "suites\_pkey" PRIMARY KEY, btree (id) \\
    "suites\_alias\_key" UNIQUE, btree (alias) \\
    "suites\_name\_key" UNIQUE, btree (name) \\
Foreign-key constraints: \\
    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\

\begin{center}
Table "public.suites"
\end{center}

\begin{tabular}{| l | l | l |}
\hline
\textit{Column} & \textit{Type} & \textit{Modifiers} \\
\hline
id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
name & text & not null \\
archive\_id & integer & not null \\
version & text &  \\
path & text &  \\
alias & text &  \\
description & text &  \\
\hline
\end{tabular}

\noindent Indexes: \\
    "suites\_pkey" PRIMARY KEY, btree (id) \\
    "suites\_alias\_key" UNIQUE, btree (alias) \\
    "suites\_name\_key" UNIQUE, btree (name) \\
Foreign-key constraints: \\
    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\

\begin{center}
Table "public.suites"
\end{center}

\begin{tabular}{cl}
\multicolumn{2}{c}{\textit{Record 1}} \\
Column & id \\
Type & integer \\
Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
\multicolumn{2}{c}{\textit{Record 2}} \\
Column & name \\
Type & text \\
Modifiers & not null \\
\multicolumn{2}{c}{\textit{Record 3}} \\
Column & archive\_id \\
Type & integer \\
Modifiers & not null \\
\multicolumn{2}{c}{\textit{Record 4}} \\
Column & version \\
Type & text \\
Modifiers &  \\
\multicolumn{2}{c}{\textit{Record 5}} \\
Column & path \\
Type & text \\
Modifiers &  \\
\multicolumn{2}{c}{\textit{Record 6}} \\
Column & alias \\
Type & text \\
Modifiers &  \\
\multicolumn{2}{c}{\textit{Record 7}} \\
Column & description \\
Type & text \\
Modifiers &  \\
\end{tabular}

\noindent Indexes: \\
    "suites\_pkey" PRIMARY KEY, btree (id) \\
    "suites\_alias\_key" UNIQUE, btree (alias) \\
    "suites\_name\_key" UNIQUE, btree (name) \\
Foreign-key constraints: \\
    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\

\begin{center}
Table "public.suites"
\end{center}

\begin{tabular}{c|l}
\multicolumn{2}{c}{\textit{Record 1}} \\
\hline
Column & id \\
Type & integer \\
Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
\multicolumn{2}{c}{\textit{Record 2}} \\
\hline
Column & name \\
Type & text \\
Modifiers & not null \\
\multicolumn{2}{c}{\textit{Record 3}} \\
\hline
Column & archive\_id \\
Type & integer \\
Modifiers & not null \\
\multicolumn{2}{c}{\textit{Record 4}} \\
\hline
Column & version \\
Type & text \\
Modifiers &  \\
\multicolumn{2}{c}{\textit{Record 5}} \\
\hline
Column & path \\
Type & text \\
Modifiers &  \\
\multicolumn{2}{c}{\textit{Record 6}} \\
\hline
Column & alias \\
Type & text \\
Modifiers &  \\
\multicolumn{2}{c}{\textit{Record 7}} \\
\hline
Column & description \\
Type & text \\
Modifiers &  \\
\end{tabular}

\noindent Indexes: \\
    "suites\_pkey" PRIMARY KEY, btree (id) \\
    "suites\_alias\_key" UNIQUE, btree (alias) \\
    "suites\_name\_key" UNIQUE, btree (name) \\
Foreign-key constraints: \\
    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\

\begin{center}
Table "public.suites"
\end{center}

\begin{tabular}{|c|l|}
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
Column & id \\
Type & integer \\
Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
Column & name \\
Type & text \\
Modifiers & not null \\
\hline
\multicolumn{2}{|c|}{\textit{Record 3}} \\
\hline
Column & archive\_id \\
Type & integer \\
Modifiers & not null \\
\hline
\multicolumn{2}{|c|}{\textit{Record 4}} \\
\hline
Column & version \\
Type & text \\
Modifiers &  \\
\hline
\multicolumn{2}{|c|}{\textit{Record 5}} \\
\hline
Column & path \\
Type & text \\
Modifiers &  \\
\hline
\multicolumn{2}{|c|}{\textit{Record 6}} \\
\hline
Column & alias \\
Type & text \\
Modifiers &  \\
\hline
\multicolumn{2}{|c|}{\textit{Record 7}} \\
\hline
Column & description \\
Type & text \\
Modifiers &  \\
\hline
\end{tabular}

\noindent Indexes: \\
    "suites\_pkey" PRIMARY KEY, btree (id) \\
    "suites\_alias\_key" UNIQUE, btree (alias) \\
    "suites\_name\_key" UNIQUE, btree (name) \\
Foreign-key constraints: \\
    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\



\end{document}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

Attachment

Re: psql latex bugfixes

From
Bruce Momjian
Date:
This has been saved for the 7.6 release:

    http:/momjian.postgresql.org/cgi-bin/pgpatches2

---------------------------------------------------------------------------

Roger Leigh wrote:
> I have noticed that the latex format in psql has some bugs:
>
> ? "_" is not escaped, and causes TeX to abort, thinking it's a
>   subscript outside of maths mode.  Most of my table and field names
>   use underscores, so this is a really nasty one.
> ? The column count is calculated using the contents of opt_align.  But
>   opt_align has one extra element, and so it's always one too many.  I
>   changed it to count the column headings, like all the other output
>   formats.  There may be a bug in computing opt_align that this patch
>   does not address, but I'm not yet familiar enough with the psql
>   source to fix this as well.
> ? The line drawing rules for each border setting (0-3) and expanded
>   mode didn't always match the documented behaviour and what other
>   formats (e.g. aligned) did.  I made it as conformant as possible,
>   and also tidied the alignment of the first line of the footer, which
>   was incorrectly indented.
>
> I've attached some example output with this patch applied.
>
> Regards,
> Roger
>
>
> Index: src/bin/psql/print.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.c,v
> retrieving revision 1.48
> diff -u -r1.48 print.c
> --- src/bin/psql/print.c    23 May 2004 22:20:10 -0000    1.48
> +++ src/bin/psql/print.c    1 Aug 2004 22:54:22 -0000
> @@ -769,7 +769,7 @@
>
>
>  /*************************/
> -/* LaTeX                 */
> +/* LaTeX         */
>  /*************************/
>
>
> @@ -790,6 +790,9 @@
>              case '$':
>                  fputs("\\$", fout);
>                  break;
> +            case '_':
> +                fputs("\\_", fout);
> +                break;
>              case '{':
>                  fputs("\\{", fout);
>                  break;
> @@ -817,7 +820,6 @@
>  {
>      unsigned int col_count = 0;
>      unsigned int i;
> -    const char *cp;
>      const char *const * ptr;
>
>
> @@ -829,42 +831,39 @@
>          fputs("\n\\end{center}\n\n", fout);
>      }
>
> +    /* count columns */
> +    for (ptr = headers; *ptr; ptr++)
> +        col_count++;
> +
>      /* begin environment and set alignments and borders */
>      fputs("\\begin{tabular}{", fout);
> -    if (opt_border == 0)
> -        fputs(opt_align, fout);
> -    else if (opt_border == 1)
> -    {
> -        for (cp = opt_align; *cp; cp++)
> -        {
> -            if (cp != opt_align)
> -                fputc('|', fout);
> -            fputc(*cp, fout);
> -        }
> -    }
> -    else if (opt_border == 2)
> +
> +    if (opt_border == 2)
> +      fputs("| ", fout);
> +        for (i = 0; i < col_count; i++)
>      {
> -        for (cp = opt_align; *cp; cp++)
> -        {
> -            fputc('|', fout);
> -            fputc(*cp, fout);
> -        }
> -        fputc('|', fout);
> +      fputc(*(opt_align + i), fout);
> +      if (opt_border != 0 && i < col_count - 1)
> +        fputs (" | ", fout);
>      }
> +    if (opt_border == 2)
> +      fputs(" |", fout);
> +
>      fputs("}\n", fout);
>
>      if (!opt_barebones && opt_border == 2)
>          fputs("\\hline\n", fout);
>
>      /* print headers and count columns */
> -    for (i = 0, ptr = headers; *ptr; i++, ptr++)
> +    for (i = 0, ptr = headers; i < col_count; i++, ptr++)
>      {
> -        col_count++;
>          if (!opt_barebones)
>          {
>              if (i != 0)
>                  fputs(" & ", fout);
> +                        fputs("\\textit{", fout);
>              latex_escaped_print(*ptr, fout);
> +                        fputc('}', fout);
>          }
>      }
>
> @@ -888,7 +887,7 @@
>      if (opt_border == 2)
>          fputs("\\hline\n", fout);
>
> -    fputs("\\end{tabular}\n\n", fout);
> +    fputs("\\end{tabular}\n\n\\noindent ", fout);
>
>
>      /* print footers */
> @@ -951,8 +950,12 @@
>              if (!opt_barebones)
>              {
>                  if (opt_border == 2)
> +                {
>                      fputs("\\hline\n", fout);
> -                fprintf(fout, "\\multicolumn{2}{c}{Record %d} \\\\\n", record++);
> +                    fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %d}} \\\\\n", record++);
> +                }
> +                else
> +                    fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %d}} \\\\\n", record++);
>              }
>              if (opt_border >= 1)
>                  fputs("\\hline\n", fout);
> @@ -967,7 +970,7 @@
>      if (opt_border == 2)
>          fputs("\\hline\n", fout);
>
> -    fputs("\\end{tabular}\n\n", fout);
> +    fputs("\\end{tabular}\n\n\\noindent ", fout);
>
>
>      /* print footers */
>
>
>
> --
> Roger Leigh
>
>                 Printing on GNU/Linux?  http://gimp-print.sourceforge.net/
>                 GPG Public Key: 0x25BFB848.  Please sign and encrypt your mail.

Content-Description: psql latex output

[ text/x-tex is unsupported, treating like TEXT/PLAIN ]

> \documentclass[a4paper]{article}
>
> \begin{document}
> \title{Test}
> \maketitle
>
> \section{Normal}
>
> \begin{center}
> Table "public.suites"
> \end{center}
>
> \begin{tabular}{lll}
> \textit{Column} & \textit{Type} & \textit{Modifiers} \\
> \hline
> id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
> name & text & not null \\
> archive\_id & integer & not null \\
> version & text &  \\
> path & text &  \\
> alias & text &  \\
> description & text &  \\
> \end{tabular}
>
> \noindent Indexes: \\
>     "suites\_pkey" PRIMARY KEY, btree (id) \\
>     "suites\_alias\_key" UNIQUE, btree (alias) \\
>     "suites\_name\_key" UNIQUE, btree (name) \\
> Foreign-key constraints: \\
>     "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>
> \begin{center}
> Table "public.suites"
> \end{center}
>
> \begin{tabular}{l | l | l}
> \textit{Column} & \textit{Type} & \textit{Modifiers} \\
> \hline
> id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
> name & text & not null \\
> archive\_id & integer & not null \\
> version & text &  \\
> path & text &  \\
> alias & text &  \\
> description & text &  \\
> \end{tabular}
>
> \noindent Indexes: \\
>     "suites\_pkey" PRIMARY KEY, btree (id) \\
>     "suites\_alias\_key" UNIQUE, btree (alias) \\
>     "suites\_name\_key" UNIQUE, btree (name) \\
> Foreign-key constraints: \\
>     "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>
> \begin{center}
> Table "public.suites"
> \end{center}
>
> \begin{tabular}{| l | l | l |}
> \hline
> \textit{Column} & \textit{Type} & \textit{Modifiers} \\
> \hline
> id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
> name & text & not null \\
> archive\_id & integer & not null \\
> version & text &  \\
> path & text &  \\
> alias & text &  \\
> description & text &  \\
> \hline
> \end{tabular}
>
> \noindent Indexes: \\
>     "suites\_pkey" PRIMARY KEY, btree (id) \\
>     "suites\_alias\_key" UNIQUE, btree (alias) \\
>     "suites\_name\_key" UNIQUE, btree (name) \\
> Foreign-key constraints: \\
>     "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>
> \begin{center}
> Table "public.suites"
> \end{center}
>
> \begin{tabular}{cl}
> \multicolumn{2}{c}{\textit{Record 1}} \\
> Column & id \\
> Type & integer \\
> Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
> \multicolumn{2}{c}{\textit{Record 2}} \\
> Column & name \\
> Type & text \\
> Modifiers & not null \\
> \multicolumn{2}{c}{\textit{Record 3}} \\
> Column & archive\_id \\
> Type & integer \\
> Modifiers & not null \\
> \multicolumn{2}{c}{\textit{Record 4}} \\
> Column & version \\
> Type & text \\
> Modifiers &  \\
> \multicolumn{2}{c}{\textit{Record 5}} \\
> Column & path \\
> Type & text \\
> Modifiers &  \\
> \multicolumn{2}{c}{\textit{Record 6}} \\
> Column & alias \\
> Type & text \\
> Modifiers &  \\
> \multicolumn{2}{c}{\textit{Record 7}} \\
> Column & description \\
> Type & text \\
> Modifiers &  \\
> \end{tabular}
>
> \noindent Indexes: \\
>     "suites\_pkey" PRIMARY KEY, btree (id) \\
>     "suites\_alias\_key" UNIQUE, btree (alias) \\
>     "suites\_name\_key" UNIQUE, btree (name) \\
> Foreign-key constraints: \\
>     "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>
> \begin{center}
> Table "public.suites"
> \end{center}
>
> \begin{tabular}{c|l}
> \multicolumn{2}{c}{\textit{Record 1}} \\
> \hline
> Column & id \\
> Type & integer \\
> Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
> \multicolumn{2}{c}{\textit{Record 2}} \\
> \hline
> Column & name \\
> Type & text \\
> Modifiers & not null \\
> \multicolumn{2}{c}{\textit{Record 3}} \\
> \hline
> Column & archive\_id \\
> Type & integer \\
> Modifiers & not null \\
> \multicolumn{2}{c}{\textit{Record 4}} \\
> \hline
> Column & version \\
> Type & text \\
> Modifiers &  \\
> \multicolumn{2}{c}{\textit{Record 5}} \\
> \hline
> Column & path \\
> Type & text \\
> Modifiers &  \\
> \multicolumn{2}{c}{\textit{Record 6}} \\
> \hline
> Column & alias \\
> Type & text \\
> Modifiers &  \\
> \multicolumn{2}{c}{\textit{Record 7}} \\
> \hline
> Column & description \\
> Type & text \\
> Modifiers &  \\
> \end{tabular}
>
> \noindent Indexes: \\
>     "suites\_pkey" PRIMARY KEY, btree (id) \\
>     "suites\_alias\_key" UNIQUE, btree (alias) \\
>     "suites\_name\_key" UNIQUE, btree (name) \\
> Foreign-key constraints: \\
>     "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>
> \begin{center}
> Table "public.suites"
> \end{center}
>
> \begin{tabular}{|c|l|}
> \hline
> \multicolumn{2}{|c|}{\textit{Record 1}} \\
> \hline
> Column & id \\
> Type & integer \\
> Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
> \hline
> \multicolumn{2}{|c|}{\textit{Record 2}} \\
> \hline
> Column & name \\
> Type & text \\
> Modifiers & not null \\
> \hline
> \multicolumn{2}{|c|}{\textit{Record 3}} \\
> \hline
> Column & archive\_id \\
> Type & integer \\
> Modifiers & not null \\
> \hline
> \multicolumn{2}{|c|}{\textit{Record 4}} \\
> \hline
> Column & version \\
> Type & text \\
> Modifiers &  \\
> \hline
> \multicolumn{2}{|c|}{\textit{Record 5}} \\
> \hline
> Column & path \\
> Type & text \\
> Modifiers &  \\
> \hline
> \multicolumn{2}{|c|}{\textit{Record 6}} \\
> \hline
> Column & alias \\
> Type & text \\
> Modifiers &  \\
> \hline
> \multicolumn{2}{|c|}{\textit{Record 7}} \\
> \hline
> Column & description \\
> Type & text \\
> Modifiers &  \\
> \hline
> \end{tabular}
>
> \noindent Indexes: \\
>     "suites\_pkey" PRIMARY KEY, btree (id) \\
>     "suites\_alias\_key" UNIQUE, btree (alias) \\
>     "suites\_name\_key" UNIQUE, btree (name) \\
> Foreign-key constraints: \\
>     "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>
>
>
> \end{document}
>
> %%% Local Variables:
> %%% mode: latex
> %%% TeX-master: t
> %%% End:

Content-Description: psql latex PDF output

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 9: the planner will ignore your desire to choose an index scan if your
>       joining column's datatypes do not match

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Re: psql latex bugfixes

From
Christopher Kings-Lynne
Date:
Surely this is a really good bug fix and should be in 7.5?

Bruce Momjian wrote:

> This has been saved for the 7.6 release:
>
>     http:/momjian.postgresql.org/cgi-bin/pgpatches2
>
> ---------------------------------------------------------------------------
>
> Roger Leigh wrote:
>
>>I have noticed that the latex format in psql has some bugs:
>>
>>? "_" is not escaped, and causes TeX to abort, thinking it's a
>>  subscript outside of maths mode.  Most of my table and field names
>>  use underscores, so this is a really nasty one.
>>? The column count is calculated using the contents of opt_align.  But
>>  opt_align has one extra element, and so it's always one too many.  I
>>  changed it to count the column headings, like all the other output
>>  formats.  There may be a bug in computing opt_align that this patch
>>  does not address, but I'm not yet familiar enough with the psql
>>  source to fix this as well.
>>? The line drawing rules for each border setting (0-3) and expanded
>>  mode didn't always match the documented behaviour and what other
>>  formats (e.g. aligned) did.  I made it as conformant as possible,
>>  and also tidied the alignment of the first line of the footer, which
>>  was incorrectly indented.
>>
>>I've attached some example output with this patch applied.
>>
>>Regards,
>>Roger
>>
>>
>>Index: src/bin/psql/print.c
>>===================================================================
>>RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.c,v
>>retrieving revision 1.48
>>diff -u -r1.48 print.c
>>--- src/bin/psql/print.c    23 May 2004 22:20:10 -0000    1.48
>>+++ src/bin/psql/print.c    1 Aug 2004 22:54:22 -0000
>>@@ -769,7 +769,7 @@
>>
>>
>> /*************************/
>>-/* LaTeX                 */
>>+/* LaTeX         */
>> /*************************/
>>
>>
>>@@ -790,6 +790,9 @@
>>             case '$':
>>                 fputs("\\$", fout);
>>                 break;
>>+            case '_':
>>+                fputs("\\_", fout);
>>+                break;
>>             case '{':
>>                 fputs("\\{", fout);
>>                 break;
>>@@ -817,7 +820,6 @@
>> {
>>     unsigned int col_count = 0;
>>     unsigned int i;
>>-    const char *cp;
>>     const char *const * ptr;
>>
>>
>>@@ -829,42 +831,39 @@
>>         fputs("\n\\end{center}\n\n", fout);
>>     }
>>
>>+    /* count columns */
>>+    for (ptr = headers; *ptr; ptr++)
>>+        col_count++;
>>+
>>     /* begin environment and set alignments and borders */
>>     fputs("\\begin{tabular}{", fout);
>>-    if (opt_border == 0)
>>-        fputs(opt_align, fout);
>>-    else if (opt_border == 1)
>>-    {
>>-        for (cp = opt_align; *cp; cp++)
>>-        {
>>-            if (cp != opt_align)
>>-                fputc('|', fout);
>>-            fputc(*cp, fout);
>>-        }
>>-    }
>>-    else if (opt_border == 2)
>>+
>>+    if (opt_border == 2)
>>+      fputs("| ", fout);
>>+        for (i = 0; i < col_count; i++)
>>     {
>>-        for (cp = opt_align; *cp; cp++)
>>-        {
>>-            fputc('|', fout);
>>-            fputc(*cp, fout);
>>-        }
>>-        fputc('|', fout);
>>+      fputc(*(opt_align + i), fout);
>>+      if (opt_border != 0 && i < col_count - 1)
>>+        fputs (" | ", fout);
>>     }
>>+    if (opt_border == 2)
>>+      fputs(" |", fout);
>>+
>>     fputs("}\n", fout);
>>
>>     if (!opt_barebones && opt_border == 2)
>>         fputs("\\hline\n", fout);
>>
>>     /* print headers and count columns */
>>-    for (i = 0, ptr = headers; *ptr; i++, ptr++)
>>+    for (i = 0, ptr = headers; i < col_count; i++, ptr++)
>>     {
>>-        col_count++;
>>         if (!opt_barebones)
>>         {
>>             if (i != 0)
>>                 fputs(" & ", fout);
>>+                        fputs("\\textit{", fout);
>>             latex_escaped_print(*ptr, fout);
>>+                        fputc('}', fout);
>>         }
>>     }
>>
>>@@ -888,7 +887,7 @@
>>     if (opt_border == 2)
>>         fputs("\\hline\n", fout);
>>
>>-    fputs("\\end{tabular}\n\n", fout);
>>+    fputs("\\end{tabular}\n\n\\noindent ", fout);
>>
>>
>>     /* print footers */
>>@@ -951,8 +950,12 @@
>>             if (!opt_barebones)
>>             {
>>                 if (opt_border == 2)
>>+                {
>>                     fputs("\\hline\n", fout);
>>-                fprintf(fout, "\\multicolumn{2}{c}{Record %d} \\\\\n", record++);
>>+                    fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %d}} \\\\\n", record++);
>>+                }
>>+                else
>>+                    fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %d}} \\\\\n", record++);
>>             }
>>             if (opt_border >= 1)
>>                 fputs("\\hline\n", fout);
>>@@ -967,7 +970,7 @@
>>     if (opt_border == 2)
>>         fputs("\\hline\n", fout);
>>
>>-    fputs("\\end{tabular}\n\n", fout);
>>+    fputs("\\end{tabular}\n\n\\noindent ", fout);
>>
>>
>>     /* print footers */
>>
>>
>>
>>--
>>Roger Leigh
>>
>>                Printing on GNU/Linux?  http://gimp-print.sourceforge.net/
>>                GPG Public Key: 0x25BFB848.  Please sign and encrypt your mail.
>
>
> Content-Description: psql latex output
>
> [ text/x-tex is unsupported, treating like TEXT/PLAIN ]
>
>
>>\documentclass[a4paper]{article}
>>
>>\begin{document}
>>\title{Test}
>>\maketitle
>>
>>\section{Normal}
>>
>>\begin{center}
>>Table "public.suites"
>>\end{center}
>>
>>\begin{tabular}{lll}
>>\textit{Column} & \textit{Type} & \textit{Modifiers} \\
>>\hline
>>id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
>>name & text & not null \\
>>archive\_id & integer & not null \\
>>version & text &  \\
>>path & text &  \\
>>alias & text &  \\
>>description & text &  \\
>>\end{tabular}
>>
>>\noindent Indexes: \\
>>    "suites\_pkey" PRIMARY KEY, btree (id) \\
>>    "suites\_alias\_key" UNIQUE, btree (alias) \\
>>    "suites\_name\_key" UNIQUE, btree (name) \\
>>Foreign-key constraints: \\
>>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>
>>\begin{center}
>>Table "public.suites"
>>\end{center}
>>
>>\begin{tabular}{l | l | l}
>>\textit{Column} & \textit{Type} & \textit{Modifiers} \\
>>\hline
>>id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
>>name & text & not null \\
>>archive\_id & integer & not null \\
>>version & text &  \\
>>path & text &  \\
>>alias & text &  \\
>>description & text &  \\
>>\end{tabular}
>>
>>\noindent Indexes: \\
>>    "suites\_pkey" PRIMARY KEY, btree (id) \\
>>    "suites\_alias\_key" UNIQUE, btree (alias) \\
>>    "suites\_name\_key" UNIQUE, btree (name) \\
>>Foreign-key constraints: \\
>>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>
>>\begin{center}
>>Table "public.suites"
>>\end{center}
>>
>>\begin{tabular}{| l | l | l |}
>>\hline
>>\textit{Column} & \textit{Type} & \textit{Modifiers} \\
>>\hline
>>id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
>>name & text & not null \\
>>archive\_id & integer & not null \\
>>version & text &  \\
>>path & text &  \\
>>alias & text &  \\
>>description & text &  \\
>>\hline
>>\end{tabular}
>>
>>\noindent Indexes: \\
>>    "suites\_pkey" PRIMARY KEY, btree (id) \\
>>    "suites\_alias\_key" UNIQUE, btree (alias) \\
>>    "suites\_name\_key" UNIQUE, btree (name) \\
>>Foreign-key constraints: \\
>>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>
>>\begin{center}
>>Table "public.suites"
>>\end{center}
>>
>>\begin{tabular}{cl}
>>\multicolumn{2}{c}{\textit{Record 1}} \\
>>Column & id \\
>>Type & integer \\
>>Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
>>\multicolumn{2}{c}{\textit{Record 2}} \\
>>Column & name \\
>>Type & text \\
>>Modifiers & not null \\
>>\multicolumn{2}{c}{\textit{Record 3}} \\
>>Column & archive\_id \\
>>Type & integer \\
>>Modifiers & not null \\
>>\multicolumn{2}{c}{\textit{Record 4}} \\
>>Column & version \\
>>Type & text \\
>>Modifiers &  \\
>>\multicolumn{2}{c}{\textit{Record 5}} \\
>>Column & path \\
>>Type & text \\
>>Modifiers &  \\
>>\multicolumn{2}{c}{\textit{Record 6}} \\
>>Column & alias \\
>>Type & text \\
>>Modifiers &  \\
>>\multicolumn{2}{c}{\textit{Record 7}} \\
>>Column & description \\
>>Type & text \\
>>Modifiers &  \\
>>\end{tabular}
>>
>>\noindent Indexes: \\
>>    "suites\_pkey" PRIMARY KEY, btree (id) \\
>>    "suites\_alias\_key" UNIQUE, btree (alias) \\
>>    "suites\_name\_key" UNIQUE, btree (name) \\
>>Foreign-key constraints: \\
>>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>
>>\begin{center}
>>Table "public.suites"
>>\end{center}
>>
>>\begin{tabular}{c|l}
>>\multicolumn{2}{c}{\textit{Record 1}} \\
>>\hline
>>Column & id \\
>>Type & integer \\
>>Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
>>\multicolumn{2}{c}{\textit{Record 2}} \\
>>\hline
>>Column & name \\
>>Type & text \\
>>Modifiers & not null \\
>>\multicolumn{2}{c}{\textit{Record 3}} \\
>>\hline
>>Column & archive\_id \\
>>Type & integer \\
>>Modifiers & not null \\
>>\multicolumn{2}{c}{\textit{Record 4}} \\
>>\hline
>>Column & version \\
>>Type & text \\
>>Modifiers &  \\
>>\multicolumn{2}{c}{\textit{Record 5}} \\
>>\hline
>>Column & path \\
>>Type & text \\
>>Modifiers &  \\
>>\multicolumn{2}{c}{\textit{Record 6}} \\
>>\hline
>>Column & alias \\
>>Type & text \\
>>Modifiers &  \\
>>\multicolumn{2}{c}{\textit{Record 7}} \\
>>\hline
>>Column & description \\
>>Type & text \\
>>Modifiers &  \\
>>\end{tabular}
>>
>>\noindent Indexes: \\
>>    "suites\_pkey" PRIMARY KEY, btree (id) \\
>>    "suites\_alias\_key" UNIQUE, btree (alias) \\
>>    "suites\_name\_key" UNIQUE, btree (name) \\
>>Foreign-key constraints: \\
>>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>
>>\begin{center}
>>Table "public.suites"
>>\end{center}
>>
>>\begin{tabular}{|c|l|}
>>\hline
>>\multicolumn{2}{|c|}{\textit{Record 1}} \\
>>\hline
>>Column & id \\
>>Type & integer \\
>>Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
>>\hline
>>\multicolumn{2}{|c|}{\textit{Record 2}} \\
>>\hline
>>Column & name \\
>>Type & text \\
>>Modifiers & not null \\
>>\hline
>>\multicolumn{2}{|c|}{\textit{Record 3}} \\
>>\hline
>>Column & archive\_id \\
>>Type & integer \\
>>Modifiers & not null \\
>>\hline
>>\multicolumn{2}{|c|}{\textit{Record 4}} \\
>>\hline
>>Column & version \\
>>Type & text \\
>>Modifiers &  \\
>>\hline
>>\multicolumn{2}{|c|}{\textit{Record 5}} \\
>>\hline
>>Column & path \\
>>Type & text \\
>>Modifiers &  \\
>>\hline
>>\multicolumn{2}{|c|}{\textit{Record 6}} \\
>>\hline
>>Column & alias \\
>>Type & text \\
>>Modifiers &  \\
>>\hline
>>\multicolumn{2}{|c|}{\textit{Record 7}} \\
>>\hline
>>Column & description \\
>>Type & text \\
>>Modifiers &  \\
>>\hline
>>\end{tabular}
>>
>>\noindent Indexes: \\
>>    "suites\_pkey" PRIMARY KEY, btree (id) \\
>>    "suites\_alias\_key" UNIQUE, btree (alias) \\
>>    "suites\_name\_key" UNIQUE, btree (name) \\
>>Foreign-key constraints: \\
>>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>
>>
>>
>>\end{document}
>>
>>%%% Local Variables:
>>%%% mode: latex
>>%%% TeX-master: t
>>%%% End:
>
>
> Content-Description: psql latex PDF output
>
> [ Attachment, skipping... ]
>
>
>>---------------------------(end of broadcast)---------------------------
>>TIP 9: the planner will ignore your desire to choose an index scan if your
>>      joining column's datatypes do not match
>
>

Re: psql latex bugfixes

From
Bruce Momjian
Date:
If you would like to review it I will apply it.

---------------------------------------------------------------------------

Christopher Kings-Lynne wrote:
> Surely this is a really good bug fix and should be in 7.5?
>
> Bruce Momjian wrote:
>
> > This has been saved for the 7.6 release:
> >
> >     http:/momjian.postgresql.org/cgi-bin/pgpatches2
> >
> > ---------------------------------------------------------------------------
> >
> > Roger Leigh wrote:
> >
> >>I have noticed that the latex format in psql has some bugs:
> >>
> >>? "_" is not escaped, and causes TeX to abort, thinking it's a
> >>  subscript outside of maths mode.  Most of my table and field names
> >>  use underscores, so this is a really nasty one.
> >>? The column count is calculated using the contents of opt_align.  But
> >>  opt_align has one extra element, and so it's always one too many.  I
> >>  changed it to count the column headings, like all the other output
> >>  formats.  There may be a bug in computing opt_align that this patch
> >>  does not address, but I'm not yet familiar enough with the psql
> >>  source to fix this as well.
> >>? The line drawing rules for each border setting (0-3) and expanded
> >>  mode didn't always match the documented behaviour and what other
> >>  formats (e.g. aligned) did.  I made it as conformant as possible,
> >>  and also tidied the alignment of the first line of the footer, which
> >>  was incorrectly indented.
> >>
> >>I've attached some example output with this patch applied.
> >>
> >>Regards,
> >>Roger
> >>
> >>
> >>Index: src/bin/psql/print.c
> >>===================================================================
> >>RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.c,v
> >>retrieving revision 1.48
> >>diff -u -r1.48 print.c
> >>--- src/bin/psql/print.c    23 May 2004 22:20:10 -0000    1.48
> >>+++ src/bin/psql/print.c    1 Aug 2004 22:54:22 -0000
> >>@@ -769,7 +769,7 @@
> >>
> >>
> >> /*************************/
> >>-/* LaTeX                 */
> >>+/* LaTeX         */
> >> /*************************/
> >>
> >>
> >>@@ -790,6 +790,9 @@
> >>             case '$':
> >>                 fputs("\\$", fout);
> >>                 break;
> >>+            case '_':
> >>+                fputs("\\_", fout);
> >>+                break;
> >>             case '{':
> >>                 fputs("\\{", fout);
> >>                 break;
> >>@@ -817,7 +820,6 @@
> >> {
> >>     unsigned int col_count = 0;
> >>     unsigned int i;
> >>-    const char *cp;
> >>     const char *const * ptr;
> >>
> >>
> >>@@ -829,42 +831,39 @@
> >>         fputs("\n\\end{center}\n\n", fout);
> >>     }
> >>
> >>+    /* count columns */
> >>+    for (ptr = headers; *ptr; ptr++)
> >>+        col_count++;
> >>+
> >>     /* begin environment and set alignments and borders */
> >>     fputs("\\begin{tabular}{", fout);
> >>-    if (opt_border == 0)
> >>-        fputs(opt_align, fout);
> >>-    else if (opt_border == 1)
> >>-    {
> >>-        for (cp = opt_align; *cp; cp++)
> >>-        {
> >>-            if (cp != opt_align)
> >>-                fputc('|', fout);
> >>-            fputc(*cp, fout);
> >>-        }
> >>-    }
> >>-    else if (opt_border == 2)
> >>+
> >>+    if (opt_border == 2)
> >>+      fputs("| ", fout);
> >>+        for (i = 0; i < col_count; i++)
> >>     {
> >>-        for (cp = opt_align; *cp; cp++)
> >>-        {
> >>-            fputc('|', fout);
> >>-            fputc(*cp, fout);
> >>-        }
> >>-        fputc('|', fout);
> >>+      fputc(*(opt_align + i), fout);
> >>+      if (opt_border != 0 && i < col_count - 1)
> >>+        fputs (" | ", fout);
> >>     }
> >>+    if (opt_border == 2)
> >>+      fputs(" |", fout);
> >>+
> >>     fputs("}\n", fout);
> >>
> >>     if (!opt_barebones && opt_border == 2)
> >>         fputs("\\hline\n", fout);
> >>
> >>     /* print headers and count columns */
> >>-    for (i = 0, ptr = headers; *ptr; i++, ptr++)
> >>+    for (i = 0, ptr = headers; i < col_count; i++, ptr++)
> >>     {
> >>-        col_count++;
> >>         if (!opt_barebones)
> >>         {
> >>             if (i != 0)
> >>                 fputs(" & ", fout);
> >>+                        fputs("\\textit{", fout);
> >>             latex_escaped_print(*ptr, fout);
> >>+                        fputc('}', fout);
> >>         }
> >>     }
> >>
> >>@@ -888,7 +887,7 @@
> >>     if (opt_border == 2)
> >>         fputs("\\hline\n", fout);
> >>
> >>-    fputs("\\end{tabular}\n\n", fout);
> >>+    fputs("\\end{tabular}\n\n\\noindent ", fout);
> >>
> >>
> >>     /* print footers */
> >>@@ -951,8 +950,12 @@
> >>             if (!opt_barebones)
> >>             {
> >>                 if (opt_border == 2)
> >>+                {
> >>                     fputs("\\hline\n", fout);
> >>-                fprintf(fout, "\\multicolumn{2}{c}{Record %d} \\\\\n", record++);
> >>+                    fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %d}} \\\\\n", record++);
> >>+                }
> >>+                else
> >>+                    fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %d}} \\\\\n", record++);
> >>             }
> >>             if (opt_border >= 1)
> >>                 fputs("\\hline\n", fout);
> >>@@ -967,7 +970,7 @@
> >>     if (opt_border == 2)
> >>         fputs("\\hline\n", fout);
> >>
> >>-    fputs("\\end{tabular}\n\n", fout);
> >>+    fputs("\\end{tabular}\n\n\\noindent ", fout);
> >>
> >>
> >>     /* print footers */
> >>
> >>
> >>
> >>--
> >>Roger Leigh
> >>
> >>                Printing on GNU/Linux?  http://gimp-print.sourceforge.net/
> >>                GPG Public Key: 0x25BFB848.  Please sign and encrypt your mail.
> >
> >
> > Content-Description: psql latex output
> >
> > [ text/x-tex is unsupported, treating like TEXT/PLAIN ]
> >
> >
> >>\documentclass[a4paper]{article}
> >>
> >>\begin{document}
> >>\title{Test}
> >>\maketitle
> >>
> >>\section{Normal}
> >>
> >>\begin{center}
> >>Table "public.suites"
> >>\end{center}
> >>
> >>\begin{tabular}{lll}
> >>\textit{Column} & \textit{Type} & \textit{Modifiers} \\
> >>\hline
> >>id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
> >>name & text & not null \\
> >>archive\_id & integer & not null \\
> >>version & text &  \\
> >>path & text &  \\
> >>alias & text &  \\
> >>description & text &  \\
> >>\end{tabular}
> >>
> >>\noindent Indexes: \\
> >>    "suites\_pkey" PRIMARY KEY, btree (id) \\
> >>    "suites\_alias\_key" UNIQUE, btree (alias) \\
> >>    "suites\_name\_key" UNIQUE, btree (name) \\
> >>Foreign-key constraints: \\
> >>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
> >>
> >>\begin{center}
> >>Table "public.suites"
> >>\end{center}
> >>
> >>\begin{tabular}{l | l | l}
> >>\textit{Column} & \textit{Type} & \textit{Modifiers} \\
> >>\hline
> >>id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
> >>name & text & not null \\
> >>archive\_id & integer & not null \\
> >>version & text &  \\
> >>path & text &  \\
> >>alias & text &  \\
> >>description & text &  \\
> >>\end{tabular}
> >>
> >>\noindent Indexes: \\
> >>    "suites\_pkey" PRIMARY KEY, btree (id) \\
> >>    "suites\_alias\_key" UNIQUE, btree (alias) \\
> >>    "suites\_name\_key" UNIQUE, btree (name) \\
> >>Foreign-key constraints: \\
> >>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
> >>
> >>\begin{center}
> >>Table "public.suites"
> >>\end{center}
> >>
> >>\begin{tabular}{| l | l | l |}
> >>\hline
> >>\textit{Column} & \textit{Type} & \textit{Modifiers} \\
> >>\hline
> >>id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
> >>name & text & not null \\
> >>archive\_id & integer & not null \\
> >>version & text &  \\
> >>path & text &  \\
> >>alias & text &  \\
> >>description & text &  \\
> >>\hline
> >>\end{tabular}
> >>
> >>\noindent Indexes: \\
> >>    "suites\_pkey" PRIMARY KEY, btree (id) \\
> >>    "suites\_alias\_key" UNIQUE, btree (alias) \\
> >>    "suites\_name\_key" UNIQUE, btree (name) \\
> >>Foreign-key constraints: \\
> >>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
> >>
> >>\begin{center}
> >>Table "public.suites"
> >>\end{center}
> >>
> >>\begin{tabular}{cl}
> >>\multicolumn{2}{c}{\textit{Record 1}} \\
> >>Column & id \\
> >>Type & integer \\
> >>Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
> >>\multicolumn{2}{c}{\textit{Record 2}} \\
> >>Column & name \\
> >>Type & text \\
> >>Modifiers & not null \\
> >>\multicolumn{2}{c}{\textit{Record 3}} \\
> >>Column & archive\_id \\
> >>Type & integer \\
> >>Modifiers & not null \\
> >>\multicolumn{2}{c}{\textit{Record 4}} \\
> >>Column & version \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\multicolumn{2}{c}{\textit{Record 5}} \\
> >>Column & path \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\multicolumn{2}{c}{\textit{Record 6}} \\
> >>Column & alias \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\multicolumn{2}{c}{\textit{Record 7}} \\
> >>Column & description \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\end{tabular}
> >>
> >>\noindent Indexes: \\
> >>    "suites\_pkey" PRIMARY KEY, btree (id) \\
> >>    "suites\_alias\_key" UNIQUE, btree (alias) \\
> >>    "suites\_name\_key" UNIQUE, btree (name) \\
> >>Foreign-key constraints: \\
> >>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
> >>
> >>\begin{center}
> >>Table "public.suites"
> >>\end{center}
> >>
> >>\begin{tabular}{c|l}
> >>\multicolumn{2}{c}{\textit{Record 1}} \\
> >>\hline
> >>Column & id \\
> >>Type & integer \\
> >>Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
> >>\multicolumn{2}{c}{\textit{Record 2}} \\
> >>\hline
> >>Column & name \\
> >>Type & text \\
> >>Modifiers & not null \\
> >>\multicolumn{2}{c}{\textit{Record 3}} \\
> >>\hline
> >>Column & archive\_id \\
> >>Type & integer \\
> >>Modifiers & not null \\
> >>\multicolumn{2}{c}{\textit{Record 4}} \\
> >>\hline
> >>Column & version \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\multicolumn{2}{c}{\textit{Record 5}} \\
> >>\hline
> >>Column & path \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\multicolumn{2}{c}{\textit{Record 6}} \\
> >>\hline
> >>Column & alias \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\multicolumn{2}{c}{\textit{Record 7}} \\
> >>\hline
> >>Column & description \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\end{tabular}
> >>
> >>\noindent Indexes: \\
> >>    "suites\_pkey" PRIMARY KEY, btree (id) \\
> >>    "suites\_alias\_key" UNIQUE, btree (alias) \\
> >>    "suites\_name\_key" UNIQUE, btree (name) \\
> >>Foreign-key constraints: \\
> >>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
> >>
> >>\begin{center}
> >>Table "public.suites"
> >>\end{center}
> >>
> >>\begin{tabular}{|c|l|}
> >>\hline
> >>\multicolumn{2}{|c|}{\textit{Record 1}} \\
> >>\hline
> >>Column & id \\
> >>Type & integer \\
> >>Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
> >>\hline
> >>\multicolumn{2}{|c|}{\textit{Record 2}} \\
> >>\hline
> >>Column & name \\
> >>Type & text \\
> >>Modifiers & not null \\
> >>\hline
> >>\multicolumn{2}{|c|}{\textit{Record 3}} \\
> >>\hline
> >>Column & archive\_id \\
> >>Type & integer \\
> >>Modifiers & not null \\
> >>\hline
> >>\multicolumn{2}{|c|}{\textit{Record 4}} \\
> >>\hline
> >>Column & version \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\hline
> >>\multicolumn{2}{|c|}{\textit{Record 5}} \\
> >>\hline
> >>Column & path \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\hline
> >>\multicolumn{2}{|c|}{\textit{Record 6}} \\
> >>\hline
> >>Column & alias \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\hline
> >>\multicolumn{2}{|c|}{\textit{Record 7}} \\
> >>\hline
> >>Column & description \\
> >>Type & text \\
> >>Modifiers &  \\
> >>\hline
> >>\end{tabular}
> >>
> >>\noindent Indexes: \\
> >>    "suites\_pkey" PRIMARY KEY, btree (id) \\
> >>    "suites\_alias\_key" UNIQUE, btree (alias) \\
> >>    "suites\_name\_key" UNIQUE, btree (name) \\
> >>Foreign-key constraints: \\
> >>    "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
> >>
> >>
> >>
> >>\end{document}
> >>
> >>%%% Local Variables:
> >>%%% mode: latex
> >>%%% TeX-master: t
> >>%%% End:
> >
> >
> > Content-Description: psql latex PDF output
> >
> > [ Attachment, skipping... ]
> >
> >
> >>---------------------------(end of broadcast)---------------------------
> >>TIP 9: the planner will ignore your desire to choose an index scan if your
> >>      joining column's datatypes do not match
> >
> >
>

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Re: psql latex bugfixes

From
Christopher Kings-Lynne
Date:
OK, when I find a moment.

Bruce Momjian wrote:

> If you would like to review it I will apply it.


Re: psql latex bugfixes

From
Tom Lane
Date:
Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes:
> Surely this is a really good bug fix and should be in 7.5?

The original patch contained both bug fixes for the LaTeX mode and an
entire new output mode (troff).  At my suggestion, Roger split out the
bug-fix parts as a separate patch.  The new output mode does need to
wait for 7.6^H^H^H8.1, but I think we should accept this patch for
this cycle (pending review of course).

I was thinking Peter would be the most likely candidate to review the
patch, since IIRC he was the last guy to touch this stuff.  But if
he doesn't have time and you do, go for it ...

            regards, tom lane

Re: psql latex bugfixes

From
Christopher Kings-Lynne
Date:
OK, it looks good.  I don't have latex handy to build it, but it looks
fine to me...

Chris

Bruce Momjian wrote:

> If you would like to review it I will apply it.
>
> ---------------------------------------------------------------------------
>
> Christopher Kings-Lynne wrote:
>
>>Surely this is a really good bug fix and should be in 7.5?
>>
>>Bruce Momjian wrote:
>>
>>
>>>This has been saved for the 7.6 release:
>>>
>>>    http:/momjian.postgresql.org/cgi-bin/pgpatches2
>>>
>>>---------------------------------------------------------------------------
>>>
>>>Roger Leigh wrote:
>>>
>>>
>>>>I have noticed that the latex format in psql has some bugs:
>>>>
>>>>? "_" is not escaped, and causes TeX to abort, thinking it's a
>>>> subscript outside of maths mode.  Most of my table and field names
>>>> use underscores, so this is a really nasty one.
>>>>? The column count is calculated using the contents of opt_align.  But
>>>> opt_align has one extra element, and so it's always one too many.  I
>>>> changed it to count the column headings, like all the other output
>>>> formats.  There may be a bug in computing opt_align that this patch
>>>> does not address, but I'm not yet familiar enough with the psql
>>>> source to fix this as well.
>>>>? The line drawing rules for each border setting (0-3) and expanded
>>>> mode didn't always match the documented behaviour and what other
>>>> formats (e.g. aligned) did.  I made it as conformant as possible,
>>>> and also tidied the alignment of the first line of the footer, which
>>>> was incorrectly indented.
>>>>
>>>>I've attached some example output with this patch applied.
>>>>
>>>>Regards,
>>>>Roger
>>>>
>>>>
>>>>Index: src/bin/psql/print.c
>>>>===================================================================
>>>>RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.c,v
>>>>retrieving revision 1.48
>>>>diff -u -r1.48 print.c
>>>>--- src/bin/psql/print.c    23 May 2004 22:20:10 -0000    1.48
>>>>+++ src/bin/psql/print.c    1 Aug 2004 22:54:22 -0000
>>>>@@ -769,7 +769,7 @@
>>>>
>>>>
>>>>/*************************/
>>>>-/* LaTeX                 */
>>>>+/* LaTeX         */
>>>>/*************************/
>>>>
>>>>
>>>>@@ -790,6 +790,9 @@
>>>>            case '$':
>>>>                fputs("\\$", fout);
>>>>                break;
>>>>+            case '_':
>>>>+                fputs("\\_", fout);
>>>>+                break;
>>>>            case '{':
>>>>                fputs("\\{", fout);
>>>>                break;
>>>>@@ -817,7 +820,6 @@
>>>>{
>>>>    unsigned int col_count = 0;
>>>>    unsigned int i;
>>>>-    const char *cp;
>>>>    const char *const * ptr;
>>>>
>>>>
>>>>@@ -829,42 +831,39 @@
>>>>        fputs("\n\\end{center}\n\n", fout);
>>>>    }
>>>>
>>>>+    /* count columns */
>>>>+    for (ptr = headers; *ptr; ptr++)
>>>>+        col_count++;
>>>>+
>>>>    /* begin environment and set alignments and borders */
>>>>    fputs("\\begin{tabular}{", fout);
>>>>-    if (opt_border == 0)
>>>>-        fputs(opt_align, fout);
>>>>-    else if (opt_border == 1)
>>>>-    {
>>>>-        for (cp = opt_align; *cp; cp++)
>>>>-        {
>>>>-            if (cp != opt_align)
>>>>-                fputc('|', fout);
>>>>-            fputc(*cp, fout);
>>>>-        }
>>>>-    }
>>>>-    else if (opt_border == 2)
>>>>+
>>>>+    if (opt_border == 2)
>>>>+      fputs("| ", fout);
>>>>+        for (i = 0; i < col_count; i++)
>>>>    {
>>>>-        for (cp = opt_align; *cp; cp++)
>>>>-        {
>>>>-            fputc('|', fout);
>>>>-            fputc(*cp, fout);
>>>>-        }
>>>>-        fputc('|', fout);
>>>>+      fputc(*(opt_align + i), fout);
>>>>+      if (opt_border != 0 && i < col_count - 1)
>>>>+        fputs (" | ", fout);
>>>>    }
>>>>+    if (opt_border == 2)
>>>>+      fputs(" |", fout);
>>>>+
>>>>    fputs("}\n", fout);
>>>>
>>>>    if (!opt_barebones && opt_border == 2)
>>>>        fputs("\\hline\n", fout);
>>>>
>>>>    /* print headers and count columns */
>>>>-    for (i = 0, ptr = headers; *ptr; i++, ptr++)
>>>>+    for (i = 0, ptr = headers; i < col_count; i++, ptr++)
>>>>    {
>>>>-        col_count++;
>>>>        if (!opt_barebones)
>>>>        {
>>>>            if (i != 0)
>>>>                fputs(" & ", fout);
>>>>+                        fputs("\\textit{", fout);
>>>>            latex_escaped_print(*ptr, fout);
>>>>+                        fputc('}', fout);
>>>>        }
>>>>    }
>>>>
>>>>@@ -888,7 +887,7 @@
>>>>    if (opt_border == 2)
>>>>        fputs("\\hline\n", fout);
>>>>
>>>>-    fputs("\\end{tabular}\n\n", fout);
>>>>+    fputs("\\end{tabular}\n\n\\noindent ", fout);
>>>>
>>>>
>>>>    /* print footers */
>>>>@@ -951,8 +950,12 @@
>>>>            if (!opt_barebones)
>>>>            {
>>>>                if (opt_border == 2)
>>>>+                {
>>>>                    fputs("\\hline\n", fout);
>>>>-                fprintf(fout, "\\multicolumn{2}{c}{Record %d} \\\\\n", record++);
>>>>+                    fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %d}} \\\\\n", record++);
>>>>+                }
>>>>+                else
>>>>+                    fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %d}} \\\\\n", record++);
>>>>            }
>>>>            if (opt_border >= 1)
>>>>                fputs("\\hline\n", fout);
>>>>@@ -967,7 +970,7 @@
>>>>    if (opt_border == 2)
>>>>        fputs("\\hline\n", fout);
>>>>
>>>>-    fputs("\\end{tabular}\n\n", fout);
>>>>+    fputs("\\end{tabular}\n\n\\noindent ", fout);
>>>>
>>>>
>>>>    /* print footers */
>>>>
>>>>
>>>>
>>>>--
>>>>Roger Leigh
>>>>
>>>>               Printing on GNU/Linux?  http://gimp-print.sourceforge.net/
>>>>               GPG Public Key: 0x25BFB848.  Please sign and encrypt your mail.
>>>
>>>
>>>Content-Description: psql latex output
>>>
>>>[ text/x-tex is unsupported, treating like TEXT/PLAIN ]
>>>
>>>
>>>
>>>>\documentclass[a4paper]{article}
>>>>
>>>>\begin{document}
>>>>\title{Test}
>>>>\maketitle
>>>>
>>>>\section{Normal}
>>>>
>>>>\begin{center}
>>>>Table "public.suites"
>>>>\end{center}
>>>>
>>>>\begin{tabular}{lll}
>>>>\textit{Column} & \textit{Type} & \textit{Modifiers} \\
>>>>\hline
>>>>id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
>>>>name & text & not null \\
>>>>archive\_id & integer & not null \\
>>>>version & text &  \\
>>>>path & text &  \\
>>>>alias & text &  \\
>>>>description & text &  \\
>>>>\end{tabular}
>>>>
>>>>\noindent Indexes: \\
>>>>   "suites\_pkey" PRIMARY KEY, btree (id) \\
>>>>   "suites\_alias\_key" UNIQUE, btree (alias) \\
>>>>   "suites\_name\_key" UNIQUE, btree (name) \\
>>>>Foreign-key constraints: \\
>>>>   "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>>>
>>>>\begin{center}
>>>>Table "public.suites"
>>>>\end{center}
>>>>
>>>>\begin{tabular}{l | l | l}
>>>>\textit{Column} & \textit{Type} & \textit{Modifiers} \\
>>>>\hline
>>>>id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
>>>>name & text & not null \\
>>>>archive\_id & integer & not null \\
>>>>version & text &  \\
>>>>path & text &  \\
>>>>alias & text &  \\
>>>>description & text &  \\
>>>>\end{tabular}
>>>>
>>>>\noindent Indexes: \\
>>>>   "suites\_pkey" PRIMARY KEY, btree (id) \\
>>>>   "suites\_alias\_key" UNIQUE, btree (alias) \\
>>>>   "suites\_name\_key" UNIQUE, btree (name) \\
>>>>Foreign-key constraints: \\
>>>>   "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>>>
>>>>\begin{center}
>>>>Table "public.suites"
>>>>\end{center}
>>>>
>>>>\begin{tabular}{| l | l | l |}
>>>>\hline
>>>>\textit{Column} & \textit{Type} & \textit{Modifiers} \\
>>>>\hline
>>>>id & integer & not null default nextval('public.suites\_id\_seq'::text) \\
>>>>name & text & not null \\
>>>>archive\_id & integer & not null \\
>>>>version & text &  \\
>>>>path & text &  \\
>>>>alias & text &  \\
>>>>description & text &  \\
>>>>\hline
>>>>\end{tabular}
>>>>
>>>>\noindent Indexes: \\
>>>>   "suites\_pkey" PRIMARY KEY, btree (id) \\
>>>>   "suites\_alias\_key" UNIQUE, btree (alias) \\
>>>>   "suites\_name\_key" UNIQUE, btree (name) \\
>>>>Foreign-key constraints: \\
>>>>   "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>>>
>>>>\begin{center}
>>>>Table "public.suites"
>>>>\end{center}
>>>>
>>>>\begin{tabular}{cl}
>>>>\multicolumn{2}{c}{\textit{Record 1}} \\
>>>>Column & id \\
>>>>Type & integer \\
>>>>Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
>>>>\multicolumn{2}{c}{\textit{Record 2}} \\
>>>>Column & name \\
>>>>Type & text \\
>>>>Modifiers & not null \\
>>>>\multicolumn{2}{c}{\textit{Record 3}} \\
>>>>Column & archive\_id \\
>>>>Type & integer \\
>>>>Modifiers & not null \\
>>>>\multicolumn{2}{c}{\textit{Record 4}} \\
>>>>Column & version \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\multicolumn{2}{c}{\textit{Record 5}} \\
>>>>Column & path \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\multicolumn{2}{c}{\textit{Record 6}} \\
>>>>Column & alias \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\multicolumn{2}{c}{\textit{Record 7}} \\
>>>>Column & description \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\end{tabular}
>>>>
>>>>\noindent Indexes: \\
>>>>   "suites\_pkey" PRIMARY KEY, btree (id) \\
>>>>   "suites\_alias\_key" UNIQUE, btree (alias) \\
>>>>   "suites\_name\_key" UNIQUE, btree (name) \\
>>>>Foreign-key constraints: \\
>>>>   "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>>>
>>>>\begin{center}
>>>>Table "public.suites"
>>>>\end{center}
>>>>
>>>>\begin{tabular}{c|l}
>>>>\multicolumn{2}{c}{\textit{Record 1}} \\
>>>>\hline
>>>>Column & id \\
>>>>Type & integer \\
>>>>Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
>>>>\multicolumn{2}{c}{\textit{Record 2}} \\
>>>>\hline
>>>>Column & name \\
>>>>Type & text \\
>>>>Modifiers & not null \\
>>>>\multicolumn{2}{c}{\textit{Record 3}} \\
>>>>\hline
>>>>Column & archive\_id \\
>>>>Type & integer \\
>>>>Modifiers & not null \\
>>>>\multicolumn{2}{c}{\textit{Record 4}} \\
>>>>\hline
>>>>Column & version \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\multicolumn{2}{c}{\textit{Record 5}} \\
>>>>\hline
>>>>Column & path \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\multicolumn{2}{c}{\textit{Record 6}} \\
>>>>\hline
>>>>Column & alias \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\multicolumn{2}{c}{\textit{Record 7}} \\
>>>>\hline
>>>>Column & description \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\end{tabular}
>>>>
>>>>\noindent Indexes: \\
>>>>   "suites\_pkey" PRIMARY KEY, btree (id) \\
>>>>   "suites\_alias\_key" UNIQUE, btree (alias) \\
>>>>   "suites\_name\_key" UNIQUE, btree (name) \\
>>>>Foreign-key constraints: \\
>>>>   "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>>>
>>>>\begin{center}
>>>>Table "public.suites"
>>>>\end{center}
>>>>
>>>>\begin{tabular}{|c|l|}
>>>>\hline
>>>>\multicolumn{2}{|c|}{\textit{Record 1}} \\
>>>>\hline
>>>>Column & id \\
>>>>Type & integer \\
>>>>Modifiers & not null default nextval('public.suites\_id\_seq'::text) \\
>>>>\hline
>>>>\multicolumn{2}{|c|}{\textit{Record 2}} \\
>>>>\hline
>>>>Column & name \\
>>>>Type & text \\
>>>>Modifiers & not null \\
>>>>\hline
>>>>\multicolumn{2}{|c|}{\textit{Record 3}} \\
>>>>\hline
>>>>Column & archive\_id \\
>>>>Type & integer \\
>>>>Modifiers & not null \\
>>>>\hline
>>>>\multicolumn{2}{|c|}{\textit{Record 4}} \\
>>>>\hline
>>>>Column & version \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\hline
>>>>\multicolumn{2}{|c|}{\textit{Record 5}} \\
>>>>\hline
>>>>Column & path \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\hline
>>>>\multicolumn{2}{|c|}{\textit{Record 6}} \\
>>>>\hline
>>>>Column & alias \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\hline
>>>>\multicolumn{2}{|c|}{\textit{Record 7}} \\
>>>>\hline
>>>>Column & description \\
>>>>Type & text \\
>>>>Modifiers &  \\
>>>>\hline
>>>>\end{tabular}
>>>>
>>>>\noindent Indexes: \\
>>>>   "suites\_pkey" PRIMARY KEY, btree (id) \\
>>>>   "suites\_alias\_key" UNIQUE, btree (alias) \\
>>>>   "suites\_name\_key" UNIQUE, btree (name) \\
>>>>Foreign-key constraints: \\
>>>>   "suites\_archive\_ref" FOREIGN KEY (archive\_id) REFERENCES archives(id) \\
>>>>
>>>>
>>>>
>>>>\end{document}
>>>>
>>>>%%% Local Variables:
>>>>%%% mode: latex
>>>>%%% TeX-master: t
>>>>%%% End:
>>>
>>>
>>>Content-Description: psql latex PDF output
>>>
>>>[ Attachment, skipping... ]
>>>
>>>
>>>
>>>>---------------------------(end of broadcast)---------------------------
>>>>TIP 9: the planner will ignore your desire to choose an index scan if your
>>>>     joining column's datatypes do not match
>>>
>>>
>

Re: psql latex bugfixes

From
Bruce Momjian
Date:
Patch applied for 8.0.  Thanks.

---------------------------------------------------------------------------



Roger Leigh wrote:
> I have noticed that the latex format in psql has some bugs:
>
> ? "_" is not escaped, and causes TeX to abort, thinking it's a
>   subscript outside of maths mode.  Most of my table and field names
>   use underscores, so this is a really nasty one.
> ? The column count is calculated using the contents of opt_align.  But
>   opt_align has one extra element, and so it's always one too many.  I
>   changed it to count the column headings, like all the other output
>   formats.  There may be a bug in computing opt_align that this patch
>   does not address, but I'm not yet familiar enough with the psql
>   source to fix this as well.
> ? The line drawing rules for each border setting (0-3) and expanded
>   mode didn't always match the documented behaviour and what other
>   formats (e.g. aligned) did.  I made it as conformant as possible,
>   and also tidied the alignment of the first line of the footer, which
>   was incorrectly indented.
>
> I've attached some example output with this patch applied.
>
> Regards,
> Roger
>
>
> Index: src/bin/psql/print.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/print.c,v
> retrieving revision 1.48
> diff -u -r1.48 print.c
> --- src/bin/psql/print.c    23 May 2004 22:20:10 -0000    1.48
> +++ src/bin/psql/print.c    1 Aug 2004 22:54:22 -0000
> @@ -769,7 +769,7 @@
>
>
>  /*************************/
> -/* LaTeX                 */
> +/* LaTeX         */
>  /*************************/
>
>
> @@ -790,6 +790,9 @@
>              case '$':
>                  fputs("\\$", fout);
>                  break;
> +            case '_':
> +                fputs("\\_", fout);
> +                break;
>              case '{':
>                  fputs("\\{", fout);
>                  break;
> @@ -817,7 +820,6 @@
>  {
>      unsigned int col_count = 0;
>      unsigned int i;
> -    const char *cp;
>      const char *const * ptr;
>
>
> @@ -829,42 +831,39 @@
>          fputs("\n\\end{center}\n\n", fout);
>      }
>
> +    /* count columns */
> +    for (ptr = headers; *ptr; ptr++)
> +        col_count++;
> +
>      /* begin environment and set alignments and borders */
>      fputs("\\begin{tabular}{", fout);
> -    if (opt_border == 0)
> -        fputs(opt_align, fout);
> -    else if (opt_border == 1)
> -    {
> -        for (cp = opt_align; *cp; cp++)
> -        {
> -            if (cp != opt_align)
> -                fputc('|', fout);
> -            fputc(*cp, fout);
> -        }
> -    }
> -    else if (opt_border == 2)
> +
> +    if (opt_border == 2)
> +      fputs("| ", fout);
> +        for (i = 0; i < col_count; i++)
>      {
> -        for (cp = opt_align; *cp; cp++)
> -        {
> -            fputc('|', fout);
> -            fputc(*cp, fout);
> -        }
> -        fputc('|', fout);
> +      fputc(*(opt_align + i), fout);
> +      if (opt_border != 0 && i < col_count - 1)
> +        fputs (" | ", fout);
>      }
> +    if (opt_border == 2)
> +      fputs(" |", fout);
> +
>      fputs("}\n", fout);
>
>      if (!opt_barebones && opt_border == 2)
>          fputs("\\hline\n", fout);
>
>      /* print headers and count columns */
> -    for (i = 0, ptr = headers; *ptr; i++, ptr++)
> +    for (i = 0, ptr = headers; i < col_count; i++, ptr++)
>      {
> -        col_count++;
>          if (!opt_barebones)
>          {
>              if (i != 0)
>                  fputs(" & ", fout);
> +                        fputs("\\textit{", fout);
>              latex_escaped_print(*ptr, fout);
> +                        fputc('}', fout);
>          }
>      }
>
> @@ -888,7 +887,7 @@
>      if (opt_border == 2)
>          fputs("\\hline\n", fout);
>
> -    fputs("\\end{tabular}\n\n", fout);
> +    fputs("\\end{tabular}\n\n\\noindent ", fout);
>
>
>      /* print footers */
> @@ -951,8 +950,12 @@
>              if (!opt_barebones)
>              {
>                  if (opt_border == 2)
> +                {
>                      fputs("\\hline\n", fout);
> -                fprintf(fout, "\\multicolumn{2}{c}{Record %d} \\\\\n", record++);
> +                    fprintf(fout, "\\multicolumn{2}{|c|}{\\textit{Record %d}} \\\\\n", record++);
> +                }
> +                else
> +                    fprintf(fout, "\\multicolumn{2}{c}{\\textit{Record %d}} \\\\\n", record++);
>              }
>              if (opt_border >= 1)
>                  fputs("\\hline\n", fout);
> @@ -967,7 +970,7 @@
>      if (opt_border == 2)
>          fputs("\\hline\n", fout);
>
> -    fputs("\\end{tabular}\n\n", fout);
> +    fputs("\\end{tabular}\n\n\\noindent ", fout);
>
>
>      /* print footers */
>
>
>
> --
> Roger Leigh
>
>                 Printing on GNU/Linux?  http://gimp-print.sourceforge.net/
>                 GPG Public Key: 0x25BFB848.  Please sign and encrypt your mail.

Content-Description: psql latex output


Content-Description: psql latex PDF output

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 9: the planner will ignore your desire to choose an index scan if your
>       joining column's datatypes do not match

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073