20101224-switch_in_next.patch

application/octet-stream

Filename: 20101224-switch_in_next.patch
Type: application/octet-stream
Part: 0
Message: Re: SQL/MED - file_fdw

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/commands/copy.c 0 0
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index d884764..c0c228f 100644
*** a/src/backend/commands/copy.c
--- b/src/backend/commands/copy.c
*************** CopyFrom(CopyState cstate)
*** 1875,1886 ****
  
  		CHECK_FOR_INTERRUPTS();
  
- 		/* Reset the per-tuple exprcontext */
- 		ResetPerTupleExprContext(estate);
- 
- 		/* Switch into its memory context */
- 		MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
- 
  		done = !NextCopyFrom(cstate, values, nulls, &loaded_oid);
  		if (done)
  			break;
--- 1875,1880 ----
*************** CopyFrom(CopyState cstate)
*** 1891,1899 ****
  		if (loaded_oid != InvalidOid)
  			HeapTupleSetOid(tuple, loaded_oid);
  
- 		/* Triggers and stuff need to be invoked in query context. */
- 		MemoryContextSwitchTo(oldcontext);
- 
  		skip_tuple = false;
  
  		/* BEFORE ROW INSERT Triggers */
--- 1885,1890 ----
*************** CopyFrom(CopyState cstate)
*** 1918,1924 ****
  			List	   *recheckIndexes = NIL;
  
  			/* Place tuple in tuple slot */
! 			ExecStoreTuple(tuple, slot, InvalidBuffer, false);
  
  			/* Check the constraints of the tuple */
  			if (cstate->rel->rd_att->constr)
--- 1909,1915 ----
  			List	   *recheckIndexes = NIL;
  
  			/* Place tuple in tuple slot */
! 			ExecStoreTuple(tuple, slot, InvalidBuffer, true);
  
  			/* Check the constraints of the tuple */
  			if (cstate->rel->rd_att->constr)
*************** BeginCopyFrom(Relation rel,
*** 2170,2179 ****
--- 2161,2173 ----
   * valus and nulls arrays must be the same length as columns of the
   * relation passed to BeginCopyFrom. Oid of the tuple is returned with
   * tupleOid separately.
+  *
+  * We do everything in per-tuple context and it would be reset in the head.
   */
  bool
  NextCopyFrom(CopyState cstate, Datum *values, bool *nulls, Oid *tupleOid)
  {
+ 	MemoryContext oldcontext = CurrentMemoryContext;
  	TupleDesc	tupDesc;
  	Form_pg_attribute *attr;
  	AttrNumber	num_phys_attrs,
*************** NextCopyFrom(CopyState cstate, Datum *va
*** 2190,2201 ****
--- 2184,2202 ----
  	ExprState **defexprs = cstate->defexprs;
  	ExprContext	*econtext;		/* used for ExecEvalExpr for default atts */
  
+ 	/* Reset the per-tuple exprcontext and switch into its memory context */
+ 	ResetPerTupleExprContext(cstate->estate);
+ 	MemoryContextSwitchTo(GetPerTupleMemoryContext(cstate->estate));
+ 
  	/* on input just throw the header line away */
  	if (cstate->cur_lineno == 0 && cstate->header_line)
  	{
  		cstate->cur_lineno++;
  		if (CopyReadLine(cstate))
+ 		{
+ 			MemoryContextSwitchTo(oldcontext);
  			return false;	/* done */
+ 		}
  	}
  
  	tupDesc = RelationGetDescr(cstate->rel);
*************** NextCopyFrom(CopyState cstate, Datum *va
*** 2228,2234 ****
--- 2229,2238 ----
  		 * EOF, ie, process the line and then exit loop on next iteration.
  		 */
  		if (done && cstate->line_buf.len == 0)
+ 		{
+ 			MemoryContextSwitchTo(oldcontext);
  			return false;
+ 		}
  
  		/* Parse the line into de-escaped field values */
  		if (cstate->csv_mode)
*************** NextCopyFrom(CopyState cstate, Datum *va
*** 2316,2321 ****
--- 2320,2326 ----
  		if (!CopyGetInt16(cstate, &fld_count))
  		{
  			/* EOF detected (end of file, or protocol-level EOF) */
+ 			MemoryContextSwitchTo(oldcontext);
  			return false;
  		}
  
*************** NextCopyFrom(CopyState cstate, Datum *va
*** 2340,2345 ****
--- 2345,2351 ----
  				ereport(ERROR,
  						(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
  						 errmsg("received copy data after EOF marker")));
+ 			MemoryContextSwitchTo(oldcontext);
  			return false;
  		}
  
*************** NextCopyFrom(CopyState cstate, Datum *va
*** 2400,2405 ****
--- 2406,2412 ----
  										 &nulls[defmap[i]], NULL);
  	}
  
+ 	MemoryContextSwitchTo(oldcontext);
  	return true;
  }