Skip to content

Commit 62ce7b2

Browse files
Fix BLOB retrieval in ibm_db.result() (#1046)
Signed-off-by: Balram Choudhary <bchoudhary@rocketsoftware.com>
1 parent 8473d58 commit 62ce7b2

1 file changed

Lines changed: 81 additions & 19 deletions

File tree

ibm_db.c

Lines changed: 81 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12883,28 +12883,90 @@ static PyObject *ibm_db_result(PyObject *self, PyObject *args)
1288312883
case SQL_LONGVARBINARY:
1288412884
#endif /* PASE */
1288512885
case SQL_VARBINARY:
12886-
switch (stmt_res->s_bin_mode)
12886+
{
12887+
LogMsg(DEBUG, "Processing SQL_BLOB/SQL_BINARY/SQL_LONGVARBINARY/SQL_VARBINARY");
12888+
targetCType = SQL_C_BINARY;
12889+
len_terChar = 0;
12890+
/* Initial buffer allocation */
12891+
out_ptr = ALLOC_N(char, INIT_BUFSIZ);
12892+
if (out_ptr == NULL)
1288712893
{
12888-
case PASSTHRU:
12889-
LogMsg(DEBUG, "SQL_BLOB/SQL_BINARY/SQL_LONGVARBINARY/SQL_VARBINARY - PASSTHRU mode, returning empty bytes");
12890-
LogMsg(INFO, "exit result()");
12891-
return PyBytes_FromStringAndSize("", 0);
12892-
break;
12893-
/* returns here */
12894-
case CONVERT:
12895-
targetCType = SQL_C_CHAR;
12896-
len_terChar = sizeof(char);
12897-
LogMsg(DEBUG, "SQL_BLOB/SQL_BINARY/SQL_LONGVARBINARY/SQL_VARBINARY - CONVERT mode, using SQL_C_CHAR");
12898-
break;
12899-
case BINARY:
12900-
targetCType = SQL_C_BINARY;
12901-
len_terChar = 0;
12902-
LogMsg(DEBUG, "SQL_BLOB/SQL_BINARY/SQL_LONGVARBINARY/SQL_VARBINARY - BINARY mode, using SQL_C_BINARY");
12903-
break;
12904-
default:
12905-
LogMsg(INFO, "exit result()");
12894+
LogMsg(ERROR, "Failed to allocate memory for BLOB data");
12895+
PyErr_SetString(PyExc_Exception,
12896+
"Failed to Allocate Memory for BLOB Data");
12897+
return NULL;
12898+
}
12899+
rc = _python_ibm_db_get_data(stmt_res,
12900+
col_num + 1,
12901+
targetCType,
12902+
out_ptr,
12903+
INIT_BUFSIZ,
12904+
&out_length);
12905+
snprintf(messageStr, sizeof(messageStr),
12906+
"SQL_Get_Data (BLOB first call) rc: %d, out_length: %d",
12907+
rc, out_length);
12908+
LogMsg(DEBUG, messageStr);
12909+
if (rc == SQL_SUCCESS_WITH_INFO)
12910+
{
12911+
LogMsg(DEBUG, "BLOB larger than INIT_BUFSIZ, reallocating buffer");
12912+
void *tmp_out_ptr = NULL;
12913+
tmp_out_ptr = ALLOC_N(char, INIT_BUFSIZ + out_length);
12914+
if (tmp_out_ptr == NULL)
12915+
{
12916+
LogMsg(ERROR, "Failed to reallocate memory for large BLOB");
12917+
PyMem_Del(out_ptr);
12918+
PyErr_SetString(PyExc_Exception,
12919+
"Failed to Reallocate Memory for Large BLOB");
12920+
return NULL;
12921+
}
12922+
memcpy(tmp_out_ptr, out_ptr, INIT_BUFSIZ);
12923+
PyMem_Del(out_ptr);
12924+
out_ptr = tmp_out_ptr;
12925+
rc = _python_ibm_db_get_data(stmt_res,
12926+
col_num + 1,
12927+
targetCType,
12928+
(char *)out_ptr + INIT_BUFSIZ,
12929+
INIT_BUFSIZ + out_length,
12930+
&out_length);
12931+
snprintf(messageStr, sizeof(messageStr),
12932+
"SQL_Get_Data (BLOB continuation) rc: %d, out_length: %d",
12933+
rc, out_length);
12934+
LogMsg(DEBUG, messageStr);
12935+
if (rc == SQL_ERROR)
12936+
{
12937+
LogMsg(ERROR, "Error retrieving extended BLOB data");
12938+
PyMem_Del(out_ptr);
12939+
return NULL;
12940+
}
12941+
retVal = PyBytes_FromStringAndSize((char *)out_ptr,
12942+
INIT_BUFSIZ + out_length);
12943+
}
12944+
else if (rc == SQL_ERROR)
12945+
{
12946+
LogMsg(ERROR, "Error retrieving BLOB data");
12947+
PyMem_Del(out_ptr);
12948+
PyErr_Clear();
1290612949
Py_RETURN_FALSE;
1290712950
}
12951+
else
12952+
{
12953+
if (out_length == SQL_NULL_DATA)
12954+
{
12955+
LogMsg(DEBUG, "BLOB column is NULL");
12956+
PyMem_Del(out_ptr);
12957+
Py_RETURN_NONE;
12958+
}
12959+
retVal = PyBytes_FromStringAndSize((char *)out_ptr,
12960+
out_length);
12961+
snprintf(messageStr, sizeof(messageStr),
12962+
"Returning BLOB data of length: %d",
12963+
out_length);
12964+
LogMsg(DEBUG, messageStr);
12965+
}
12966+
PyMem_Del(out_ptr);
12967+
LogMsg(INFO, "exit result()");
12968+
return retVal;
12969+
}
1290812970
break;
1290912971
case SQL_XML:
1291012972
case SQL_CLOB:

0 commit comments

Comments
 (0)