diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
new file mode 100644
index c41593c..932c7ca
*** a/doc/src/sgml/ref/psql-ref.sgml
--- b/doc/src/sgml/ref/psql-ref.sgml
*************** lo_import 152801
*** 1979,1985 ****
            Sets the output format to one of <literal>unaligned</literal>,
            <literal>aligned</literal>, <literal>wrapped</literal>,
            <literal>html</literal>,
!           <literal>latex</literal>, or <literal>troff-ms</literal>.
            Unique abbreviations are allowed.  (That would mean one letter
            is enough.)
            </para>
--- 1979,1986 ----
            Sets the output format to one of <literal>unaligned</literal>,
            <literal>aligned</literal>, <literal>wrapped</literal>,
            <literal>html</literal>,
!           <literal>latex</literal>, <literal>latex-longtable</literal>,
!           or <literal>troff-ms</literal>.
            Unique abbreviations are allowed.  (That would mean one letter
            is enough.)
            </para>
*************** lo_import 152801
*** 2005,2016 ****
            </para>
  
            <para>
!           The <literal>html</>, <literal>latex</>, and <literal>troff-ms</>
            formats put out tables that are intended to
            be included in documents using the respective mark-up
            language. They are not complete documents! (This might not be
!           so dramatic in <acronym>HTML</acronym>, but in <application>LaTeX</application> you must
!           have a complete document wrapper.)
            </para>
            </listitem>
            </varlistentry>
--- 2006,2019 ----
            </para>
  
            <para>
!           The <literal>html</>, <literal>latex</>,
!           <literal>latex-longtable</literal>, and <literal>troff-ms</>
            formats put out tables that are intended to
            be included in documents using the respective mark-up
            language. They are not complete documents! (This might not be
!           so dramatic in <acronym>HTML</acronym>, but in
!           <application>LaTeX</application> you must have a complete
!           document wrapper.)
            </para>
            </listitem>
            </varlistentry>
*************** lo_import 152801
*** 2141,2149 ****
            <term><literal>tableattr</literal> (or <literal>T</literal>)</term>
            <listitem>
            <para>
!           Specifies attributes to be placed inside the
!           <acronym>HTML</acronym> <sgmltag>table</sgmltag> tag in
!           <literal>html</> output format. This
            could for example be <literal>cellpadding</literal> or
            <literal>bgcolor</literal>. Note that you probably don't want
            to specify <literal>border</literal> here, as that is already
--- 2144,2151 ----
            <term><literal>tableattr</literal> (or <literal>T</literal>)</term>
            <listitem>
            <para>
!           In <acronym>HTML</acronym> format, this specifies attributes
!           to be placed inside the <sgmltag>table</sgmltag> tag.  This
            could for example be <literal>cellpadding</literal> or
            <literal>bgcolor</literal>. Note that you probably don't want
            to specify <literal>border</literal> here, as that is already
*************** lo_import 152801
*** 2152,2157 ****
--- 2154,2165 ----
            <replaceable class="parameter">value</replaceable> is given,
            the table attributes are unset.
            </para>
+           <para>
+           In <acronym>latex-longtable</acronym> format, this controls
+           the proportional width of each column.  It is specified as a
+           space-separated list of values, e.g. <literal>'0.2 0.2 0.6'</>.
+           Unspecified output columns will use the last specified value.
+           </para>
            </listitem>
            </varlistentry>
  
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
new file mode 100644
index 59f8b03..740884f
*** a/src/bin/psql/command.c
--- b/src/bin/psql/command.c
*************** _align2string(enum printFormat in)
*** 2164,2169 ****
--- 2164,2172 ----
  		case PRINT_LATEX:
  			return "latex";
  			break;
+ 		case PRINT_LATEX_LONGTABLE:
+ 			return "latex-longtable";
+ 			break;
  		case PRINT_TROFF_MS:
  			return "troff-ms";
  			break;
*************** do_pset(const char *param, const char *v
*** 2197,2202 ****
--- 2200,2207 ----
  			popt->topt.format = PRINT_HTML;
  		else if (pg_strncasecmp("latex", value, vallen) == 0)
  			popt->topt.format = PRINT_LATEX;
+ 		else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
+ 			popt->topt.format = PRINT_LATEX_LONGTABLE;
  		else if (pg_strncasecmp("troff-ms", value, vallen) == 0)
  			popt->topt.format = PRINT_TROFF_MS;
  		else
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
new file mode 100644
index 466c255..6839d6c
*** a/src/bin/psql/print.c
--- b/src/bin/psql/print.c
*************** print_latex_text(const printTableContent
*** 1656,1662 ****
  				fputc('}', fout);
  			}
  			fputs(" \\\\\n", fout);
! 			fputs("\\hline\n", fout);
  		}
  	}
  
--- 1656,1663 ----
  				fputc('}', fout);
  			}
  			fputs(" \\\\\n", fout);
! 			if (opt_border != 0)
! 				fputs("\\hline\n", fout);
  		}
  	}
  
*************** print_latex_text(const printTableContent
*** 1702,1707 ****
--- 1703,1843 ----
  
  
  static void
+ print_latex_text_longtable(const printTableContent *cont, FILE *fout)
+ {
+ #define LONGTABLE_WHITESPACE	" \t\n"
+ 
+ 	bool		opt_tuples_only = cont->opt->tuples_only;
+ 	unsigned short opt_border = cont->opt->border;
+ 	unsigned int i;
+ 	const char *opt_table_attr = cont->opt->tableAttr;
+ 	const char *next_opt_table_attr_char = opt_table_attr;
+ 	const char *last_opt_table_attr_char = NULL;
+ 	const char *const * ptr;
+ 
+ 	if (cancel_pressed)
+ 		return;
+ 
+ 	if (opt_border > 2)
+ 		opt_border = 2;
+ 
+ 	if (cont->opt->start_table)
+ 	{
+ 		/* print title */
+ 		if (!opt_tuples_only && cont->title)
+ 		{
+ 			fputs("\\begin{center}\n", fout);
+ 			latex_escaped_print(cont->title, fout);
+ 			fputs("\n\\end{center}\n\n", fout);
+ 		}
+ 
+ 		/* begin environment and set alignments and borders */
+ 		fputs("\\begin{longtable}{", fout);
+ 
+ 		if (opt_border == 2)
+ 			fputs("| ", fout);
+ 		for (i = 0; i < cont->ncolumns; i++)
+ 		{
+ 			fputc('p', fout);
+ 			fputc(*(cont->aligns + i), fout);
+ 			/* Was a proportional width specified? */
+ 			if (opt_table_attr)
+ 			{
+ 				/* advance over whitespace */
+ 				next_opt_table_attr_char += strspn(next_opt_table_attr_char,
+ 												   LONGTABLE_WHITESPACE);
+ 				/* We have a value? */
+ 				if (next_opt_table_attr_char[0] != '\0')
+ 				{
+ 					fputc('{', fout);
+ 					fwrite(next_opt_table_attr_char, strcspn(next_opt_table_attr_char,
+ 						   LONGTABLE_WHITESPACE), 1, fout);
+ 					last_opt_table_attr_char = next_opt_table_attr_char;
+ 					next_opt_table_attr_char += strcspn(next_opt_table_attr_char,
+ 													    LONGTABLE_WHITESPACE);
+ 					fputs("\\textwidth}", fout);
+ 				}
+ 				/* use previous value */
+ 				else if (last_opt_table_attr_char != NULL)
+ 				{
+ 					fputc('{', fout);
+ 					fwrite(last_opt_table_attr_char, strcspn(last_opt_table_attr_char,
+ 						   LONGTABLE_WHITESPACE), 1, fout);
+ 					fputs("\\textwidth}", fout);
+ 				}
+ 			}
+ 			if (opt_border != 0 && i < cont->ncolumns - 1)
+ 				fputs(" | ", fout);
+ 		}
+ 		if (opt_border == 2)
+ 			fputs(" |", fout);
+ 
+ 		fputs("}\n", fout);
+ 
+ 		if (!opt_tuples_only && opt_border == 2)
+ 			fputs("\\hline\n", fout);
+ 
+ 		/* print headers */
+ 		if (!opt_tuples_only)
+ 		{
+ 			fputs("\\toprule\n", fout);
+ 			for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
+ 			{
+ 				if (i != 0)
+ 					fputs(" & ", fout);
+ 				fputs("\\small\\textbf{\\textit{", fout);
+ 				latex_escaped_print(*ptr, fout);
+ 				fputs("}}", fout);
+ 			}
+ 			fputs(" \\\\\n", fout);
+ 			fputs("\\midrule\n\\endfirsthead\n\\toprule\n", fout);
+ 			for (i = 0, ptr = cont->headers; i < cont->ncolumns; i++, ptr++)
+ 			{
+ 				if (i != 0)
+ 					fputs(" & ", fout);
+ 				fputs("\\small\\textbf{\\textit{", fout);
+ 				latex_escaped_print(*ptr, fout);
+ 				fputs("}}", fout);
+ 			}
+ 			fputs(" \\\\\n", fout);
+ 			fputs("\\midrule\n\\endhead\n", fout);
+ 			if (cont->headers)
+ 			{
+ 				fputs("\\bottomrule\n", fout);
+ 				fprintf(fout, "\\caption[%s. (Continued)]{%s.}\n",
+ 						*cont->headers, *cont->headers);
+ 				fputs("\\endfoot\n", fout);
+ 				fputs("\\bottomrule\n", fout);
+ 				fprintf(fout, "\\caption[%s.]{%s.}\n",
+ 						*cont->headers, *cont->headers);
+ 				fputs("\\endlastfoot\n", fout);
+ 			}
+ 			if (opt_border != 0)
+ 				fputs("\\hline\n", fout);
+ 		}
+ 	}
+ 
+ 	/* print cells */
+ 	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
+ 	{
+ 		if (i != 0 && i % cont->ncolumns != 0)
+ 			fputs("\n&\n", fout);
+ 		fputs("\\raggedright{", fout);
+ 		latex_escaped_print(*ptr, fout);
+ 		fputc('}', fout);
+ 		if ((i + 1) % cont->ncolumns == 0)
+ 			fputs(" \\tabularnewline\n", fout);
+ 		if (cancel_pressed)
+ 			break;
+ 	}
+ 
+ 	if (opt_border == 2)
+ 		fputs("\\hline\n", fout);
+ 	fputs("\\end{longtable}\n", fout);
+ }
+ 
+ 
+ static void
  print_latex_vertical(const printTableContent *cont, FILE *fout)
  {
  	bool		opt_tuples_only = cont->opt->tuples_only;
*************** printTable(const printTableContent *cont
*** 2394,2399 ****
--- 2530,2541 ----
  			else
  				print_latex_text(cont, fout);
  			break;
+ 		case PRINT_LATEX_LONGTABLE:
+ 			if (cont->opt->expanded == 1)
+ 				print_latex_vertical(cont, fout);
+ 			else
+ 				print_latex_text_longtable(cont, fout);
+ 			break;
  		case PRINT_TROFF_MS:
  			if (cont->opt->expanded == 1)
  				print_troff_ms_vertical(cont, fout);
diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h
new file mode 100644
index 63ba4a5..9cfa3b6
*** a/src/bin/psql/print.h
--- b/src/bin/psql/print.h
*************** enum printFormat
*** 19,24 ****
--- 19,25 ----
  	PRINT_WRAPPED,
  	PRINT_HTML,
  	PRINT_LATEX,
+ 	PRINT_LATEX_LONGTABLE,
  	PRINT_TROFF_MS
  	/* add your favourite output format here ... */
  };
