At 2012-01-14 14:23:49 +0200, pete...@gmx.net wrote:
>
> Inspired by this question http://stackoverflow.com/questions/6857265 I
> have implemented a way to set the psql record and field separators to
> a zero byte (ASCII NUL character).

Since this patch is in the commitfest, I had a look at it.

I agree that the feature is useful. The patch applies and builds cleanly
with HEAD@9f9135d1, but needs a further minor tweak to work (attached).
Without it, both zero separators get overwritten with the default value
after option parsing. The code looks good otherwise.

There's one problem:

> psql --record-separator-zero -At -c 'select something from somewhere' | xargs 
> -0 dosomething

If you run find -print0 and it finds one file, it will still print
"filename\0", and xargs -0 will work fine.

But psql --record-separator-zero -At -c 'select 1' will print "1\n", not
"1\0" or even "1\0\n", so xargs -0 will use the value "1\n", not "1". If
you're doing this in a shell script, handing the last argument specially
would be painful.

At issue are (at least) these three lines from print_unaligned_text in
src/bin/psql/print.c:

 358         /* the last record needs to be concluded with a newline */
 359         if (need_recordsep)
 360             fputc('\n', fout);

Perhaps the right thing to do would be to change this to output \0 if
--record-separator-zero was used (but leave it at \n otherwise)? That
is what my second attached patch does:

$ bin/psql --record-separator-zero --field-separator-zero -At -c 'select 1,2 
union select 3,4'|xargs -0 echo
1 2 3 4

Thoughts?

> I think the most common use of this would be to set the record
> separator from the command line, so we could use a short option
> such as -0 or -z for that.

I agree. The current option names are very unwieldy to type.

-- ams
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 69207c1..691ad14 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -150,12 +150,14 @@ main(int argc, char *argv[])
 
 	parse_psql_options(argc, argv, &options);
 
-	if (!pset.popt.topt.fieldSep.separator)
+	if (!pset.popt.topt.fieldSep.separator &&
+		!pset.popt.topt.fieldSep.separator_zero)
 	{
 		pset.popt.topt.fieldSep.separator = pg_strdup(DEFAULT_FIELD_SEP);
 		pset.popt.topt.fieldSep.separator_zero = false;
 	}
-	if (!pset.popt.topt.recordSep.separator)
+	if (!pset.popt.topt.recordSep.separator &&
+		!pset.popt.topt.recordSep.separator_zero)
 	{
 		pset.popt.topt.recordSep.separator = pg_strdup(DEFAULT_RECORD_SEP);
 		pset.popt.topt.recordSep.separator_zero = false;
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 43ddab1..94535eb 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -357,7 +357,12 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
 		}
 		/* the last record needs to be concluded with a newline */
 		if (need_recordsep)
-			fputc('\n', fout);
+		{
+			if (cont->opt->recordSep.separator_zero)
+				print_separator(cont->opt->recordSep, fout);
+			else
+				fputc('\n', fout);
+		}
 	}
 }
 
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to