summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2018-11-26 22:32:51 +0000
committerTom Lane2018-11-26 22:32:51 +0000
commit70d7e507ef9d380bd46345e984f069207de5e24e (patch)
tree22f1fa97284d9a16c13d43678a5d92e2ff852ebd
parent95dcb8fc0580c7b1c5f480b3ecaf81c5fc9801ba (diff)
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 6b78f0909c..a157a161fe 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 f4975464f6..775b127121 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 9ac6c20804..1bb2a6e16d 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;