|
44 | 44 | #include"utils/builtins.h"
|
45 | 45 | #include"utils/lsyscache.h"
|
46 | 46 | #include"utils/memutils.h"
|
| 47 | +#include"utils/portal.h" |
47 | 48 | #include"utils/rel.h"
|
48 | 49 | #include"utils/snapmgr.h"
|
49 | 50 |
|
@@ -109,6 +110,7 @@ typedef struct CopyStateData
|
109 | 110 | char*filename;/* filename, or NULL for STDIN/STDOUT */
|
110 | 111 | boolbinary;/* binary format? */
|
111 | 112 | booloids;/* include OIDs? */
|
| 113 | +boolfreeze;/* freeze rows on loading? */ |
112 | 114 | boolcsv_mode;/* Comma Separated Value format? */
|
113 | 115 | boolheader_line;/* CSV header line? */
|
114 | 116 | char*null_print;/* NULL marker string (server encoding!) */
|
@@ -895,6 +897,14 @@ ProcessCopyOptions(CopyState cstate,
|
895 | 897 | errmsg("conflicting or redundant options")));
|
896 | 898 | cstate->oids=defGetBoolean(defel);
|
897 | 899 | }
|
| 900 | +elseif (strcmp(defel->defname,"freeze")==0) |
| 901 | +{ |
| 902 | +if (cstate->freeze) |
| 903 | +ereport(ERROR, |
| 904 | +(errcode(ERRCODE_SYNTAX_ERROR), |
| 905 | +errmsg("conflicting or redundant options"))); |
| 906 | +cstate->freeze=defGetBoolean(defel); |
| 907 | +} |
898 | 908 | elseif (strcmp(defel->defname,"delimiter")==0)
|
899 | 909 | {
|
900 | 910 | if (cstate->delim)
|
@@ -1974,8 +1984,31 @@ CopyFrom(CopyState cstate)
|
1974 | 1984 | hi_options |=HEAP_INSERT_SKIP_FSM;
|
1975 | 1985 | if (!XLogIsNeeded())
|
1976 | 1986 | hi_options |=HEAP_INSERT_SKIP_WAL;
|
| 1987 | + |
| 1988 | +/* |
| 1989 | + * Optimize if new relfilenode was created in this subxact or |
| 1990 | + * one of its committed children and we won't see those rows later |
| 1991 | + * as part of an earlier scan or command. This ensures that if this |
| 1992 | + * subtransaction aborts then the frozen rows won't be visible |
| 1993 | + * after xact cleanup. Note that the stronger test of exactly |
| 1994 | + * which subtransaction created it is crucial for correctness |
| 1995 | + * of this optimisation. |
| 1996 | + */ |
| 1997 | +if (ThereAreNoPriorRegisteredSnapshots()&& |
| 1998 | +ThereAreNoReadyPortals()&& |
| 1999 | +cstate->rel->rd_newRelfilenodeSubid==GetCurrentSubTransactionId()) |
| 2000 | +{ |
| 2001 | +hi_options |=HEAP_INSERT_COMMITTED; |
| 2002 | +if (cstate->freeze) |
| 2003 | +hi_options |=HEAP_INSERT_FROZEN; |
| 2004 | +} |
1977 | 2005 | }
|
1978 | 2006 |
|
| 2007 | +if (cstate->freeze&& (hi_options&HEAP_INSERT_FROZEN)==0) |
| 2008 | +ereport(NOTICE, |
| 2009 | +(errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 2010 | +errmsg("FREEZE option specified but pre-conditions not met"))); |
| 2011 | + |
1979 | 2012 | /*
|
1980 | 2013 | * We need a ResultRelInfo so we can use the regular executor's
|
1981 | 2014 | * index-entry-making machinery. (There used to be a huge amount of code
|
|