20110113-copy_context.patch
application/octet-stream
Filename: 20110113-copy_context.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 00139b9..5ee6bb0 100644
*** a/src/backend/commands/copy.c
--- b/src/backend/commands/copy.c
*************** typedef struct CopyStateData
*** 124,129 ****
--- 124,134 ----
const char *cur_attval; /* current att value for error messages */
/*
+ * Working state for COPY TO/FROM
+ */
+ MemoryContext copycontext; /* per-copy execution context */
+
+ /*
* Working state for COPY TO
*/
FmgrInfo *out_functions; /* lookup info for output functions */
*************** static const char BinarySignature[11] =
*** 260,265 ****
--- 265,271 ----
/* non-export function prototypes */
static CopyState BeginCopy(bool is_from, Relation rel, Node *raw_query,
const char *queryString, List *attnamelist, List *options);
+ static void EndCopy(CopyState cstate);
static CopyState BeginCopyTo(Relation rel, Node *query, const char *queryString,
const char *filename, List *attnamelist, List *options);
static void EndCopyTo(CopyState cstate);
*************** BeginCopy(bool is_from,
*** 839,848 ****
--- 845,870 ----
ListCell *option;
TupleDesc tupDesc;
int num_phys_attrs;
+ MemoryContext oldcontext;
/* Allocate workspace and zero all fields */
cstate = (CopyStateData *) palloc0(sizeof(CopyStateData));
+ /*
+ * We allocate everything linked from cstate in new per-COPY context
+ * which is created in caller's context.
+ * This would avoid memory leak repeated COPY use in a query.
+ *
+ * Caller should MemoryContextDelete(cstate->copycontext) first, and then
+ * pfree(cstate) to release memory.
+ */
+ cstate->copycontext = AllocSetContextCreate(CurrentMemoryContext,
+ "COPY context",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+ oldcontext = MemoryContextSwitchTo(cstate->copycontext);
+
/* Extract options from the statement node tree */
foreach(option, options)
{
*************** BeginCopy(bool is_from,
*** 1242,1250 ****
--- 1264,1284 ----
cstate->copy_dest = COPY_FILE; /* default */
+ /* switch back to caller's context */
+ MemoryContextSwitchTo(oldcontext);
+
return cstate;
}
+ /*
+ * Release resources allocated in BeginCopu() for this copy execution.
+ */
+ static void
+ EndCopy(CopyState cstate)
+ {
+ MemoryContextDelete(cstate->copycontext);
+ pfree(cstate);
+ }
/*
* Setup CopyState to read tuples from a table or a query for COPY TO.
*************** BeginCopyTo(Relation rel,
*** 1259,1266 ****
--- 1293,1302 ----
{
CopyState cstate;
bool pipe = (filename == NULL);
+ MemoryContext oldcontext;
cstate = BeginCopy(false, rel, query, queryString, attnamelist, options);
+ oldcontext = MemoryContextSwitchTo(cstate->copycontext);
if (cstate->rel)
{
*************** BeginCopyTo(Relation rel,
*** 1328,1333 ****
--- 1364,1372 ----
errmsg("\"%s\" is a directory", cstate->filename)));
}
+ /* switch back to caller's context */
+ MemoryContextSwitchTo(oldcontext);
+
return cstate;
}
*************** EndCopyTo(CopyState cstate)
*** 1395,1401 ****
PopActiveSnapshot();
}
! pfree(cstate);
}
/*
--- 1434,1441 ----
PopActiveSnapshot();
}
! /* Release memory resources */
! EndCopy(cstate);
}
/*
*************** BeginCopyFrom(Relation rel,
*** 2010,2017 ****
--- 2050,2059 ----
EState *estate = CreateExecutorState(); /* for ExecPrepareExpr() */
int *defmap;
ExprState **defexprs;
+ MemoryContext oldcontext;
cstate = BeginCopy(true, rel, NULL, NULL, attnamelist, options);
+ oldcontext = MemoryContextSwitchTo(cstate->copycontext);
/* Initialize state variables */
cstate->fe_eof = false;
*************** BeginCopyFrom(Relation rel,
*** 2172,2177 ****
--- 2214,2221 ----
cstate->raw_fields = (char **) palloc(nfields * sizeof(char *));
}
+ MemoryContextSwitchTo(oldcontext);
+
return cstate;
}
*************** EndCopyFrom(CopyState cstate)
*** 2433,2448 ****
}
/* Clean up storage */
! if (!cstate->binary)
! pfree(cstate->raw_fields);
! pfree(cstate->attribute_buf.data);
! pfree(cstate->line_buf.data);
! pfree(cstate->raw_buf);
! pfree(cstate->in_functions);
! pfree(cstate->typioparams);
! pfree(cstate->defmap);
! pfree(cstate->defexprs);
! pfree(cstate);
}
--- 2477,2483 ----
}
/* Clean up storage */
! EndCopy(cstate);
}