Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > Tom Lane wrote:
> >> What is "command output" and how does that differ from stdout?
>
> > In this case, stdout is going to psql's stdout, not to the command
> > stdout.
>
> Hm, I didn't realize it worked like that. So "command output" means
> "where SELECT output would go"? Is that what happens to COPY TO STDOUT?
> (experiments ... I guess so.)
>
> > I thought pstdin/pstdout were very clear in helping folks remember how
> > it is different from stdin/stdout.
>
> Fair enough. If we need two flavors of stdout too, then I agree that
> names are better than "-".
OK, the attached patch implements pstdin and pstdout, and change stdin
and stdout for \copy to be the same as COPY. Using this file:
drop table test;
create table test (x int);
insert into test values (1);
\copy test from stdin
I get for stdin:
$ psql -f /tmp/x -o /dev/null test
for pstdin:
$ psql -f /tmp/x -o /dev/null test
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
test> 33
test> \.
for stdout:
$ psql -f /tmp/x -o /dev/null test
for pstdout:
$ psql -f /tmp/x -o /dev/null test
1
This breaks backward compatibility and has to be mentioned in the
release notes.
--
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
Index: doc/src/sgml/ref/psql-ref.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/ref/psql-ref.sgml,v
retrieving revision 1.109
diff -c -c -r1.109 psql-ref.sgml
*** doc/src/sgml/ref/psql-ref.sgml 30 Mar 2004 15:54:33 -0000 1.109
--- doc/src/sgml/ref/psql-ref.sgml 10 Apr 2004 15:18:58 -0000
***************
*** 706,712 ****
<term><literal>\copy <replaceable class="parameter">table</replaceable>
[ ( <replaceable class="parameter">column_list</replaceable> ) ]
{ <literal>from</literal> | <literal>to</literal> }
! { <replaceable class="parameter">filename</replaceable> | stdin | stdout | - }
[ <literal>with</literal> ]
[ <literal>oids</literal> ]
[ <literal>delimiter [as] </literal> '<replaceable class="parameter">character</replaceable>' ]
--- 706,712 ----
<term><literal>\copy <replaceable class="parameter">table</replaceable>
[ ( <replaceable class="parameter">column_list</replaceable> ) ]
{ <literal>from</literal> | <literal>to</literal> }
! { <replaceable class="parameter">filename</replaceable> | stdin | stdout | pstdin | pstdout }
[ <literal>with</literal> ]
[ <literal>oids</literal> ]
[ <literal>delimiter [as] </literal> '<replaceable class="parameter">character</replaceable>' ]
***************
*** 736,753 ****
</para>
<para>
! For <literal>\copy <replaceable
class="parameter">table</replaceable> from <replaceable
! class="parameter">filename</replaceable></literal> operations,
! <application>psql</application> adds the option of using a
! hyphen instead of <replaceable
! class="parameter">filename</replaceable>. This causes
! <literal>\copy</literal> to read rows from the same source that
! issued the command, continuing until <literal>\.</literal> is
! read or the stream reaches <acronym>EOF</>. This option is
! useful for populating tables in-line within a SQL script file.
! In contrast, <literal>\copy from stdin</> always reads from
! <application>psql</application>'s standard input.
</para>
<tip>
--- 736,752 ----
</para>
<para>
! <literal>\copy <replaceable
class="parameter">table</replaceable> from <replaceable
! class="parameter">stdin | stdout</replaceable></literal>
! reads/writes based on the command input and output respectively.
! All rows are read from the same source that issued the command,
! continuing until <literal>\.</literal> is read or the stream
! reaches <acronym>EOF</>. Output is sent to the same place as
! command output. To read/write from
! <application>psql</application>'s standard input or output, use
! <literal>pstdin</> or <literal>pstdout</>. This option is useful
! for populating tables in-line within a SQL script file.
</para>
<tip>
***************
*** 759,778 ****
</para>
</tip>
- <note>
- <para>
- Note the difference in interpretation of
- <literal>stdin</literal> and <literal>stdout</literal> between
- <literal>\copy</literal> and <command>COPY</command>.
- In <literal>\copy</literal> these always
- refer to <application>psql</application>'s input and output
- streams. In <command>COPY</command>, <literal>stdin</literal> comes
- from wherever the <command>COPY</command> itself came from (for
- example, a script run with the <option>-f</option> option), while
- <literal>stdout</literal> refers to the query output stream (see
- <command>\o</command> meta-command below).
- </para>
- </note>
</listitem>
</varlistentry>
--- 758,763 ----
Index: src/bin/psql/copy.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/copy.c,v
retrieving revision 1.42
diff -c -c -r1.42 copy.c
*** src/bin/psql/copy.c 29 Jan 2004 12:34:59 -0000 1.42
--- src/bin/psql/copy.c 10 Apr 2004 15:19:05 -0000
***************
*** 62,68 ****
char *table;
char *column_list;
char *file; /* NULL = stdin/stdout */
! bool in_dash; /* true = use src stream not true stdin */
bool from;
bool binary;
bool oids;
--- 62,68 ----
char *table;
char *column_list;
char *file; /* NULL = stdin/stdout */
! bool psql_inout; /* true = use psql stdin/stdout */
bool from;
bool binary;
bool oids;
***************
*** 220,240 ****
if (strcasecmp(token, "stdin") == 0 ||
strcasecmp(token, "stdout") == 0)
{
! result->in_dash = false;
result->file = NULL;
}
! else if (strcmp(token, "-") == 0)
{
! /* Can't do this on output */
! if (!result->from)
! goto error;
!
! result->in_dash = true;
result->file = NULL;
}
else
{
! result->in_dash = false;
result->file = pg_strdup(token);
expand_tilde(&result->file);
}
--- 220,237 ----
if (strcasecmp(token, "stdin") == 0 ||
strcasecmp(token, "stdout") == 0)
{
! result->psql_inout = false;
result->file = NULL;
}
! else if (strcasecmp(token, "pstdin") == 0 ||
! strcasecmp(token, "pstdout") == 0)
{
! result->psql_inout = true;
result->file = NULL;
}
else
{
! result->psql_inout = false;
result->file = pg_strdup(token);
expand_tilde(&result->file);
}
***************
*** 394,400 ****
{
if (options->file)
copystream = fopen(options->file, "r");
! else if (options->in_dash)
copystream = pset.cur_cmd_source;
else
copystream = stdin;
--- 391,397 ----
{
if (options->file)
copystream = fopen(options->file, "r");
! else if (!options->psql_inout)
copystream = pset.cur_cmd_source;
else
copystream = stdin;
***************
*** 403,408 ****
--- 400,407 ----
{
if (options->file)
copystream = fopen(options->file, "w");
+ else if (!options->psql_inout)
+ copystream = pset.queryFout;
else
copystream = stdout;
}