aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-11-26 17:32:51 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2018-11-26 17:32:51 -0500
commit70d7e507ef9d380bd46345e984f069207de5e24e (patch)
tree22f1fa97284d9a16c13d43678a5d92e2ff852ebd
parent95dcb8fc0580c7b1c5f480b3ecaf81c5fc9801ba (diff)
downloadpostgresql-70d7e507ef9d380bd46345e984f069207de5e24e.tar.gz
postgresql-70d7e507ef9d380bd46345e984f069207de5e24e.zip
Fix translation of special characters in psql's LaTeX output modes.
latex_escaped_print() mistranslated \ and failed to provide any translation for # ^ and ~, all of which would typically lead to LaTeX document syntax errors. In addition it didn't translate < > and |, which would typically render as unexpected characters. To some extent this represents shortcomings in ancient versions of LaTeX, which if memory serves had no easy way to render these control characters as ASCII text. But that's been fixed for, um, decades. In any case there is no value in emitting guaranteed-to-fail output for these characters. Noted while fooling with test cases added by commit 9a98984f4. Back-patch the code change to all supported versions.
-rw-r--r--src/fe_utils/print.c36
-rw-r--r--src/test/regress/expected/psql.out132
-rw-r--r--src/test/regress/sql/psql.sql4
3 files changed, 98 insertions, 74 deletions
diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c
index 6b78f0909cd..a157a161fea 100644
--- a/src/fe_utils/print.c
+++ b/src/fe_utils/print.c
@@ -2301,14 +2301,34 @@ latex_escaped_print(const char *in, FILE *fout)
for (p = in; *p; p++)
switch (*p)
{
- case '&':
- fputs("\\&", fout);
+ /*
+ * We convert ASCII characters per the recommendations in
+ * Scott Pakin's "The Comprehensive LATEX Symbol List",
+ * available from CTAN. For non-ASCII, you're on your own.
+ */
+ case '#':
+ fputs("\\#", fout);
+ break;
+ case '$':
+ fputs("\\$", fout);
break;
case '%':
fputs("\\%", fout);
break;
- case '$':
- fputs("\\$", fout);
+ case '&':
+ fputs("\\&", fout);
+ break;
+ case '<':
+ fputs("\\textless{}", fout);
+ break;
+ case '>':
+ fputs("\\textgreater{}", fout);
+ break;
+ case '\\':
+ fputs("\\textbackslash{}", fout);
+ break;
+ case '^':
+ fputs("\\^{}", fout);
break;
case '_':
fputs("\\_", fout);
@@ -2316,13 +2336,17 @@ latex_escaped_print(const char *in, FILE *fout)
case '{':
fputs("\\{", fout);
break;
+ case '|':
+ fputs("\\textbar{}", fout);
+ break;
case '}':
fputs("\\}", fout);
break;
- case '\\':
- fputs("\\backslash", fout);
+ case '~':
+ fputs("\\~{}", fout);
break;
case '\n':
+ /* This is not right, but doing it right seems too hard */
fputs("\\\\", fout);
break;
default:
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index f4975464f6a..775b127121e 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -3443,7 +3443,7 @@ Type & func \\
\noindent
\pset tuples_only false
prepare q as
- select 'some\more_text' as "a$title", E' &foo%\n{bar}' as "junk",
+ select 'some\more_text' as "a$title", E' #<foo>%&^~|\n{bar}' as "junk",
' ' as "empty", n as int
from generate_series(1,2) as n;
\pset expanded off
@@ -3452,8 +3452,8 @@ execute q;
\begin{tabular}{lllr}
\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\
\hline
-some\backslashmore\_text & \&foo\%\\\{bar\} & & 1 \\
-some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
+some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\
+some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\
\end{tabular}
\noindent (2 rows) \\
@@ -3463,8 +3463,8 @@ execute q;
\begin{tabular}{l | l | l | r}
\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\
\hline
-some\backslashmore\_text & \&foo\%\\\{bar\} & & 1 \\
-some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
+some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\
+some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\
\end{tabular}
\noindent (2 rows) \\
@@ -3475,8 +3475,8 @@ execute q;
\hline
\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\
\hline
-some\backslashmore\_text & \&foo\%\\\{bar\} & & 1 \\
-some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
+some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\
+some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\
\hline
\end{tabular}
@@ -3488,9 +3488,9 @@ execute q;
\hline
\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\
\hline
-some\backslashmore\_text & \&foo\%\\\{bar\} & & 1 \\
+some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\
\hline
-some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
+some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\
\hline
\end{tabular}
@@ -3501,13 +3501,13 @@ some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
execute q;
\begin{tabular}{cl}
\multicolumn{2}{c}{\textit{Record 1}} \\
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\multicolumn{2}{c}{\textit{Record 2}} \\
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\end{tabular}
@@ -3518,14 +3518,14 @@ execute q;
\begin{tabular}{c|l}
\multicolumn{2}{c}{\textit{Record 1}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\multicolumn{2}{c}{\textit{Record 2}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\end{tabular}
@@ -3537,15 +3537,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
@@ -3558,15 +3558,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
@@ -3667,7 +3667,7 @@ Type & func \\
\noindent
\pset tuples_only false
prepare q as
- select 'some\more_text' as "a$title", E' &foo%\n{bar}' as "junk",
+ select 'some\more_text' as "a$title", E' #<foo>%&^~|\n{bar}' as "junk",
' ' as "empty", n as int
from generate_series(1,2) as n;
\pset expanded off
@@ -3680,16 +3680,16 @@ execute q;
\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\
\midrule
\endhead
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
@@ -3704,16 +3704,16 @@ execute q;
\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\
\midrule
\endhead
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
@@ -3734,16 +3734,16 @@ execute q;
\endfoot
\bottomrule
\endlastfoot
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
@@ -3763,17 +3763,17 @@ execute q;
\endfoot
\bottomrule
\endlastfoot
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
\hline
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
@@ -3794,17 +3794,17 @@ execute q;
\endfoot
\bottomrule
\endlastfoot
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
\hline
-\raggedright{some\backslashmore\_text}
+\raggedright{some\textbackslash{}more\_text}
&
-\raggedright{ \&foo\%\\\{bar\}}
+\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
@@ -3817,13 +3817,13 @@ execute q;
execute q;
\begin{tabular}{cl}
\multicolumn{2}{c}{\textit{Record 1}} \\
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\multicolumn{2}{c}{\textit{Record 2}} \\
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\end{tabular}
@@ -3834,14 +3834,14 @@ execute q;
\begin{tabular}{c|l}
\multicolumn{2}{c}{\textit{Record 1}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\multicolumn{2}{c}{\textit{Record 2}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\end{tabular}
@@ -3853,15 +3853,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
@@ -3874,15 +3874,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
@@ -3895,15 +3895,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
-a\$title & some\backslashmore\_text \\
-junk & \&foo\%\\\{bar\} \\
+a\$title & some\textbackslash{}more\_text \\
+junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql
index 9ac6c208041..1bb2a6e16d4 100644
--- a/src/test/regress/sql/psql.sql
+++ b/src/test/regress/sql/psql.sql
@@ -611,7 +611,7 @@ deallocate q;
\pset tuples_only false
prepare q as
- select 'some\more_text' as "a$title", E' &foo%\n{bar}' as "junk",
+ select 'some\more_text' as "a$title", E' #<foo>%&^~|\n{bar}' as "junk",
' ' as "empty", n as int
from generate_series(1,2) as n;
@@ -660,7 +660,7 @@ deallocate q;
\pset tuples_only false
prepare q as
- select 'some\more_text' as "a$title", E' &foo%\n{bar}' as "junk",
+ select 'some\more_text' as "a$title", E' #<foo>%&^~|\n{bar}' as "junk",
' ' as "empty", n as int
from generate_series(1,2) as n;