<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.103 2004/01/20 19:49:34 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.104 2004/01/20 23:48:56 tgl Exp $
PostgreSQL documentation
-->
<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
+ { <replaceable class="parameter">filename</replaceable> | stdin | stdout | - }
[ <literal>with</literal> ]
[ <literal>oids</literal> ]
[ <literal>delimiter [as] </literal> '<replaceable class="parameter">character</replaceable>' ]
reading or writing the specified file,
<application>psql</application> reads or writes the file and
routes the data between the server and the local file system.
- This means that file accessibility and privileges are those
- of the local user, not the server, and no SQL superuser
- privileges are required.
+ This means that file accessibility and privileges are those of
+ the local user, not the server, and no SQL superuser
+ privileges are required.
</para>
<para>
The syntax of the command is similar to that of the
- <acronym>SQL</acronym> <command>COPY</command> command. (See its
- description for the details.) Note that, because of this,
+ <acronym>SQL</acronym> <xref linkend="sql-copy"
+ endterm="sql-copy-title"> command. Note that, because of this,
special parsing rules apply to the <command>\copy</command>
command. In particular, the variable substitution rules and
backslash escapes do not apply.
</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>
<para>
This operation is not as efficient as the <acronym>SQL</acronym>
<command>COPY</command> command because all data must pass
through the client/server connection. For large
- amounts of data the other technique may be preferable.
+ amounts of data the <acronym>SQL</acronym> command may be preferable.
</para>
</tip>
<para>
Note the difference in interpretation of
<literal>stdin</literal> and <literal>stdout</literal> between
- client and server copies: in a client copy these always
+ <literal>\copy</literal> and <command>COPY</command>.
+ In <literal>\copy</literal> these always
refer to <application>psql</application>'s input and output
- stream. On a server copy <literal>stdin</literal> comes from
- wherever the <command>COPY</command> itself came from (for
- example, a script run with the <option>-f</option> option), and
+ 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>
*
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.79 2004/01/09 21:12:20 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.80 2004/01/20 23:48:56 tgl Exp $
*/
#include "postgres_fe.h"
#include "common.h"
break;
case PGRES_COPY_IN:
- if (pset.cur_cmd_interactive && !QUIET())
- puts(gettext("Enter data to be copied followed by a newline.\n"
- "End with a backslash and a period on a line by itself."));
-
- success = handleCopyIn(pset.db, pset.cur_cmd_source,
- pset.cur_cmd_interactive ? get_prompt(PROMPT_COPY) : NULL);
+ success = handleCopyIn(pset.db, pset.cur_cmd_source);
break;
default:
*
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.36 2004/01/09 21:12:20 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.37 2004/01/20 23:48:56 tgl Exp $
*/
#include "postgres_fe.h"
#include "copy.h"
#include "settings.h"
#include "common.h"
+#include "prompt.h"
#include "stringutils.h"
#ifdef WIN32
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;
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 = xstrdup(token);
- expand_tilde(&result->file);
+ expand_tilde(&result->file);
+ }
token = strtokx(NULL, whitespace, NULL, NULL,
0, false, pset.encoding);
{
if (options->file)
copystream = fopen(options->file, "r");
+ else if (options->in_dash)
+ copystream = pset.cur_cmd_source;
else
- copystream = stdin;
+ copystream = stdin;
}
else
{
success = handleCopyOut(pset.db, copystream);
break;
case PGRES_COPY_IN:
- success = handleCopyIn(pset.db, copystream, NULL);
+ success = handleCopyIn(pset.db, copystream);
break;
case PGRES_NONFATAL_ERROR:
case PGRES_FATAL_ERROR:
PQclear(result);
- if (copystream != stdout && copystream != stdin)
+ if (options->file != NULL)
fclose(copystream);
free_copy_options(options);
return success;
* conn should be a database connection that you just called COPY FROM on
* (and which gave you PGRES_COPY_IN back);
* copystream is the file stream you want the input to come from
- * prompt is something to display to request user input (only makes sense
- * if stdin is an interactive tty)
*/
bool
-handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt)
+handleCopyIn(PGconn *conn, FILE *copystream)
{
+ const char *prompt;
bool copydone = false;
bool firstload;
bool linedone;
int ret;
unsigned int linecount = 0;
- if (prompt) /* disable prompt if not interactive */
+ /* Prompt if interactive input */
+ if (isatty(fileno(copystream)))
+ {
+ if (!QUIET())
+ puts(gettext("Enter data to be copied followed by a newline.\n"
+ "End with a backslash and a period on a line by itself."));
+ prompt = get_prompt(PROMPT_COPY);
+ }
+ else
{
- if (!isatty(fileno(copystream)))
- prompt = NULL;
+ prompt = NULL;
}
while (!copydone)
*
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/copy.h,v 1.14 2003/11/29 19:52:06 pgsql Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/copy.h,v 1.15 2004/01/20 23:48:56 tgl Exp $
*/
#ifndef COPY_H
#define COPY_H
/* lower level processors for copy in/out streams */
bool handleCopyOut(PGconn *conn, FILE *copystream);
-bool handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt);
+bool handleCopyIn(PGconn *conn, FILE *copystream);
#endif