Improve COPY syntax to use WITH clause, keep backward compatibility.
This commit is contained in:
parent
2912fd45d1
commit
c2c2fd57ee
@ -1,4 +1,4 @@
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/keywords.sgml,v 2.5 2002/01/08 15:38:42 tgl Exp $ -->
|
||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/keywords.sgml,v 2.6 2002/06/20 16:00:43 momjian Exp $ -->
|
||||
|
||||
<appendix id="sql-keywords-appendix">
|
||||
<title><acronym>SQL</acronym> Key Words</title>
|
||||
@ -890,6 +890,12 @@
|
||||
<entry>reserved</entry>
|
||||
<entry>reserved</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><token>DELIMITER</token></entry>
|
||||
<entry>non-reserved</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><token>DELIMITERS</token></entry>
|
||||
<entry>non-reserved</entry>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/copy.sgml,v 1.31 2002/05/14 18:47:58 tgl Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/copy.sgml,v 1.32 2002/06/20 16:00:43 momjian Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -21,14 +21,20 @@ PostgreSQL documentation
|
||||
<date>1999-12-11</date>
|
||||
</refsynopsisdivinfo>
|
||||
<synopsis>
|
||||
COPY [ BINARY ] <replaceable class="parameter">table</replaceable> [ WITH OIDS ]
|
||||
COPY <replaceable class="parameter">table</replaceable>
|
||||
FROM { '<replaceable class="parameter">filename</replaceable>' | <filename>stdin</filename> }
|
||||
[ [USING] DELIMITERS '<replaceable class="parameter">delimiter</replaceable>' ]
|
||||
[ WITH NULL AS '<replaceable class="parameter">null string</replaceable>' ]
|
||||
COPY [ BINARY ] <replaceable class="parameter">table</replaceable> [ WITH OIDS ]
|
||||
[ [ WITH ]
|
||||
[ BINARY ]
|
||||
[ OIDS ]
|
||||
[ DELIMITER [ AS ] '<replaceable class="parameter">delimiter</replaceable>' ]
|
||||
[ NULL [ AS ] '<replaceable class="parameter">null string</replaceable>' ] ]
|
||||
COPY <replaceable class="parameter">table</replaceable>
|
||||
TO { '<replaceable class="parameter">filename</replaceable>' | <filename>stdout</filename> }
|
||||
[ [USING] DELIMITERS '<replaceable class="parameter">delimiter</replaceable>' ]
|
||||
[ WITH NULL AS '<replaceable class="parameter">null string</replaceable>' ]
|
||||
[ [ WITH ]
|
||||
[ BINARY ]
|
||||
[ OIDS ]
|
||||
[ DELIMITER [ AS ] '<replaceable class="parameter">delimiter</replaceable>' ]
|
||||
[ NULL [ AS ] '<replaceable class="parameter">null string</replaceable>' ] ]
|
||||
</synopsis>
|
||||
|
||||
<refsect2 id="R2-SQL-COPY-1">
|
||||
@ -41,17 +47,6 @@ COPY [ BINARY ] <replaceable class="parameter">table</replaceable> [ WITH OIDS ]
|
||||
<para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>BINARY</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Changes the behavior of field formatting, forcing all data to be
|
||||
stored or read in binary format rather than as text.
|
||||
The DELIMITERS and WITH NULL options are irrelevant for binary format.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">table</replaceable></term>
|
||||
<listitem>
|
||||
@ -61,15 +56,6 @@ COPY [ BINARY ] <replaceable class="parameter">table</replaceable> [ WITH OIDS ]
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>WITH OIDS</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies copying the internal object id (OID) for each row.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">filename</replaceable></term>
|
||||
<listitem>
|
||||
@ -97,6 +83,26 @@ COPY [ BINARY ] <replaceable class="parameter">table</replaceable> [ WITH OIDS ]
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>BINARY</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Changes the behavior of field formatting, forcing all data to be
|
||||
stored or read in binary format rather than as text. You can not
|
||||
specify DELIMITER or NULL in binary mode.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>OIDS</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies copying the internal object id (OID) for each row.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">delimiter</replaceable></term>
|
||||
<listitem>
|
||||
@ -111,8 +117,8 @@ COPY [ BINARY ] <replaceable class="parameter">table</replaceable> [ WITH OIDS ]
|
||||
<listitem>
|
||||
<para>
|
||||
The string that represents a NULL value. The default is
|
||||
<quote><literal>\N</literal></quote> (backslash-N).
|
||||
You might prefer an empty string, for example.
|
||||
<quote><literal>\N</literal></quote> (backslash-N). You might
|
||||
prefer an empty string, for example.
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
@ -172,34 +178,33 @@ ERROR: <replaceable>reason</replaceable>
|
||||
</title>
|
||||
<para>
|
||||
<command>COPY</command> moves data between
|
||||
<productname>PostgreSQL</productname> tables and
|
||||
standard file-system files.
|
||||
<productname>PostgreSQL</productname> tables and standard file-system
|
||||
files.
|
||||
|
||||
<command>COPY TO</command> copies the entire contents of a table
|
||||
<emphasis>to</>
|
||||
a file, while <command>COPY FROM</command> copies data <emphasis>from</> a
|
||||
file to a
|
||||
table (appending the data to whatever is in the table already).
|
||||
<emphasis>to</> a file, while <command>COPY FROM</command> copies
|
||||
data <emphasis>from</> a file to a table (appending the data to
|
||||
whatever is in the table already).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<command>COPY</command> with a file name instructs
|
||||
the <productname>PostgreSQL</productname> backend
|
||||
to directly read from or write to a file.
|
||||
The file must be accessible to the backend and the name must be specified
|
||||
from the viewpoint of the backend.
|
||||
When <filename>stdin</filename> or <filename>stdout</filename> is
|
||||
specified, data flows through the client frontend to the backend.
|
||||
<command>COPY</command> with a file name instructs the
|
||||
<productname>PostgreSQL</productname> backend to directly read from
|
||||
or write to a file. The file must be accessible to the backend and
|
||||
the name must be specified from the viewpoint of the backend. When
|
||||
<filename>stdin</filename> or <filename>stdout</filename> is
|
||||
specified, data flows through the client frontend to the backend.
|
||||
|
||||
<tip>
|
||||
<para>
|
||||
Do not confuse <command>COPY</command> with the
|
||||
<application>psql</application> instruction <command>\copy</command>.
|
||||
<command>\copy</command> invokes <command>COPY FROM stdin</command>
|
||||
or <command>COPY TO stdout</command>, and then fetches/stores the data
|
||||
in a file accessible to the <application>psql</application> client.
|
||||
Thus, file accessibility and access rights depend on the client
|
||||
rather than the backend when <command>\copy</command> is used.
|
||||
<application>psql</application> instruction
|
||||
<command>\copy</command>. <command>\copy</command> invokes
|
||||
<command>COPY FROM stdin</command> or <command>COPY TO
|
||||
stdout</command>, and then fetches/stores the data in a file
|
||||
accessible to the <application>psql</application> client. Thus,
|
||||
file accessibility and access rights depend on the client rather
|
||||
than the backend when <command>\copy</command> is used.
|
||||
</para>
|
||||
</tip>
|
||||
</para>
|
||||
@ -225,20 +230,19 @@ ERROR: <replaceable>reason</replaceable>
|
||||
|
||||
<para>
|
||||
By default, a text copy uses a tab ("\t") character as a delimiter
|
||||
between fields. The field delimiter may be changed to any other single
|
||||
character with the keyword phrase USING DELIMITERS. Characters
|
||||
in data fields that happen to match the delimiter character will
|
||||
be backslash quoted.
|
||||
between fields. The field delimiter may be changed to any other
|
||||
single character with the keyword DELIMITER. Characters in data
|
||||
fields that happen to match the delimiter character will be
|
||||
backslash quoted.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You must have <firstterm>select privilege</firstterm> on any table
|
||||
whose values are read by
|
||||
<command>COPY TO</command>, and
|
||||
<firstterm>insert privilege</firstterm> on a
|
||||
table into which values are being inserted by <command>COPY FROM</command>.
|
||||
The backend also needs appropriate Unix permissions for any file read
|
||||
or written by <command>COPY</command>.
|
||||
whose values are read by <command>COPY TO</command>, and
|
||||
<firstterm>insert privilege</firstterm> on a table into which values
|
||||
are being inserted by <command>COPY FROM</command>. The backend also
|
||||
needs appropriate Unix permissions for any file read or written by
|
||||
<command>COPY</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -247,28 +251,25 @@ ERROR: <replaceable>reason</replaceable>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<command>COPY</command> stops operation at the first error. This
|
||||
should not lead to problems in the event of
|
||||
a <command>COPY TO</command>, but the
|
||||
target relation will already have received earlier rows in a
|
||||
<command>COPY FROM</command>. These rows will not be visible or
|
||||
accessible, but they still occupy disk space. This may amount to a
|
||||
considerable amount
|
||||
of wasted disk space if the failure happened well into a large copy
|
||||
operation. You may wish to invoke <command>VACUUM</command> to recover
|
||||
the wasted space.
|
||||
<command>COPY</command> stops operation at the first error. This
|
||||
should not lead to problems in the event of a <command>COPY
|
||||
TO</command>, but the target relation will already have received
|
||||
earlier rows in a <command>COPY FROM</command>. These rows will not
|
||||
be visible or accessible, but they still occupy disk space. This may
|
||||
amount to a considerable amount of wasted disk space if the failure
|
||||
happened well into a large copy operation. You may wish to invoke
|
||||
<command>VACUUM</command> to recover the wasted space.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Files named in a <command>COPY</command> command are read or written
|
||||
directly by the backend, not by the client application. Therefore,
|
||||
directly by the backend, not by the client application. Therefore,
|
||||
they must reside on or be accessible to the database server machine,
|
||||
not the client. They must be accessible to and readable or writable
|
||||
not the client. They must be accessible to and readable or writable
|
||||
by the <application>PostgreSQL</application> user (the user ID the
|
||||
server runs as), not the client.
|
||||
<command>COPY</command> naming a file is only allowed to database
|
||||
superusers, since it allows reading or writing any file that the backend
|
||||
has privileges to access.
|
||||
server runs as), not the client. <command>COPY</command> naming a
|
||||
file is only allowed to database superusers, since it allows reading
|
||||
or writing any file that the backend has privileges to access.
|
||||
|
||||
<tip>
|
||||
<para>
|
||||
@ -282,11 +283,11 @@ ERROR: <replaceable>reason</replaceable>
|
||||
|
||||
<para>
|
||||
It is recommended that the file name used in <command>COPY</command>
|
||||
always be specified as an absolute path. This is enforced by the backend
|
||||
in the case of <command>COPY TO</command>, but for <command>COPY
|
||||
FROM</command> you do have the option of reading from a file specified
|
||||
by a relative path. The path will be interpreted relative to the
|
||||
backend's working directory (somewhere below
|
||||
always be specified as an absolute path. This is enforced by the
|
||||
backend in the case of <command>COPY TO</command>, but for
|
||||
<command>COPY FROM</command> you do have the option of reading from
|
||||
a file specified by a relative path. The path will be interpreted
|
||||
relative to the backend's working directory (somewhere below
|
||||
<filename>$PGDATA</filename>), not the client's working directory.
|
||||
</para>
|
||||
</refsect2>
|
||||
@ -312,8 +313,8 @@ ERROR: <replaceable>reason</replaceable>
|
||||
place of attributes that are NULL.
|
||||
</para>
|
||||
<para>
|
||||
If WITH OIDS is specified, the OID is read or written as the first column,
|
||||
preceding the user data columns. (An error is raised if WITH OIDS is
|
||||
If OIDS is specified, the OID is read or written as the first column,
|
||||
preceding the user data columns. (An error is raised if OIDS is
|
||||
specified for a table that does not have OIDs.)
|
||||
</para>
|
||||
<para>
|
||||
@ -325,11 +326,11 @@ ERROR: <replaceable>reason</replaceable>
|
||||
</para>
|
||||
<para>
|
||||
Backslash characters (<literal>\</>) may be used in the
|
||||
<command>COPY</command> data to quote data characters that might otherwise
|
||||
be taken as row or column delimiters. In particular, the following
|
||||
characters <emphasis>must</> be preceded by a backslash if they appear
|
||||
as part of an attribute value: backslash itself, newline, and the current
|
||||
delimiter character.
|
||||
<command>COPY</command> data to quote data characters that might
|
||||
otherwise be taken as row or column delimiters. In particular, the
|
||||
following characters <emphasis>must</> be preceded by a backslash if
|
||||
they appear as part of an attribute value: backslash itself,
|
||||
newline, and the current delimiter character.
|
||||
</para>
|
||||
<para>
|
||||
The following special backslash sequences are recognized by
|
||||
@ -412,9 +413,8 @@ ERROR: <replaceable>reason</replaceable>
|
||||
<title>Binary Format</title>
|
||||
<para>
|
||||
The file format used for <command>COPY BINARY</command> changed in
|
||||
<application>PostgreSQL</application> v7.1.
|
||||
The new format consists of a file header, zero or more
|
||||
tuples, and a file trailer.
|
||||
<application>PostgreSQL</application> v7.1. The new format consists
|
||||
of a file header, zero or more tuples, and a file trailer.
|
||||
</para>
|
||||
|
||||
<refsect3>
|
||||
@ -446,9 +446,9 @@ filters, dropped nulls, dropped high bits, or parity changes.)
|
||||
<term>Integer layout field</term>
|
||||
<listitem>
|
||||
<para>
|
||||
int32 constant 0x01020304 in source's byte order.
|
||||
Potentially, a reader could engage in byte-flipping of subsequent fields
|
||||
if the wrong byte order is detected here.
|
||||
int32 constant 0x01020304 in source's byte order. Potentially, a reader
|
||||
could engage in byte-flipping of subsequent fields if the wrong byte
|
||||
order is detected here.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -457,14 +457,14 @@ if the wrong byte order is detected here.
|
||||
<term>Flags field</term>
|
||||
<listitem>
|
||||
<para>
|
||||
int32 bit mask to denote important aspects of the file
|
||||
format. Bits are numbered from 0 (LSB) to 31 (MSB) --- note that this
|
||||
field is stored with source's endianness, as are all subsequent integer
|
||||
fields. Bits 16-31 are reserved to denote critical file format issues;
|
||||
a reader should abort if it finds an unexpected bit set in this range.
|
||||
Bits 0-15 are reserved to signal backwards-compatible format issues;
|
||||
a reader should simply ignore any unexpected bits set in this range.
|
||||
Currently only one flag bit is defined, and the rest must be zero:
|
||||
int32 bit mask to denote important aspects of the file format. Bits are
|
||||
numbered from 0 (LSB) to 31 (MSB) --- note that this field is stored
|
||||
with source's endianness, as are all subsequent integer fields. Bits
|
||||
16-31 are reserved to denote critical file format issues; a reader
|
||||
should abort if it finds an unexpected bit set in this range. Bits 0-15
|
||||
are reserved to signal backwards-compatible format issues; a reader
|
||||
should simply ignore any unexpected bits set in this range. Currently
|
||||
only one flag bit is defined, and the rest must be zero:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>Bit 16</term>
|
||||
@ -620,7 +620,7 @@ The following example copies a table to standard output,
|
||||
delimiter:
|
||||
</para>
|
||||
<programlisting>
|
||||
COPY country TO <filename>stdout</filename> USING DELIMITERS '|';
|
||||
COPY country TO <filename>stdout</filename> WITH DELIMITER '|';
|
||||
</programlisting>
|
||||
<para>
|
||||
To copy data from a Unix file into a table country:
|
||||
@ -629,9 +629,9 @@ COPY country TO <filename>stdout</filename> USING DELIMITERS '|';
|
||||
COPY country FROM '/usr1/proj/bray/sql/country_data';
|
||||
</programlisting>
|
||||
<para>
|
||||
Here is a sample of data suitable for copying into a table
|
||||
from <filename>stdin</filename> (so it
|
||||
has the termination sequence on the last line):
|
||||
Here is a sample of data suitable for copying into a table from
|
||||
<filename>stdin</filename> (so it has the termination sequence on the
|
||||
last line):
|
||||
</para>
|
||||
<programlisting>
|
||||
AF AFGHANISTAN
|
||||
@ -645,13 +645,12 @@ ZW ZIMBABWE
|
||||
Note that the white space on each line is actually a TAB.
|
||||
</para>
|
||||
<para>
|
||||
The following is the same data, output in binary format on a Linux/i586
|
||||
machine. The data is shown after filtering through
|
||||
the Unix utility <command>od -c</command>. The table has
|
||||
three fields; the first is <type>char(2)</type>,
|
||||
the second is <type>text</type>, and the third is
|
||||
<type>integer</type>. All the
|
||||
rows have a null value in the third field.
|
||||
The following is the same data, output in binary format on a
|
||||
Linux/i586 machine. The data is shown after filtering through the
|
||||
Unix utility <command>od -c</command>. The table has three fields;
|
||||
the first is <type>char(2)</type>, the second is <type>text</type>,
|
||||
and the third is <type>integer</type>. All the rows have a null value
|
||||
in the third field.
|
||||
</para>
|
||||
<programlisting>
|
||||
0000000 P G B C O P Y \n 377 \r \n \0 004 003 002 001
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.156 2002/05/21 22:59:00 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.157 2002/06/20 16:00:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -261,18 +261,79 @@ CopyDonePeek(FILE *fp, int c, bool pickup)
|
||||
* the table.
|
||||
*/
|
||||
void
|
||||
DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe,
|
||||
char *filename, char *delim, char *null_print)
|
||||
DoCopy(const CopyStmt *stmt)
|
||||
{
|
||||
RangeVar *relation = stmt->relation;
|
||||
char *filename = stmt->filename;
|
||||
bool is_from = stmt->is_from;
|
||||
bool pipe = (stmt->filename == NULL);
|
||||
List *option;
|
||||
DefElem *dbinary = NULL;
|
||||
DefElem *doids = NULL;
|
||||
DefElem *ddelim = NULL;
|
||||
DefElem *dnull = NULL;
|
||||
bool binary = false;
|
||||
bool oids = false;
|
||||
char *delim = "\t";
|
||||
char *null_print = "\\N";
|
||||
FILE *fp;
|
||||
Relation rel;
|
||||
AclMode required_access = (from ? ACL_INSERT : ACL_SELECT);
|
||||
AclMode required_access = (is_from ? ACL_INSERT : ACL_SELECT);
|
||||
AclResult aclresult;
|
||||
|
||||
/* Extract options from the statement node tree */
|
||||
foreach(option, stmt->options)
|
||||
{
|
||||
DefElem *defel = (DefElem *) lfirst(option);
|
||||
|
||||
if (strcmp(defel->defname, "binary") == 0)
|
||||
{
|
||||
if (dbinary)
|
||||
elog(ERROR, "COPY: conflicting options");
|
||||
dbinary = defel;
|
||||
}
|
||||
else if (strcmp(defel->defname, "oids") == 0)
|
||||
{
|
||||
if (doids)
|
||||
elog(ERROR, "COPY: conflicting options");
|
||||
doids = defel;
|
||||
}
|
||||
else if (strcmp(defel->defname, "delimiter") == 0)
|
||||
{
|
||||
if (ddelim)
|
||||
elog(ERROR, "COPY: conflicting options");
|
||||
ddelim = defel;
|
||||
}
|
||||
else if (strcmp(defel->defname, "null") == 0)
|
||||
{
|
||||
if (dnull)
|
||||
elog(ERROR, "COPY: conflicting options");
|
||||
dnull = defel;
|
||||
}
|
||||
else
|
||||
elog(ERROR, "COPY: option \"%s\" not recognized",
|
||||
defel->defname);
|
||||
}
|
||||
|
||||
if (dbinary)
|
||||
binary = intVal(dbinary->arg);
|
||||
if (doids)
|
||||
oids = intVal(doids->arg);
|
||||
if (ddelim)
|
||||
delim = strVal(ddelim->arg);
|
||||
if (dnull)
|
||||
null_print = strVal(dnull->arg);
|
||||
|
||||
if (binary && ddelim)
|
||||
elog(ERROR, "You can not specify the DELIMITER in BINARY mode.");
|
||||
|
||||
if (binary && dnull)
|
||||
elog(ERROR, "You can not specify NULL in BINARY mode.");
|
||||
|
||||
/*
|
||||
* Open and lock the relation, using the appropriate lock type.
|
||||
*/
|
||||
rel = heap_openrv(relation, (from ? RowExclusiveLock : AccessShareLock));
|
||||
rel = heap_openrv(relation, (is_from ? RowExclusiveLock : AccessShareLock));
|
||||
|
||||
/* Check permissions. */
|
||||
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
|
||||
@ -306,7 +367,7 @@ DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe,
|
||||
server_encoding = GetDatabaseEncoding();
|
||||
#endif
|
||||
|
||||
if (from)
|
||||
if (is_from)
|
||||
{ /* copy from file to database */
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||
{
|
||||
@ -410,7 +471,7 @@ DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe,
|
||||
|
||||
if (!pipe)
|
||||
FreeFile(fp);
|
||||
else if (!from)
|
||||
else if (!is_from)
|
||||
{
|
||||
if (!binary)
|
||||
CopySendData("\\.\n", 3, fp);
|
||||
@ -425,7 +486,7 @@ DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe,
|
||||
* transaction to ensure that updates will be committed before lock is
|
||||
* released.
|
||||
*/
|
||||
heap_close(rel, (from ? NoLock : AccessShareLock));
|
||||
heap_close(rel, (is_from ? NoLock : AccessShareLock));
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.93 2002/06/18 17:27:57 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.94 2002/06/20 16:00:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -58,7 +58,7 @@ static bool remove_dbdirs(const char *real_loc, const char *altloc);
|
||||
*/
|
||||
|
||||
void
|
||||
createdb(CreatedbStmt *stmt)
|
||||
createdb(const CreatedbStmt *stmt)
|
||||
{
|
||||
char *nominal_loc;
|
||||
char *alt_loc;
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.189 2002/06/18 17:27:57 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.190 2002/06/20 16:00:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1992,16 +1992,11 @@ _copyCopyStmt(CopyStmt *from)
|
||||
{
|
||||
CopyStmt *newnode = makeNode(CopyStmt);
|
||||
|
||||
newnode->binary = from->binary;
|
||||
Node_Copy(from, newnode, relation);
|
||||
newnode->oids = from->oids;
|
||||
newnode->direction = from->direction;
|
||||
newnode->is_from = from->is_from;
|
||||
if (from->filename)
|
||||
newnode->filename = pstrdup(from->filename);
|
||||
if (from->delimiter)
|
||||
newnode->delimiter = pstrdup(from->delimiter);
|
||||
if (from->null_print)
|
||||
newnode->null_print = pstrdup(from->null_print);
|
||||
Node_Copy(from, newnode, options);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.136 2002/06/18 17:27:57 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.137 2002/06/20 16:00:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -799,19 +799,13 @@ _equalClusterStmt(ClusterStmt *a, ClusterStmt *b)
|
||||
static bool
|
||||
_equalCopyStmt(CopyStmt *a, CopyStmt *b)
|
||||
{
|
||||
if (a->binary != b->binary)
|
||||
return false;
|
||||
if (!equal(a->relation, b->relation))
|
||||
return false;
|
||||
if (a->oids != b->oids)
|
||||
return false;
|
||||
if (a->direction != b->direction)
|
||||
if (a->is_from != b->is_from)
|
||||
return false;
|
||||
if (!equalstr(a->filename, b->filename))
|
||||
return false;
|
||||
if (!equalstr(a->delimiter, b->delimiter))
|
||||
return false;
|
||||
if (!equalstr(a->null_print, b->null_print))
|
||||
if (!equal(a->options, b->options))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.331 2002/06/19 15:40:58 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.332 2002/06/20 16:00:43 momjian Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -159,8 +159,8 @@ static void doNegateFloat(Value *v);
|
||||
%type <node> alter_column_default
|
||||
%type <ival> add_drop, drop_behavior, opt_drop_behavior
|
||||
|
||||
%type <list> createdb_opt_list
|
||||
%type <defelt> createdb_opt_item
|
||||
%type <list> createdb_opt_list, copy_opt_list
|
||||
%type <defelt> createdb_opt_item, copy_opt_item
|
||||
|
||||
%type <ival> opt_lock, lock_type
|
||||
%type <boolean> opt_force, opt_or_replace
|
||||
@ -182,7 +182,7 @@ static void doNegateFloat(Value *v);
|
||||
%type <str> TriggerEvents
|
||||
%type <value> TriggerFuncArg
|
||||
|
||||
%type <str> relation_name, copy_file_name, copy_delimiter, copy_null,
|
||||
%type <str> relation_name, copy_file_name,
|
||||
database_name, access_method_clause, access_method, attr_name,
|
||||
index_name, name, function_name, file_name
|
||||
|
||||
@ -236,11 +236,14 @@ static void doNegateFloat(Value *v);
|
||||
%type <ival> opt_interval
|
||||
%type <node> overlay_placing, substr_from, substr_for
|
||||
|
||||
%type <boolean> opt_binary, opt_instead, opt_cursor
|
||||
%type <boolean> opt_with_copy, index_opt_unique, opt_verbose, opt_full
|
||||
%type <boolean> opt_instead, opt_cursor
|
||||
%type <boolean> index_opt_unique, opt_verbose, opt_full
|
||||
%type <boolean> opt_freeze
|
||||
%type <defelt> opt_binary, opt_oids, copy_delimiter
|
||||
|
||||
%type <ival> copy_dirn, direction, reindex_type, drop_type,
|
||||
%type <boolean> copy_from
|
||||
|
||||
%type <ival> direction, reindex_type, drop_type,
|
||||
opt_column, event, comment_type
|
||||
|
||||
%type <ival> fetch_how_many
|
||||
@ -330,8 +333,8 @@ static void doNegateFloat(Value *v);
|
||||
CURRENT_TIMESTAMP, CURRENT_USER, CURSOR, CYCLE,
|
||||
|
||||
DATABASE, DAY_P, DEC, DECIMAL, DECLARE, DEFAULT,
|
||||
DEFERRABLE, DEFERRED, DEFINER, DELETE_P, DELIMITERS, DESC,
|
||||
DISTINCT, DO, DOMAIN_P, DOUBLE, DROP,
|
||||
DEFERRABLE, DEFERRED, DEFINER, DELETE_P, DELIMITER, DELIMITERS,
|
||||
DESC, DISTINCT, DO, DOMAIN_P, DOUBLE, DROP,
|
||||
|
||||
EACH, ELSE, ENCODING, ENCRYPTED, END_TRANS, ESCAPE, EXCEPT,
|
||||
EXCLUSIVE, EXECUTE, EXISTS, EXPLAIN, EXTERNAL, EXTRACT,
|
||||
@ -1293,27 +1296,38 @@ opt_id: ColId { $$ = $1; }
|
||||
/*****************************************************************************
|
||||
*
|
||||
* QUERY :
|
||||
* COPY [BINARY] <relname> FROM/TO
|
||||
* [USING DELIMITERS <delimiter>]
|
||||
* COPY <relname> FROM/TO [WITH options]
|
||||
*
|
||||
* BINARY, OIDS, and DELIMITERS kept in old locations
|
||||
* for backward compatibility. 2002-06-18
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
CopyStmt: COPY opt_binary qualified_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
|
||||
CopyStmt: COPY opt_binary qualified_name opt_oids copy_from
|
||||
copy_file_name copy_delimiter opt_with copy_opt_list
|
||||
{
|
||||
CopyStmt *n = makeNode(CopyStmt);
|
||||
n->binary = $2;
|
||||
n->relation = $3;
|
||||
n->oids = $4;
|
||||
n->direction = $5;
|
||||
n->is_from = $5;
|
||||
n->filename = $6;
|
||||
n->delimiter = $7;
|
||||
n->null_print = $8;
|
||||
|
||||
n->options = NIL;
|
||||
/* Concatenate user-supplied flags */
|
||||
if ($2)
|
||||
n->options = lappend(n->options, $2);
|
||||
if ($4)
|
||||
n->options = lappend(n->options, $4);
|
||||
if ($7)
|
||||
n->options = lappend(n->options, $7);
|
||||
if ($9)
|
||||
n->options = nconc(n->options, $9);
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
copy_dirn: TO { $$ = TO; }
|
||||
| FROM { $$ = FROM; }
|
||||
copy_from:
|
||||
FROM { $$ = TRUE; }
|
||||
| TO { $$ = FALSE; }
|
||||
;
|
||||
|
||||
/*
|
||||
@ -1327,30 +1341,79 @@ copy_file_name:
|
||||
| STDOUT { $$ = NULL; }
|
||||
;
|
||||
|
||||
opt_binary: BINARY { $$ = TRUE; }
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
|
||||
|
||||
copy_opt_list:
|
||||
copy_opt_list copy_opt_item { $$ = lappend($1, $2); }
|
||||
| /* EMPTY */ { $$ = NIL; }
|
||||
;
|
||||
|
||||
opt_with_copy:
|
||||
WITH OIDS { $$ = TRUE; }
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
|
||||
copy_opt_item:
|
||||
BINARY
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "binary";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
}
|
||||
| OIDS
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "oids";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
}
|
||||
| DELIMITER opt_as Sconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "delimiter";
|
||||
$$->arg = (Node *)makeString($3);
|
||||
}
|
||||
| NULL_P opt_as Sconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "null";
|
||||
$$->arg = (Node *)makeString($3);
|
||||
}
|
||||
;
|
||||
|
||||
/* The following exist for backward compatibility */
|
||||
|
||||
opt_binary:
|
||||
BINARY
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "binary";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
}
|
||||
| /*EMPTY*/ { $$ = NULL; }
|
||||
;
|
||||
|
||||
opt_oids:
|
||||
WITH OIDS
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "oids";
|
||||
$$->arg = (Node *)makeInteger(TRUE);
|
||||
}
|
||||
| /*EMPTY*/ { $$ = NULL; }
|
||||
;
|
||||
|
||||
/*
|
||||
* the default copy delimiter is tab but the user can configure it
|
||||
*/
|
||||
copy_delimiter:
|
||||
opt_using DELIMITERS Sconst { $$ = $3; }
|
||||
| /*EMPTY*/ { $$ = "\t"; }
|
||||
/* USING DELIMITERS kept for backward compatibility. 2002-06-15 */
|
||||
opt_using DELIMITERS Sconst
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "delimiter";
|
||||
$$->arg = (Node *)makeString($3);
|
||||
}
|
||||
| /*EMPTY*/ { $$ = NULL; }
|
||||
;
|
||||
|
||||
opt_using: USING {}
|
||||
opt_using:
|
||||
USING {}
|
||||
| /*EMPTY*/ {}
|
||||
;
|
||||
|
||||
copy_null: WITH NULL_P AS Sconst { $$ = $4; }
|
||||
| /*EMPTY*/ { $$ = "\\N"; }
|
||||
;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@ -3422,10 +3485,6 @@ createdb_opt_list:
|
||||
| /* EMPTY */ { $$ = NIL; }
|
||||
;
|
||||
|
||||
/*
|
||||
* createdb_opt_item returns 2-element lists, with the first element
|
||||
* being an integer code to indicate which item was specified.
|
||||
*/
|
||||
createdb_opt_item:
|
||||
LOCATION opt_equal Sconst
|
||||
{
|
||||
@ -6529,6 +6588,7 @@ unreserved_keyword:
|
||||
| DEFERRED
|
||||
| DEFINER
|
||||
| DELETE_P
|
||||
| DELIMITER
|
||||
| DELIMITERS
|
||||
| DOMAIN_P
|
||||
| DOUBLE
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.114 2002/06/15 03:00:03 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.115 2002/06/20 16:00:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -98,6 +98,7 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"deferred", DEFERRED},
|
||||
{"definer", DEFINER},
|
||||
{"delete", DELETE_P},
|
||||
{"delimiter", DELIMITER},
|
||||
{"delimiters", DELIMITERS},
|
||||
{"desc", DESC},
|
||||
{"distinct", DISTINCT},
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.157 2002/06/18 17:27:58 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.158 2002/06/20 16:00:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -347,22 +347,10 @@ ProcessUtility(Node *parsetree,
|
||||
{
|
||||
CopyStmt *stmt = (CopyStmt *) parsetree;
|
||||
|
||||
if (stmt->direction != FROM)
|
||||
if (!stmt->is_from)
|
||||
SetQuerySnapshot();
|
||||
|
||||
DoCopy(stmt->relation,
|
||||
stmt->binary,
|
||||
stmt->oids,
|
||||
(bool) (stmt->direction == FROM),
|
||||
(bool) (stmt->filename == NULL),
|
||||
|
||||
/*
|
||||
* null filename means copy to/from stdout/stdin, rather
|
||||
* than to/from a file.
|
||||
*/
|
||||
stmt->filename,
|
||||
stmt->delimiter,
|
||||
stmt->null_print);
|
||||
DoCopy(stmt);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -29,7 +29,7 @@ a text file named <samp>newref.txt</samp> that starts like this:<p>
|
||||
Notice that there are two consecutive tildes to allow for the fact that this
|
||||
particular entry doesn't have anything in the <b>Editor</b> field.
|
||||
You can then perform a <em>Query</em> as follows:<p>
|
||||
<samp>COPY psyref FROM '/home/jim/newref.txt' USING DELIMITERS
|
||||
<samp>COPY psyref FROM '/home/jim/newref.txt' WITH DELIMITER
|
||||
'~';</samp><p>
|
||||
This will read the records from <samp>newref.txt</samp> and insert them into the
|
||||
table <samp>psyref</samp>. See the PostgreSQL documentation under the headings
|
||||
|
@ -5,10 +5,10 @@ and the name must be specified from the viewpoint of the backend. If stdin or st
|
||||
" {} "
|
||||
COPY \[ BINARY \] table \[ WITH OIDS \]
|
||||
FROM { 'filename' | stdin }
|
||||
\[ USING DELIMITERS 'delimiter' \]
|
||||
\[ WITH DELIMITER 'delimiter' \]
|
||||
COPY \[ BINARY \] table \[ WITH OIDS \]
|
||||
TO { 'filename' | stdout }
|
||||
\[ USING DELIMITERS 'delimiter' \]
|
||||
\[ WITH DELIMITER 'delimiter' \]
|
||||
|
||||
" {code} "Inputs" {bold} "
|
||||
|
||||
@ -44,7 +44,7 @@ COPY \[ BINARY \] table \[ WITH OIDS \]
|
||||
" {} "Usage" {bold} "
|
||||
|
||||
The following example copies a table to standard output, using a vertical bar \(\"|\"\) as the field delimiter:
|
||||
COPY country TO stdout USING DELIMITERS '|';
|
||||
COPY country TO stdout WITH DELIMITER '|';
|
||||
|
||||
To copy data from a Unix file into a table \"country\":
|
||||
COPY country FROM '/usr1/proj/bray/sql/country_data';
|
||||
@ -93,13 +93,12 @@ The format for each instance in the file is as follows. Note that this format mu
|
||||
|
||||
The " {} "BINARY" {bold} " keyword will force all data to be stored/read as binary objects rather than as text. It is somewhat faster than the normal copy command, but is not generally portable, and the files \
|
||||
generated are somewhat larger, although this factor is highly dependent on the data itself. By default, a text copy uses a tab \
|
||||
\(\"\\t\"\) character as a delimiter. The delimiter may also be changed to any other single character with the keyword phrase USING DELIMITERS. Characters in data fields which happen to match the delimiter character will be quoted.
|
||||
\(\"\\t\"\) character as a delimiter. The delimiter may also be changed to any other single character with the keyword phrase WITH DELIMITER. Characters in data fields which happen to match the delimiter character will be quoted.
|
||||
|
||||
You must have select access on any table whose values are read by " {} "COPY" {bold} ", and either insert or update access to a table into which values are being inserted by \
|
||||
" {} "COPY" {bold} ". The backend also needs appropriate Unix permissions for any file read or written by \
|
||||
" {} "COPY" {bold} ".
|
||||
|
||||
The keyword phrase " {} "USING DELIMITERS" {bold} " specifies a single character to be used for all delimiters between columns. If multiple characters are specified in the delimiter string, only the first \
|
||||
character is used.
|
||||
The keyword phrase " {} "WITH DELIMITER" {bold} " specifies a single character to be used for all delimiters between columns.
|
||||
|
||||
Tip: Do not confuse " {} "COPY" {bold} " with the psql instruction \\copy. "
|
||||
|
@ -636,6 +636,8 @@ proc vTclWindow.pgaw:ImportExport {base} {
|
||||
if {$PgAcVar(impexp,delimiter)==""} {
|
||||
set sup ""
|
||||
} else {
|
||||
# now we use WITH DELIMITER, but keep old syntax for
|
||||
# backward compatibility. 2002-06-15
|
||||
set sup " USING DELIMITERS '$PgAcVar(impexp,delimiter)'"
|
||||
}
|
||||
if {[.pgaw:ImportExport.expbtn cget -text]=="Import"} {
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright 2000 by PostgreSQL Global Development Group
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.22 2002/04/24 21:00:10 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.23 2002/06/20 16:00:44 momjian Exp $
|
||||
*/
|
||||
#include "postgres_fe.h"
|
||||
#include "copy.h"
|
||||
@ -36,9 +36,12 @@ bool copy_in_state;
|
||||
* parse_slash_copy
|
||||
* -- parses \copy command line
|
||||
*
|
||||
* Accepted syntax: \copy [binary] table|"table" [with oids] from|to filename|'filename' [ using delimiters '<char>'] [ with null as 'string' ]
|
||||
* Accepted syntax: \copy table|"table" [with oids] from|to filename|'filename' [with ] [ oids ] [ delimiter '<char>'] [ null as 'string' ]
|
||||
* (binary is not here yet)
|
||||
*
|
||||
* Old syntax for backward compatibility: (2002-06-19):
|
||||
* \copy table|"table" [with oids] from|to filename|'filename' [ using delimiters '<char>'] [ with null as 'string' ]
|
||||
*
|
||||
* returns a malloc'ed structure with the options, or NULL on parsing error
|
||||
*/
|
||||
|
||||
@ -120,6 +123,7 @@ parse_slash_copy(const char *args)
|
||||
error = true;
|
||||
else
|
||||
{
|
||||
/* Allows old COPY syntax for backward compatibility 2002-06-19 */
|
||||
if (strcasecmp(token, "with") == 0)
|
||||
{
|
||||
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||
@ -161,12 +165,11 @@ parse_slash_copy(const char *args)
|
||||
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||
if (token)
|
||||
{
|
||||
/* Allows old COPY syntax for backward compatibility 2002-06-19 */
|
||||
if (strcasecmp(token, "using") == 0)
|
||||
{
|
||||
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||
if (!token || strcasecmp(token, "delimiters") != 0)
|
||||
error = true;
|
||||
else
|
||||
if (token && strcasecmp(token, "delimiters") == 0)
|
||||
{
|
||||
token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding);
|
||||
if (token)
|
||||
@ -177,34 +180,44 @@ parse_slash_copy(const char *args)
|
||||
else
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!error && token)
|
||||
{
|
||||
if (strcasecmp(token, "with") == 0)
|
||||
{
|
||||
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||
if (!token || strcasecmp(token, "null") != 0)
|
||||
error = true;
|
||||
else
|
||||
{
|
||||
token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding);
|
||||
if (!token || strcasecmp(token, "as") != 0)
|
||||
error = true;
|
||||
else
|
||||
{
|
||||
token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding);
|
||||
if (token)
|
||||
result->null = xstrdup(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!error && token)
|
||||
{
|
||||
if (strcasecmp(token, "with") == 0)
|
||||
{
|
||||
while (!error && (token = strtokx(NULL, " \t\n\r", NULL, '\\', NULL, NULL, pset.encoding)))
|
||||
{
|
||||
if (strcasecmp(token, "delimiter") == 0)
|
||||
{
|
||||
token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding);
|
||||
if (token && strcasecmp(token, "as") == 0)
|
||||
token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding);
|
||||
if (token)
|
||||
result->delim = xstrdup(token);
|
||||
else
|
||||
error = true;
|
||||
}
|
||||
else if (strcasecmp(token, "null") == 0)
|
||||
{
|
||||
token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding);
|
||||
if (token && strcasecmp(token, "as") == 0)
|
||||
token = strtokx(NULL, " \t\n\r", "'", '\\', NULL, NULL, pset.encoding);
|
||||
if (token)
|
||||
result->null = xstrdup(token);
|
||||
else
|
||||
error = true;
|
||||
}
|
||||
else error = true;
|
||||
}
|
||||
}
|
||||
else error = true;
|
||||
}
|
||||
|
||||
free(line);
|
||||
|
||||
if (error)
|
||||
@ -250,6 +263,7 @@ do_copy(const char *args)
|
||||
appendPQExpBuffer(&query, "BINARY ");
|
||||
|
||||
appendPQExpBuffer(&query, "\"%s\" ", options->table);
|
||||
/* Uses old COPY syntax for backward compatibility 2002-06-19 */
|
||||
if (options->oids)
|
||||
appendPQExpBuffer(&query, "WITH OIDS ");
|
||||
|
||||
@ -259,6 +273,7 @@ do_copy(const char *args)
|
||||
appendPQExpBuffer(&query, "TO STDOUT");
|
||||
|
||||
|
||||
/* Uses old COPY syntax for backward compatibility 2002-06-19 */
|
||||
if (options->delim)
|
||||
appendPQExpBuffer(&query, " USING DELIMITERS '%s'", options->delim);
|
||||
|
||||
@ -298,7 +313,7 @@ do_copy(const char *args)
|
||||
free_copy_options(options);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
result = PSQLexec(query.data);
|
||||
termPQExpBuffer(&query);
|
||||
|
||||
|
@ -7,19 +7,18 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: copy.h,v 1.17 2002/03/29 19:06:21 tgl Exp $
|
||||
* $Id: copy.h,v 1.18 2002/06/20 16:00:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef COPY_H
|
||||
#define COPY_H
|
||||
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "nodes/primnodes.h"
|
||||
|
||||
extern int copy_lineno;
|
||||
|
||||
void DoCopy(const RangeVar *relation, bool binary, bool oids,
|
||||
bool from, bool pipe,
|
||||
char *filename, char *delim, char *null_print);
|
||||
void DoCopy(const CopyStmt *stmt);
|
||||
|
||||
#endif /* COPY_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: dbcommands.h,v 1.22 2002/06/18 17:27:58 momjian Exp $
|
||||
* $Id: dbcommands.h,v 1.23 2002/06/20 16:00:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
#include <nodes/parsenodes.h>
|
||||
|
||||
extern void createdb(CreatedbStmt *stmt);
|
||||
extern void createdb(const CreatedbStmt *stmt);
|
||||
extern void dropdb(const char *dbname);
|
||||
extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parsenodes.h,v 1.180 2002/06/18 17:27:58 momjian Exp $
|
||||
* $Id: parsenodes.h,v 1.181 2002/06/20 16:00:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -851,13 +851,10 @@ typedef struct ClosePortalStmt
|
||||
typedef struct CopyStmt
|
||||
{
|
||||
NodeTag type;
|
||||
bool binary; /* is a binary copy? */
|
||||
RangeVar *relation; /* the relation to copy */
|
||||
bool oids; /* copy oid's? */
|
||||
int direction; /* TO or FROM */
|
||||
bool is_from; /* TO or FROM */
|
||||
char *filename; /* if NULL, use stdin/stdout */
|
||||
char *delimiter; /* delimiter character, \t by default */
|
||||
char *null_print; /* how to print NULLs, `\N' by default */
|
||||
List *options; /* List of DefElem nodes */
|
||||
} CopyStmt;
|
||||
|
||||
/* ----------------------
|
||||
|
@ -13,7 +13,7 @@ import org.postgresql.util.PSQLException;
|
||||
/*
|
||||
* This class provides information about the database as a whole.
|
||||
*
|
||||
* $Id: DatabaseMetaData.java,v 1.46 2002/06/11 02:55:16 barry Exp $
|
||||
* $Id: DatabaseMetaData.java,v 1.47 2002/06/20 16:00:44 momjian Exp $
|
||||
*
|
||||
* <p>Many of the methods here return lists of information in ResultSets. You
|
||||
* can use the normal ResultSet methods such as getString and getInt to
|
||||
@ -370,7 +370,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
*/
|
||||
public String getSQLKeywords() throws SQLException
|
||||
{
|
||||
return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version";
|
||||
return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiter,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version";
|
||||
}
|
||||
|
||||
public String getNumericFunctions() throws SQLException
|
||||
|
@ -15,7 +15,7 @@ import org.postgresql.util.PSQLException;
|
||||
/*
|
||||
* This class provides information about the database as a whole.
|
||||
*
|
||||
* $Id: DatabaseMetaData.java,v 1.55 2002/06/11 02:55:16 barry Exp $
|
||||
* $Id: DatabaseMetaData.java,v 1.56 2002/06/20 16:00:44 momjian Exp $
|
||||
*
|
||||
* <p>Many of the methods here return lists of information in ResultSets. You
|
||||
* can use the normal ResultSet methods such as getString and getInt to
|
||||
@ -409,7 +409,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
|
||||
public String getSQLKeywords() throws SQLException
|
||||
{
|
||||
if (Driver.logDebug) Driver.debug("getSQLKeyWords");
|
||||
return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version";
|
||||
return "abort,acl,add,aggregate,append,archive,arch_store,backward,binary,change,cluster,copy,database,delimiter,delimiters,do,extend,explain,forward,heavy,index,inherits,isnull,light,listen,load,merge,nothing,notify,notnull,oids,purge,rename,replace,retrieve,returns,rule,recipe,setof,stdin,stdout,store,vacuum,verbose,version";
|
||||
}
|
||||
|
||||
public String getNumericFunctions() throws SQLException
|
||||
|
@ -1,4 +1,4 @@
|
||||
COPY wordlist FROM stdin USING DELIMITERS '|';
|
||||
COPY wordlist FROM stdin WITH DELIMITER '|';
|
||||
AAA |<EFBFBD><EFBFBD><EFBFBD>
|
||||
AAAAa |<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
BBBB |BBBB
|
||||
|
@ -1,4 +1,4 @@
|
||||
COPY wordlist FROM stdin USING DELIMITERS '|';
|
||||
COPY wordlist FROM stdin WITH DELIMITER '|';
|
||||
AAA |<EFBFBD><EFBFBD><EFBFBD>
|
||||
AAAAa |<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
BBBB |BBBB
|
||||
|
@ -1,4 +1,4 @@
|
||||
COPY usastates FROM stdin USING DELIMITERS '|';
|
||||
COPY usastates FROM stdin WITH DELIMITER '|';
|
||||
AK|Alaska |ÁëÜóêá
|
||||
WA|Washington |Ãïõüóéíãêôïí
|
||||
OR|Oregon |Ïñåãêïí
|
||||
|
@ -1,4 +1,4 @@
|
||||
COPY usastates FROM stdin USING DELIMITERS '|';
|
||||
COPY usastates FROM stdin WITH DELIMITER '|';
|
||||
AK|Alaska |áÌÑÓËÁ
|
||||
WA|Washington |÷ÁÛÉÎÇÔÏÎ
|
||||
OR|Oregon |ïÒÅÇÏÎ
|
||||
|
@ -1,4 +1,4 @@
|
||||
COPY usastates FROM stdin USING DELIMITERS '|';
|
||||
COPY usastates FROM stdin WITH DELIMITER '|';
|
||||
AK|Alaska |Àëÿñêà
|
||||
WA|Washington |Âàøèíãòîí
|
||||
OR|Oregon |Îðåãîí
|
||||
|
Loading…
x
Reference in New Issue
Block a user