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:
parent
fb2e048851
commit
9be85a356c
12
Cursor.c
12
Cursor.c
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
52
LobVar.c
52
LobVar.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue