ODAC 10.3.8 AV inside TOCIRecordSet.InitFetchCursor function IsValidCursor
Posted: Fri 28 Dec 2018 10:23
With Delphi RIO 10.3 and ODAC 10.3.8
we encouter an AV inside Unit OraClasses méthod TOCIRecordSet.InitFetchCursor.
The function IsValidCursor fails when it reaches the sentence OCISvcCtx.Home.OCIVersion
This happens everywhere when an oracle procedure returns a cursor.
What is even more strange is that it fails at the same place regardless off the connection using OCi or Direct MODE.
When debugging OCISvcCtx value is nil
Server is an Oracle Database 11g Release 11.2.0.4.0 - 64bit Production
When in OCI mode client is a 12.1.0.2.0 instantclient
If we change the sentence to
if assigned(OCISvcCtx) and (OCISvcCtx.Home.OCIVersion >= 9100) then // supported starting with 9.1
it works again
But we don't know if the fix is ok or if something else is required
we encouter an AV inside Unit OraClasses méthod TOCIRecordSet.InitFetchCursor.
The function IsValidCursor fails when it reaches the sentence OCISvcCtx.Home.OCIVersion
This happens everywhere when an oracle procedure returns a cursor.
What is even more strange is that it fails at the same place regardless off the connection using OCi or Direct MODE.
When debugging OCISvcCtx value is nil
Code: Select all
procedure TOCIRecordSet.InitFetchCursor;
function IsValidCursor(Cursor: TOraCursor): Boolean;
var
State: integer;
begin
if (Cursor = nil) or (Cursor.hOCIStmt = nil) then
Result := False
else begin
if OCISvcCtx.Home.OCIVersion >= 9100 then // supported starting with 9.1
Check(OCI8.OCIAttrGet2(Cursor.OCIStmt, OCI_HTYPE_STMT, State, nil, OCI_ATTR_STMT_STATE, CISvcCtx.hOCIError))
else
State := OCI_STMT_STATE_EXECUTED;
Result := (State = OCI_STMT_STATE_EXECUTED);
end;
end;
var
i: integer;
Cursor: TOraCursor;
begin
FFetchCursor := FCommand.FCursorRef;
if FCommand.NativeCursor and (FCommand.FSQLType = SQL_PLSQL) then begin
// read implicit result sets
FCommand.InitResultSets;
FFetchCursor := nil;
if FCommand.FResultSets <> nil then
for i := 0 to FCommand.FResultSets.Count - 1 do begin
Cursor := FCommand.FResultSets[i];
if IsValidCursor(Cursor) then begin
FFetchCursor := Cursor;
Break;
end;
end;
if FFetchCursor = nil then
for i := 0 to FCommand.Params.Count - 1 do
if FCommand.GetParam(i).DataType = dtCursor then begin
Cursor := FCommand.GetParam(i).GetAsCursor;
if IsValidCursor(Cursor) then begin
FFetchCursor := Cursor;
Break;
end;
end;
// redefine command type - depend on cursor: canbe executed or not
if FFetchCursor = nil then
FCommand.CommandType := ctStatement
else
FCommand.CommandType := ctCursor;
end;
end;
When in OCI mode client is a 12.1.0.2.0 instantclient
If we change the sentence to
if assigned(OCISvcCtx) and (OCISvcCtx.Home.OCIVersion >= 9100) then // supported starting with 9.1
it works again
But we don't know if the fix is ok or if something else is required