Free temporary LOBs prior to each fetch in order to avoid leaking them; thanks

to Uwe Hoffmann for the initial patch.
This commit is contained in:
Anthony Tuininga 2011-01-04 05:55:54 +00:00
parent fb2e048851
commit 9be85a356c
11 changed files with 71 additions and 15 deletions

View File

@ -1809,6 +1809,14 @@ static int Cursor_InternalFetch(
PyErr_SetString(g_InterfaceErrorException, "query not executed");
return -1;
}
for (i = 0; i < PyList_GET_SIZE(self->fetchVariables); i++) {
var = (udt_Variable*) PyList_GET_ITEM(self->fetchVariables, i);
var->internalFetchNum++;
if (var->type->preFetchProc) {
if ((*var->type->preFetchProc)(var) < 0)
return -1;
}
}
Py_BEGIN_ALLOW_THREADS
status = OCIStmtFetch(self->handle, self->environment->errorHandle,
numRows, OCI_FETCH_NEXT, OCI_DEFAULT);
@ -1818,10 +1826,6 @@ static int Cursor_InternalFetch(
"Cursor_InternalFetch(): fetch") < 0)
return -1;
}
for (i = 0; i < PyList_GET_SIZE(self->fetchVariables); i++) {
var = (udt_Variable*) PyList_GET_ITEM(self->fetchVariables, i);
var->internalFetchNum++;
}
status = OCIAttrGet(self->handle, OCI_HTYPE_STMT, &rowCount, 0,
OCI_ATTR_ROW_COUNT, self->environment->errorHandle);
if (Environment_CheckForError(self->environment, status,

View File

@ -59,6 +59,7 @@ static udt_VariableType vt_Cursor = {
(FinalizeProc) CursorVar_Finalize,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) CursorVar_SetValue,
(GetValueProc) CursorVar_GetValue,

View File

@ -55,6 +55,7 @@ static udt_VariableType vt_DateTime = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) DateTimeVar_SetValue,
(GetValueProc) DateTimeVar_GetValue,
@ -75,6 +76,7 @@ static udt_VariableType vt_Date = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) DateTimeVar_SetValue,
(GetValueProc) DateTimeVar_GetValue,

View File

@ -57,6 +57,7 @@ static udt_VariableType vt_Interval = {
(FinalizeProc) IntervalVar_Finalize,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) IntervalVar_SetValue,
(GetValueProc) IntervalVar_GetValue,

View File

@ -17,6 +17,7 @@ typedef struct {
// Declaration of LOB variable functions.
//-----------------------------------------------------------------------------
static int LobVar_Initialize(udt_LobVar*, udt_Cursor*);
static int LobVar_PreFetch(udt_LobVar*);
static void LobVar_Finalize(udt_LobVar*);
static PyObject *LobVar_GetValue(udt_LobVar*, unsigned);
static int LobVar_SetValue(udt_LobVar*, unsigned, PyObject*);
@ -133,6 +134,7 @@ static udt_VariableType vt_CLOB = {
(FinalizeProc) LobVar_Finalize,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) LobVar_PreFetch,
(IsNullProc) NULL,
(SetValueProc) LobVar_SetValue,
(GetValueProc) LobVar_GetValue,
@ -153,6 +155,7 @@ static udt_VariableType vt_NCLOB = {
(FinalizeProc) LobVar_Finalize,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) LobVar_PreFetch,
(IsNullProc) NULL,
(SetValueProc) LobVar_SetValue,
(GetValueProc) LobVar_GetValue,
@ -173,6 +176,7 @@ static udt_VariableType vt_BLOB = {
(FinalizeProc) LobVar_Finalize,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) LobVar_PreFetch,
(IsNullProc) NULL,
(SetValueProc) LobVar_SetValue,
(GetValueProc) LobVar_GetValue,
@ -193,6 +197,7 @@ static udt_VariableType vt_BFILE = {
(FinalizeProc) LobVar_Finalize,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) LobVar_PreFetch,
(IsNullProc) NULL,
(SetValueProc) LobVar_SetValue,
(GetValueProc) LobVar_GetValue,
@ -240,6 +245,40 @@ static int LobVar_Initialize(
}
//-----------------------------------------------------------------------------
// LobVar_PreFetch()
// Free temporary LOBs prior to fetch.
//-----------------------------------------------------------------------------
static int LobVar_PreFetch(
udt_LobVar *var) // variable to free
{
boolean isTemporary;
sword status;
ub4 i;
for (i = 0; i < var->allocatedElements; i++) {
if (var->data[i]) {
status = OCILobIsTemporary(var->environment->handle,
var->environment->errorHandle, var->data[i], &isTemporary);
if (Environment_CheckForError(var->environment, status,
"LobVar_PreFetch(): is temporary LOB?") < 0)
return -1;
if (isTemporary) {
Py_BEGIN_ALLOW_THREADS
status = OCILobFreeTemporary(var->connection->handle,
var->environment->errorHandle, var->data[i]);
Py_END_ALLOW_THREADS
if (Environment_CheckForError(var->environment, status,
"LobVar_PreFetch(): free temporary LOB") < 0)
return -1;
}
}
}
return 0;
}
//-----------------------------------------------------------------------------
// LobVar_Finalize()
// Prepare for variable destruction.
@ -247,21 +286,12 @@ static int LobVar_Initialize(
static void LobVar_Finalize(
udt_LobVar *var) // variable to free
{
boolean isTemporary;
ub4 i;
LobVar_PreFetch(var);
for (i = 0; i < var->allocatedElements; i++) {
if (var->data[i]) {
OCILobIsTemporary(var->environment->handle,
var->environment->errorHandle, var->data[i], &isTemporary);
if (isTemporary) {
Py_BEGIN_ALLOW_THREADS
OCILobFreeTemporary(var->connection->handle,
var->environment->errorHandle, var->data[i]);
Py_END_ALLOW_THREADS
}
if (var->data[i])
OCIDescriptorFree(var->data[i], OCI_DTYPE_LOB);
}
}
Py_DECREF(var->connection);
}

View File

@ -81,6 +81,7 @@ static udt_VariableType vt_LongString = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) LongVar_SetValue,
(GetValueProc) LongVar_GetValue,
@ -101,6 +102,7 @@ static udt_VariableType vt_LongBinary = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) LongVar_SetValue,
(GetValueProc) LongVar_GetValue,

View File

@ -95,6 +95,7 @@ static udt_VariableType vt_Float = {
(FinalizeProc) NULL,
(PreDefineProc) NumberVar_PreDefine,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) NumberVar_SetValue,
(GetValueProc) NumberVar_GetValue,
@ -116,6 +117,7 @@ static udt_VariableType vt_NativeFloat = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) NativeFloatVar_SetValue,
(GetValueProc) NativeFloatVar_GetValue,
@ -138,6 +140,7 @@ static udt_VariableType vt_Integer = {
(FinalizeProc) NULL,
(PreDefineProc) NumberVar_PreDefine,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) NumberVar_SetValue,
(GetValueProc) NumberVar_GetValue,
@ -159,6 +162,7 @@ static udt_VariableType vt_LongInteger = {
(FinalizeProc) NULL,
(PreDefineProc) NumberVar_PreDefine,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) NumberVar_SetValue,
(GetValueProc) NumberVar_GetValue,
@ -179,6 +183,7 @@ static udt_VariableType vt_NumberAsString = {
(FinalizeProc) NULL,
(PreDefineProc) NumberVar_PreDefine,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) NumberVar_SetValue,
(GetValueProc) NumberVar_GetValue,
@ -199,6 +204,7 @@ static udt_VariableType vt_Boolean = {
(FinalizeProc) NULL,
(PreDefineProc) NumberVar_PreDefine,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) NumberVar_SetValue,
(GetValueProc) NumberVar_GetValue,

View File

@ -80,6 +80,7 @@ static udt_VariableType vt_Object = {
(FinalizeProc) ObjectVar_Finalize,
(PreDefineProc) ObjectVar_PreDefine,
(PostDefineProc) ObjectVar_PostDefine,
(PreFetchProc) NULL,
(IsNullProc) ObjectVar_IsNull,
(SetValueProc) NULL,
(GetValueProc) ObjectVar_GetValue,

View File

@ -188,6 +188,7 @@ static udt_VariableType vt_String = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) StringVar_SetValue,
(GetValueProc) StringVar_GetValue,
@ -209,6 +210,7 @@ static udt_VariableType vt_NationalCharString = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) StringVar_PostDefine,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) StringVar_SetValue,
(GetValueProc) StringVar_GetValue,
@ -230,6 +232,7 @@ static udt_VariableType vt_FixedChar = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) StringVar_SetValue,
(GetValueProc) StringVar_GetValue,
@ -251,6 +254,7 @@ static udt_VariableType vt_FixedNationalChar = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) StringVar_PostDefine,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) StringVar_SetValue,
(GetValueProc) StringVar_GetValue,
@ -272,6 +276,7 @@ static udt_VariableType vt_Rowid = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) StringVar_SetValue,
(GetValueProc) StringVar_GetValue,
@ -292,6 +297,7 @@ static udt_VariableType vt_Binary = {
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) StringVar_SetValue,
(GetValueProc) StringVar_GetValue,

View File

@ -57,6 +57,7 @@ static udt_VariableType vt_Timestamp = {
(FinalizeProc) TimestampVar_Finalize,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) TimestampVar_SetValue,
(GetValueProc) TimestampVar_GetValue,

View File

@ -41,6 +41,7 @@ typedef int (*InitializeProc)(udt_Variable*, udt_Cursor*);
typedef void (*FinalizeProc)(udt_Variable*);
typedef int (*PreDefineProc)(udt_Variable*, OCIParam*);
typedef int (*PostDefineProc)(udt_Variable*);
typedef int (*PreFetchProc)(udt_Variable*);
typedef int (*IsNullProc)(udt_Variable*, unsigned);
typedef int (*SetValueProc)(udt_Variable*, unsigned, PyObject*);
typedef PyObject * (*GetValueProc)(udt_Variable*, unsigned);
@ -55,6 +56,7 @@ typedef struct _udt_VariableType {
FinalizeProc finalizeProc;
PreDefineProc preDefineProc;
PostDefineProc postDefineProc;
PreFetchProc preFetchProc;
IsNullProc isNullProc;
SetValueProc setValueProc;
GetValueProc getValueProc;