Page 1 of 1

Dataset disconnected property and clob issue.

Posted: Fri 15 Aug 2014 12:52
by MarkF
It appears that closing a disconnected dataset that contains clobs will give an access violation if the session is closed as well. Here's a simple test case:

Table used by test case:

Code: Select all

CREATE TABLE TEST_CLOB (
  ID    NUMBER(38) NOT NULL PRIMARY KEY,
  CL    CLOB);
INSERT INTO TEST_CLOB VALUES (1, LPAD('Z', 4000, 'A'));
COMMIT;
Console app that should cause the access violation:

Code: Select all

program ODACTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  OraCall,
  Ora;

var
  FOraSession: TOraSession;
  FOraQuery: TOraQuery;
  i: integer;
begin
  FOraSession := TOraSession.Create(nil);
  try
    FOraSession.ConnectPrompt := False;
    FOraSession.Options.UnicodeEnvironment := True;
    FOraSession.Options.UseUnicode := True;
    FOraSession.ConnectString := 'SCOTT/tiger@myserver';
    FOraSession.Connect;
    FOraQuery := TOraQuery.Create(nil);
    try
      FOraQuery.Session := FOraSession;
      FOraQuery.ObjectView := True;
      FOraQuery.Options.CacheLobs := True;
      FOraQuery.FetchAll := True;
      FOraQuery.SQL.Text := 'select * from test_clob';
      try
        FOraQuery.Open;
        FOraQuery.Disconnected := True;
        FOraSession.Disconnect;
        while not FOraQuery.Eof do
        begin
          WriteLn;
          WriteLn;
          for i := 0 to FOraQuery.FieldCount - 1 do
            WriteLn('Field: ' + FOraQuery.Fields[i].AsString);
          WriteLn;
          FOraQuery.Next;
        end;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    finally
      FOraQuery.Close;  // AV here, call to TOraLob.IsTemporary with nil OCISvcCtx property
      FOraQuery.Free;
    end;
    WriteLn('Press Enter to Close.');
    ReadLn;
  finally
    FOraSession.Free;
  end;
end.
Thanks for any help!

-Mark Ford
Benthic Software

Re: Dataset disconnected property and clob issue.

Posted: Mon 18 Aug 2014 07:48
by AlexP
Hello,

Thank you for the information, we have reproduced the problem with the cursor and will try to fix it as soon as possible.

Re: Dataset disconnected property and clob issue.

Posted: Tue 19 Aug 2014 15:25
by MarkF
Thank you for looking into that. It appears that the disconnected property only works with simple types and does not work with complex types such as object (or anything that needs a service context to work.) Ideally it would work with every type, however a simpler solution would be to make it so that the dataset doesn't crash when using complex types as long as they aren't accessed after the disconnect. This would allow customers to do their own caching of those types before they set disconnected to true. Right now this (caching the objects myself) works for me right until I close the dataset, at which time I get errors because the complex types are trying to free handles that rely on a service context which is no longer available (similarly to the clob issue mentioned above.) Thanks for any help on this.

-Mark

Re: Dataset disconnected property and clob issue.

Posted: Thu 21 Aug 2014 07:44
by AlexP
Thank you, we will try to support these types in disconnect mode in one of our next versions.

Re: Dataset disconnected property and clob issue.

Posted: Thu 18 Sep 2014 10:06
by MarkF
I've verified that this issue has been fixed for LOBs. I noticed this entry in the fixed list:

Bug with releasing TOraType after disconnect is fixed

And was wondering if it was related to my request regarding OraObjects above? I've verified that the issue still occurs with OraObject types in a disconnected dataset (an AV when closing the dataset.) I'm happy to supply a test case if it helps. Thanks again for the fix to LOBS.

-Mark Ford

Re: Dataset disconnected property and clob issue.

Posted: Thu 18 Sep 2014 11:23
by AlexP
Unfortunately, there is no "simple" way to support such types in the Disconnect mode. Maybe we will be back to this feature later.

Re: Dataset disconnected property and clob issue.

Posted: Thu 18 Sep 2014 14:40
by MarkF
Thanks, I appreciate what you've done so far. I've looked through the code and it appears that some of the plumbing to do this is already there. I've made the following changes and it seems to do what I want (I'm caching the objects separately before I disconnect.) Basically I'm:

Going through the objects and calling CacheObject on each one (just to set the FCached property which keeps the objects from making some OCI calls after the disconnect, since I'm caching the objects as strings separately.)

I had to modify procedure TSharedObject.Free adding an exit if FRefCount < 1 (perhaps a band aid but it seems to work.)

-Mark