Recent

Author Topic: IBX 2.3.4 is now available for download  (Read 1603 times)

Zoran

  • Hero Member
  • *****
  • Posts: 1611
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: IBX 2.3.4 is now available for download
« Reply #15 on: April 24, 2020, 04:46:42 pm »
Thanks a lot for your help, but prepare never raises exception. See my examples. No problem in preparing phase, and after dataset is prepared, Dataset.StatementType is returned correctly.

It is only ExecSQL which raises SIGSEGV.

Now I tried to experiment more.
Interestingly, it seems that it has nothing to do with Dataset, but this also gives us SIGSEGV:

Code: Pascal  [Select][+][-]
  1. var
  2.   Stm: IStatement;
  3.   Trn: ITransaction;  
  4.   S: String;
  5.  
  6. ...
  7.  
  8.   S := 'savepoint abc';
  9.  
  10.   Trn := Database.Attachment.StartTransaction(
  11.                   [isc_tpb_write, isc_tpb_nowait, isc_tpb_rec_version, isc_tpb_read_committed]
  12.                   , TACommit);
  13.  
  14.   Stm := Database.Attachment.Prepare(Trn, S); // this is ok
  15.   Stm.Execute; // SIGSEGV
  16.  

But, if instead of Stm.Execute, I use Database.Attachement.ExecImmediate(Trn, S), then everything is fine!

I'm surprised that Execute on low level leads to SIGSEGV, whereas Dataset.Database.Attachment.ExecImmediate works just fine.

Zoran

  • Hero Member
  • *****
  • Posts: 1611
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: IBX 2.3.4 is now available for download
« Reply #16 on: April 24, 2020, 05:36:57 pm »
In unit FB30Statement.pas, look in the method TFB30Statement.InternalExecute:

ExecImmediate does not use this method, but Execute does.

There is this code (from line 1116 in trunk rev. 301):

Code: Pascal  [Select][+][-]
  1.       case FSQLStatementType of
  2.       SQLSelect:
  3.         IBError(ibxeIsAExecuteProcedure,[]);
  4.  
  5.       SQLExecProcedure:
  6.       begin
  7.         FStatementIntf.execute(StatusIntf,
  8.                                (aTransaction as TFB30Transaction).TransactionIntf,
  9.                                FSQLParams.MetaData,
  10.                                FSQLParams.MessageBuffer,
  11.                                FSQLRecord.MetaData,
  12.                                FSQLRecord.MessageBuffer);
  13.         Check4DataBaseError;
  14.  
  15.         Result := TResults.Create(FSQLRecord);
  16.         FSingleResults := true;      
  17.       end
  18.       else
  19.         FStatementIntf.execute(StatusIntf,
  20.                                (aTransaction as TFB30Transaction).TransactionIntf,
  21.                                FSQLParams.MetaData,
  22.                                FSQLParams.MessageBuffer,
  23.                                nil,
  24.                                nil);
  25.         Check4DataBaseError;
  26.       end;
  27.  

The statement with SQLSavePoint type falls in "else" branch.

I tried to add separate case for SQLSavePoint, with nil in all parameters:

Code: Pascal  [Select][+][-]
  1.       case FSQLStatementType of
  2.       SQLSelect:
  3.         IBError(ibxeIsAExecuteProcedure,[]);
  4.  
  5.       SQLExecProcedure:
  6.       begin
  7.         FStatementIntf.execute(StatusIntf,
  8.                                (aTransaction as TFB30Transaction).TransactionIntf,
  9.                                FSQLParams.MetaData,
  10.                                FSQLParams.MessageBuffer,
  11.                                FSQLRecord.MetaData,
  12.                                FSQLRecord.MessageBuffer);
  13.         Check4DataBaseError;
  14.  
  15.         Result := TResults.Create(FSQLRecord);
  16.         FSingleResults := true;
  17.       end;
  18.  
  19.       SQLSavePoint:
  20.       begin
  21.         FStatementIntf.execute(StatusIntf,
  22.                                (aTransaction as TFB30Transaction).TransactionIntf,
  23.                                nil,
  24.                                nil,
  25.                                nil,
  26.                                nil);
  27.         Check4DataBaseError;
  28.       end
  29.       else
  30.         FStatementIntf.execute(StatusIntf,
  31.                                (aTransaction as TFB30Transaction).TransactionIntf,
  32.                                FSQLParams.MetaData,
  33.                                FSQLParams.MessageBuffer,
  34.                                nil,
  35.                                nil);
  36.         Check4DataBaseError;
  37.       end;

And then it seems to work...

Honestly, I do not understand this code much. But I hope this is helpful to you, take a look.

 

TinyPortal © 2005-2018