OSDN Git Service

Allow * as parameter for FORCE QUOTE for COPY CSV. Itagaki Takahiro.
authorAndrew Dunstan <andrew@dunslane.net>
Sat, 25 Jul 2009 00:07:14 +0000 (00:07 +0000)
committerAndrew Dunstan <andrew@dunslane.net>
Sat, 25 Jul 2009 00:07:14 +0000 (00:07 +0000)
doc/src/sgml/ref/copy.sgml
src/backend/commands/copy.c
src/backend/parser/gram.y
src/test/regress/expected/copy2.out
src/test/regress/sql/copy2.sql

index e7f76d3..2ea68de 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/copy.sgml,v 1.85 2009/02/06 21:22:49 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/copy.sgml,v 1.86 2009/07/25 00:07:10 adunstan Exp $
 PostgreSQL documentation
 -->
 
@@ -44,7 +44,7 @@ COPY { <replaceable class="parameter">tablename</replaceable> [ ( <replaceable c
           [ CSV [ HEADER ]
                 [ QUOTE [ AS ] '<replaceable class="parameter">quote</replaceable>' ] 
                 [ ESCAPE [ AS ] '<replaceable class="parameter">escape</replaceable>' ]
-                [ FORCE QUOTE <replaceable class="parameter">column</replaceable> [, ...] ]
+                [ FORCE QUOTE { <replaceable class="parameter">column</replaceable> [, ...] | * } ]
 </synopsis>
  </refsynopsisdiv>
  
@@ -248,7 +248,9 @@ COPY { <replaceable class="parameter">tablename</replaceable> [ ( <replaceable c
      <para>
       In <literal>CSV</> <command>COPY TO</> mode, forces quoting to be
       used for all non-<literal>NULL</> values in each specified column.
-      <literal>NULL</> output is never quoted.
+      <literal>NULL</> output is never quoted. If <literal>*</> is specified,
+      non-<literal>NULL</> values for all columns of the table will be 
+      quoted.
      </para>
     </listitem>
    </varlistentry>
index c464ed7..9048276 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.312 2009/06/11 14:48:55 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.313 2009/07/25 00:07:11 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -730,6 +730,9 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
        int                     num_phys_attrs;
        uint64          processed;
 
+       /* a dummy list that represents 'all-columns' */
+       List            all_columns = { T_List };
+       
        /* Allocate workspace and zero all fields */
        cstate = (CopyStateData *) palloc0(sizeof(CopyStateData));
 
@@ -808,7 +811,11 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
                                ereport(ERROR,
                                                (errcode(ERRCODE_SYNTAX_ERROR),
                                                 errmsg("conflicting or redundant options")));
-                       force_quote = (List *) defel->arg;
+
+                       if (IsA(defel->arg, A_Star))
+                               force_quote = &all_columns;
+                       else
+                               force_quote = (List *) defel->arg;
                }
                else if (strcmp(defel->defname, "force_notnull") == 0)
                {
@@ -1092,7 +1099,14 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
 
        /* Convert FORCE QUOTE name list to per-column flags, check validity */
        cstate->force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
-       if (force_quote)
+       if (force_quote == &all_columns)
+       {
+               int             i;
+
+               for (i = 0; i < num_phys_attrs; i++)
+                       cstate->force_quote_flags[i] = true;
+       }
+       else if (force_quote)
        {
                List       *attnums;
                ListCell   *cur;
index 7e6d55b..c88073d 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.671 2009/07/20 02:42:28 adunstan Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.672 2009/07/25 00:07:11 adunstan Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -2028,6 +2028,10 @@ copy_opt_item:
                                {
                                        $$ = makeDefElem("force_quote", (Node *)$3);
                                }
+                       | FORCE QUOTE '*'
+                               {
+                                       $$ = makeDefElem("force_quote", (Node *)makeNode(A_Star));
+                               }
                        | FORCE NOT NULL_P columnList
                                {
                                        $$ = makeDefElem("force_notnull", (Node *)$4);
index 7f374ac..5f52d6e 100644 (file)
@@ -191,6 +191,10 @@ COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE E'\\';
 "Jackson, Sam","\\h"
 "It is \"perfect\"."," "
 "",
+COPY y TO stdout WITH CSV FORCE QUOTE *;
+"Jackson, Sam","\h"
+"It is ""perfect""."," "
+"",
 --test that we read consecutive LFs properly
 CREATE TEMP TABLE testnl (a int, b text, c int);
 COPY testnl FROM stdin CSV;
index 7c23ba2..9dee93c 100644 (file)
@@ -128,6 +128,7 @@ INSERT INTO y VALUES ('', NULL);
 COPY y TO stdout WITH CSV;
 COPY y TO stdout WITH CSV QUOTE '''' DELIMITER '|';
 COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE E'\\';
+COPY y TO stdout WITH CSV FORCE QUOTE *;
 
 --test that we read consecutive LFs properly