diff -cpr head/src/backend/commands/copy.c force_quote_all/src/backend/commands/copy.c
*** head/src/backend/commands/copy.c	Mon Apr 20 09:35:39 2009
--- force_quote_all/src/backend/commands/copy.c	Tue May 12 13:46:23 2009
*************** DoCopy(const CopyStmt *stmt, const char 
*** 730,735 ****
--- 730,738 ----
  	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));
  
*************** DoCopy(const CopyStmt *stmt, const char 
*** 809,814 ****
--- 812,821 ----
  						(errcode(ERRCODE_SYNTAX_ERROR),
  						 errmsg("conflicting or redundant options")));
  			force_quote = (List *) defel->arg;
+ 
+ 			/* NIL means all-columns */
+ 			if (force_quote == NIL)
+ 				force_quote = &all_columns;
  		}
  		else if (strcmp(defel->defname, "force_notnull") == 0)
  		{
*************** DoCopy(const CopyStmt *stmt, const char 
*** 817,822 ****
--- 824,833 ----
  						(errcode(ERRCODE_SYNTAX_ERROR),
  						 errmsg("conflicting or redundant options")));
  			force_notnull = (List *) defel->arg;
+ 
+ 			/* NIL means all-columns */
+ 			if (force_notnull == NIL)
+ 				force_notnull = &all_columns;
  		}
  		else
  			elog(ERROR, "option \"%s\" not recognized",
*************** DoCopy(const CopyStmt *stmt, const char 
*** 1092,1098 ****
  
  	/* 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)
  	{
  		List	   *attnums;
  		ListCell   *cur;
--- 1103,1116 ----
  
  	/* 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 == &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;
*************** DoCopy(const CopyStmt *stmt, const char 
*** 1114,1120 ****
  
  	/* Convert FORCE NOT NULL name list to per-column flags, check validity */
  	cstate->force_notnull_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
! 	if (force_notnull)
  	{
  		List	   *attnums;
  		ListCell   *cur;
--- 1132,1145 ----
  
  	/* Convert FORCE NOT NULL name list to per-column flags, check validity */
  	cstate->force_notnull_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool));
! 	if (force_notnull == &all_columns)
! 	{
! 		int		i;
! 
! 		for (i = 0; i < num_phys_attrs; i++)
! 			cstate->force_notnull_flags[i] = true;
! 	}
! 	else if (force_notnull)
  	{
  		List	   *attnums;
  		ListCell   *cur;
diff -cpr head/src/backend/parser/gram.y force_quote_all/src/backend/parser/gram.y
*** head/src/backend/parser/gram.y	Thu Apr 30 09:43:10 2009
--- force_quote_all/src/backend/parser/gram.y	Tue May 12 13:46:23 2009
*************** copy_opt_item:
*** 1989,1997 ****
--- 1989,2005 ----
  				{
  					$$ = makeDefElem("force_quote", (Node *)$3);
  				}
+ 			| FORCE QUOTE '*'
+ 				{
+ 					$$ = makeDefElem("force_quote", NULL);
+ 				}
  			| FORCE NOT NULL_P columnList
  				{
  					$$ = makeDefElem("force_notnull", (Node *)$4);
+ 				}
+ 			| FORCE NOT NULL_P '*'
+ 				{
+ 					$$ = makeDefElem("force_notnull", NULL);
  				}
  		;
  
diff -cpr head/src/test/regress/expected/copy2.out force_quote_all/src/test/regress/expected/copy2.out
*** head/src/test/regress/expected/copy2.out	Tue Oct 10 16:16:01 2006
--- force_quote_all/src/test/regress/expected/copy2.out	Tue May 12 13:46:23 2009
*************** COPY y TO stdout WITH CSV FORCE QUOTE co
*** 191,196 ****
--- 191,200 ----
  "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;
diff -cpr head/src/test/regress/sql/copy2.sql force_quote_all/src/test/regress/sql/copy2.sql
*** head/src/test/regress/sql/copy2.sql	Tue Oct 10 16:16:01 2006
--- force_quote_all/src/test/regress/sql/copy2.sql	Tue May 12 13:46:23 2009
*************** INSERT INTO y VALUES ('', NULL);
*** 128,133 ****
--- 128,134 ----
  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
  
