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 75e7a816f748a4cc5d100b9a9090b9ae1336f845..c09dd6092090003bf1898738fb8e34db8235a66b 100644 (file)
@@ -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 a1519998d35326e8ff01bc72b058957779b44480..9ee8ea2c8254e079e74f2eb3dc5a82b2b956a7f8 100644 (file)
@@ -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 eb786e96eabe7519ffcb1aae06bfede01b574252..38ee5585c0d01e08765d3dde202e1fcadbca09c7 100644 (file)
@@ -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 7f374ac1a6f79e41dc530501ed85254d0db9864d..5f52d6ee6cf226b65d41e58d1630683107eef2e0 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 7c23ba253c4e28a47af195963ffd3d8094b829da..9dee93c14cd4c73a76644fa5beb386ce89005b10 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