ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/branches/journaling/fbintf/client/2.5/FB25Statement.pas
(Generate patch)

Comparing:
ibx/trunk/fbintf/client/2.5/FB25Statement.pas (file contents), Revision 68 by tony, Tue Oct 17 10:07:58 2017 UTC vs.
ibx/branches/journaling/fbintf/client/2.5/FB25Statement.pas (file contents), Revision 363 by tony, Tue Dec 7 13:30:05 2021 UTC

# Line 121 | Line 121 | type
121    TIBXSQLVAR = class(TSQLVarData)
122    private
123      FStatement: TFB25Statement;
124 +    FFirebird25ClientAPI: TFB25ClientAPI;
125      FBlob: IBlob;             {Cache references}
125    FArray: IArray;
126      FNullIndicator: short;
127      FOwnsSQLData: boolean;
128      FBlobMetaData: IBlobMetaData;
129      FArrayMetaData: IArrayMetaData;
130 +    FMetadataSize: short; {size of field from metadata}
131      FXSQLVAR: PXSQLVAR;       { Points to the PXSQLVAR in the owner object }
132    protected
133      function GetSQLType: cardinal; override;
# Line 138 | Line 139 | type
139      function GetScale: integer; override;
140      function GetCharSetID: cardinal; override;
141      function GetCodePage: TSystemCodePage; override;
142 +    function GetCharSetWidth: integer; override;
143      function GetIsNull: Boolean;   override;
144      function GetIsNullable: boolean; override;
145      function GetSQLData: PByte;  override;
146      function GetDataLength: cardinal; override;
147 +    function GetSize: cardinal; override;
148 +    function GetAttachment: IAttachment; override;
149 +    function GetDefaultTextSQLType: cardinal; override;
150      procedure SetIsNull(Value: Boolean); override;
151      procedure SetIsNullable(Value: Boolean);  override;
152      procedure SetSQLData(AValue: PByte; len: cardinal); override;
# Line 153 | Line 158 | type
158      constructor Create(aParent: TIBXSQLDA; aIndex: integer);
159      procedure FreeSQLData;
160      procedure RowChange; override;
161 <    function GetAsArray(Array_ID: TISC_QUAD): IArray; override;
161 >    function GetAsArray: IArray; override;
162      function GetAsBlob(Blob_ID: TISC_QUAD; BPB: IBPB): IBlob; override;
163      function GetArrayMetaData: IArrayMetaData; override;
164      function GetBlobMetaData: IBlobMetaData; override;
# Line 161 | Line 166 | type
166      procedure Initialize; override;
167  
168      property Statement: TFB25Statement read FStatement;
169 +    property SQLType: cardinal read GetSQLType write SetSQLType;
170    end;
171  
172    TIBXINPUTSQLDA = class;
# Line 177 | Line 183 | type
183      function GetXSQLDA: PXSQLDA;
184    protected
185      FStatement: TFB25Statement;
186 +    FFirebird25ClientAPI: TFB25ClientAPI;
187      function GetTransactionSeqNo: integer; override;
188      procedure FreeXSQLDA;
189      function GetStatement: IStatement; override;
# Line 185 | Line 192 | type
192    public
193      constructor Create(aStatement: TFB25Statement);
194      destructor Destroy; override;
195 +    function CanChangeMetaData: boolean; override;
196      function CheckStatementStatus(Request: TStatementStatus): boolean; override;
197      function ColumnsInUseCount: integer; override;
198      function GetTransaction: TFB25Transaction; virtual;
# Line 228 | Line 236 | type
236      constructor Create(aResults: TIBXOUTPUTSQLDA);
237      destructor Destroy; override;
238      {IResultSet}
239 <    function FetchNext: boolean;
239 >    function FetchNext: boolean; {fetch next record}
240 >    function FetchPrior: boolean; {fetch previous record}
241 >    function FetchFirst:boolean; {fetch first record}
242 >    function FetchLast: boolean; {fetch last record}
243 >    function FetchAbsolute(position: Integer): boolean; {fetch record by its absolute position in result set}
244 >    function FetchRelative(offset: Integer): boolean; {fetch record by position relative to current}
245      function GetCursorName: AnsiString;
246      function GetTransaction: ITransaction; override;
247      function IsEof: boolean;
248 +    function IsBof: boolean;
249      procedure Close;
250    end;
251  
# Line 241 | Line 255 | type
255    private
256      FDBHandle: TISC_DB_HANDLE;
257      FHandle: TISC_STMT_HANDLE;
258 +    FFirebird25ClientAPI: TFB25ClientAPI;
259      FSQLParams: TIBXINPUTSQLDA;
260      FSQLRecord: TIBXOUTPUTSQLDA;
261      FCursor: AnsiString;               { Cursor name...}
# Line 249 | Line 264 | type
264    protected
265      procedure CheckHandle; override;
266      procedure GetDsqlInfo(info_request: byte; buffer: ISQLInfoResults); override;
267 <    procedure InternalPrepare; override;
267 >    function GetStatementIntf: IStatement; override;
268 >    procedure InternalPrepare(CursorName: AnsiString=''); override;
269      function InternalExecute(aTransaction: ITransaction): IResults; override;
270 <    function InternalOpenCursor(aTransaction: ITransaction): IResultSet; override;
270 >    function InternalOpenCursor(aTransaction: ITransaction; Scrollable: boolean): IResultSet; override;
271 >    procedure ProcessSQL(sql: AnsiString; GenerateParamNames: boolean; var processedSQL: AnsiString); override;
272      procedure FreeHandle; override;
273      procedure InternalClose(Force: boolean); override;
274    public
275      constructor Create(Attachment: TFB25Attachment; Transaction: ITransaction;
276 <      sql: AnsiString; aSQLDialect: integer);
276 >      sql: AnsiString; aSQLDialect: integer; CursorName: AnsiString='');
277      constructor CreateWithParameterNames(Attachment: TFB25Attachment;
278 <      Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; GenerateParamNames: boolean);
278 >      Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; GenerateParamNames: boolean;
279 >      CaseSensitiveParams: boolean=false; CursorName: AnsiString='');
280      destructor Destroy; override;
281      function FetchNext: boolean;
282  
# Line 350 | Line 368 | begin
368       CharSetID2CodePage(GetCharSetID,result);
369   end;
370  
371 + function TIBXSQLVAR.GetCharSetWidth: integer;
372 + begin
373 +  result := 1;
374 +  with Statement.GetAttachment DO
375 +    CharSetWidth(GetCharSetID,result);
376 + end;
377 +
378   function TIBXSQLVAR.GetIsNull: Boolean;
379   begin
380    result := IsNullable and (FNullIndicator = -1);
# Line 370 | Line 395 | begin
395    Result := FXSQLVAR^.sqllen;
396   end;
397  
398 + function TIBXSQLVAR.GetSize: cardinal;
399 + begin
400 +  Result := FMetadataSize;
401 + end;
402 +
403 + function TIBXSQLVAR.GetAttachment: IAttachment;
404 + begin
405 +  Result := FStatement.GetAttachment;
406 + end;
407 +
408   function TIBXSQLVAR.GetArrayMetaData: IArrayMetaData;
409   begin
410    if GetSQLType <> SQL_ARRAY then
# Line 395 | Line 430 | begin
430    Result := FBlobMetaData;
431   end;
432  
433 < function TIBXSQLVAR.GetAsArray(Array_ID: TISC_QUAD): IArray;
433 > function TIBXSQLVAR.GetAsArray: IArray;
434   begin
435    if SQLType <> SQL_ARRAY then
436      IBError(ibxeInvalidDataConversion,[nil]);
# Line 404 | Line 439 | begin
439      Result := nil
440    else
441    begin
442 <    if FArray = nil then
443 <      FArray := TFB25Array.Create(FStatement.GetAttachment as TFB25Attachment,
442 >    if FArrayIntf = nil then
443 >      FArrayIntf := TFB25Array.Create(FStatement.GetAttachment as TFB25Attachment,
444                                    TIBXSQLDA(Parent).GetTransaction,
445 <                                  GetArrayMetaData,Array_ID);
446 <    Result := FArray;
445 >                                  GetArrayMetaData,PISC_QUAD(SQLData)^);
446 >    Result := FArrayIntf;
447    end;
448   end;
449  
# Line 441 | Line 476 | procedure TIBXSQLVAR.Initialize;
476   begin
477    inherited Initialize;
478    FOwnsSQLData := true;
479 <  with FirebirdClientAPI, FXSQLVar^ do
479 >  with FFirebird25ClientAPI, FXSQLVar^ do
480    begin
481 +    FMetadataSize := sqllen;
482      case sqltype and (not 1) of
483        SQL_TEXT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TIMESTAMP,
484        SQL_BLOB, SQL_ARRAY, SQL_QUAD, SQL_SHORT, SQL_BOOLEAN,
# Line 468 | Line 504 | begin
504      else
505        sqlInd :=  nil;
506    end;
507 +  SaveMetaData;
508   end;
509  
510   procedure TIBXSQLVAR.SetIsNull(Value: Boolean);
# Line 526 | Line 563 | begin
563    if not FOwnsSQLData then
564      FXSQLVAR^.sqldata := nil;
565    FXSQLVAR^.sqllen := len;
566 <  with FirebirdClientAPI do
566 >  with FFirebird25ClientAPI do
567      IBAlloc(FXSQLVAR^.sqldata, 0, FXSQLVAR^.sqllen);
568    FOwnsSQLData := true;
569    Changed;
# Line 554 | Line 591 | begin
591    end;
592   end;
593  
594 + function TIBXSQLVAR.GetDefaultTextSQLType: cardinal;
595 + begin
596 +  Result := SQL_TEXT;
597 + end;
598 +
599   constructor TIBXSQLVAR.Create(aParent: TIBXSQLDA; aIndex: integer);
600   begin
601    inherited Create(aParent,aIndex);
602    FStatement := aParent.Statement;
603 +  FFirebird25ClientAPI := aParent.FFirebird25ClientAPI;
604   end;
605  
606   procedure TIBXSQLVAR.FreeSQLData;
# Line 572 | Line 615 | procedure TIBXSQLVAR.RowChange;
615   begin
616    inherited RowChange;
617    FBlob := nil;
575  FArray := nil;
618   end;
619  
620  
# Line 601 | Line 643 | begin
643        FResults.Column[i].RowChange;
644   end;
645  
646 + function TResultSet.FetchPrior: boolean;
647 + begin
648 +  IBError(ibxeNoScrollableCursors,[]);
649 + end;
650 +
651 + function TResultSet.FetchFirst: boolean;
652 + begin
653 +  IBError(ibxeNoScrollableCursors,[]);
654 + end;
655 +
656 + function TResultSet.FetchLast: boolean;
657 + begin
658 +  IBError(ibxeNoScrollableCursors,[]);
659 + end;
660 +
661 + function TResultSet.FetchAbsolute(position: Integer): boolean;
662 + begin
663 +  IBError(ibxeNoScrollableCursors,[]);
664 + end;
665 +
666 + function TResultSet.FetchRelative(offset: Integer): boolean;
667 + begin
668 +  IBError(ibxeNoScrollableCursors,[]);
669 + end;
670 +
671   function TResultSet.GetCursorName: AnsiString;
672   begin
673    Result := FResults.FStatement.FCursor;
# Line 616 | Line 683 | begin
683    Result := FResults.FStatement.FEof;
684   end;
685  
686 + function TResultSet.IsBof: boolean;
687 + begin
688 +  Result := FResults.FStatement.FBof;
689 + end;
690 +
691   procedure TResultSet.Close;
692   begin
693    if FCursorSeqNo = FResults.FStatement.FCursorSeqNo then
# Line 628 | Line 700 | procedure TIBXINPUTSQLDA.Bind;
700   begin
701    if Count = 0 then
702      Count := 1;
703 <  with Firebird25ClientAPI do
703 >  with FFirebird25ClientAPI do
704    begin
705      if (FXSQLDA <> nil) then
706         if isc_dsql_describe_bind(StatusVector, @(FStatement.Handle), FStatement.SQLDialect,
# Line 660 | Line 732 | procedure TIBXOUTPUTSQLDA.Bind;
732   begin
733    { Allocate an initial output descriptor (with one column) }
734    Count := 1;
735 <  with Firebird25ClientAPI do
735 >  with FFirebird25ClientAPI do
736    begin
737      { Using isc_dsql_describe, get the right size for the columns... }
738      if isc_dsql_describe(StatusVector, @(FStatement.Handle), FStatement.SQLDialect, FXSQLDA) > 0 then
# Line 695 | Line 767 | begin
767      len := sqllen;
768      if not IsNull and ((sqltype and (not 1)) = SQL_VARYING) then
769      begin
770 <      with FirebirdClientAPI do
770 >      with FFirebird25ClientAPI do
771          len := DecodeInteger(data,2);
772        Inc(data,2);
773      end;
# Line 712 | Line 784 | constructor TIBXSQLDA.Create(aStatement:
784   begin
785    inherited Create;
786    FStatement := aStatement;
787 +  FFirebird25ClientAPI := aStatement.FFirebird25ClientAPI;
788    FSize := 0;
789   //  writeln('Creating ',ClassName);
790   end;
# Line 723 | Line 796 | begin
796    inherited Destroy;
797   end;
798  
799 + function TIBXSQLDA.CanChangeMetaData: boolean;
800 + begin
801 +  Result := true;
802 + end;
803 +
804   function TIBXSQLDA.CheckStatementStatus(Request: TStatementStatus): boolean;
805   begin
806    Result := false;
# Line 798 | Line 876 | begin
876        OldSize := 0;
877      if Count > FSize then
878      begin
879 <      Firebird25ClientAPI.IBAlloc(FXSQLDA, OldSize, XSQLDA_LENGTH(Count));
879 >      FFirebird25ClientAPI.IBAlloc(FXSQLDA, OldSize, XSQLDA_LENGTH(Count));
880        SetLength(FColumnList, FCount);
881        FXSQLDA^.version := SQLDA_VERSION1;
882        p := @FXSQLDA^.sqlvar[0];
# Line 896 | Line 974 | end;
974   procedure TFB25Statement.GetDsqlInfo(info_request: byte; buffer: ISQLInfoResults
975    );
976   begin
977 <  with Firebird25ClientAPI, buffer as TSQLInfoResultsBuffer do
977 >  with FFirebird25ClientAPI, buffer as TSQLInfoResultsBuffer do
978    if isc_dsql_sql_info(StatusVector, @(FHandle), 1, @info_request,
979                       GetBufSize, Buffer) > 0 then
980      IBDatabaseError;
981   end;
982  
983 < procedure TFB25Statement.InternalPrepare;
983 > function TFB25Statement.GetStatementIntf: IStatement;
984 > begin
985 >  Result := self;
986 > end;
987 >
988 > procedure TFB25Statement.InternalPrepare(CursorName: AnsiString);
989   var
990 +  GUID: TGUID;
991    RB: ISQLInfoResults;
992    TRHandle: TISC_TR_HANDLE;
993   begin
994    if FPrepared then
995      Exit;
996 +
997    if (FSQL = '') then
998      IBError(ibxeEmptyQuery, [nil]);
999 +
1000 +  FCursor := CursorName;
1001 +  if FCursor = '' then
1002 +  begin
1003 +    CreateGuid(GUID);
1004 +    FCursor := GUIDToString(GUID);
1005 +  end;
1006 +
1007    try
1008      CheckTransaction(FTransactionIntf);
1009 <    with Firebird25ClientAPI do
1009 >    with FFirebird25ClientAPI do
1010      begin
1011        Call(isc_dsql_alloc_statement2(StatusVector, @(FDBHandle),
1012                                        @FHandle), True);
# Line 921 | Line 1014 | begin
1014        if FHasParamNames then
1015        begin
1016          if FProcessedSQL = '' then
1017 <          FSQLParams.PreprocessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
1017 >          ProcessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
1018          Call(isc_dsql_prepare(StatusVector, @(TRHandle), @FHandle, 0,
1019                   PAnsiChar(FProcessedSQL), FSQLDialect, nil), True);
1020        end
# Line 929 | Line 1022 | begin
1022          Call(isc_dsql_prepare(StatusVector, @(TRHandle), @FHandle, 0,
1023                   PAnsiChar(FSQL), FSQLDialect, nil), True);
1024      end;
1025 +
1026      { After preparing the statement, query the stmt type and possibly
1027        create a FSQLRecord "holder" }
1028      { Get the type of the statement }
# Line 938 | Line 1032 | begin
1032      else
1033        FSQLStatementType := SQLUnknown;
1034  
1035 +    if FSQLStatementType = SQLSelect then
1036 +    with FFirebird25ClientAPI do
1037 +      Call(
1038 +        isc_dsql_set_cursor_name(StatusVector, @FHandle, PAnsiChar(FCursor), 0),
1039 +        True);
1040 +
1041      case FSQLStatementType of
1042        SQLGetSegment,
1043        SQLPutSegment,
# Line 965 | Line 1065 | begin
1065        if (FHandle <> nil) then
1066          FreeHandle;
1067        if E is EIBInterBaseError then
1068 <        raise EIBInterBaseError.Create(EIBInterBaseError(E).SQLCode,
1069 <                                       EIBInterBaseError(E).IBErrorCode,
970 <                                       EIBInterBaseError(E).Message +
971 <                                       sSQLErrorSeparator + FSQL)
972 <      else
973 <        raise;
1068 >        E.Message := E.Message + sSQLErrorSeparator + FSQL;
1069 >      raise;
1070      end;
1071    end;
1072    FPrepared := true;
# Line 1002 | Line 1098 | begin
1098    CheckHandle;
1099    if aTransaction <> FTransactionIntf then
1100      AddMonitor(aTransaction as TFB25Transaction);
1101 <  if (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1101 >  if FStaleReferenceChecks and (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1102      IBError(ibxeInterfaceOutofDate,[nil]);
1103  
1104    try
1105      TRHandle := (aTransaction as TFB25Transaction).Handle;
1106 <    with Firebird25ClientAPI do
1106 >    with FFirebird25ClientAPI do
1107      begin
1108        if FCollectStatistics then
1109          GetPerfCounters(FBeforeStats);
# Line 1046 | Line 1142 | begin
1142         RemoveMonitor(aTransaction as TFB25Transaction);
1143    end;
1144    FExecTransactionIntf := aTransaction;
1145 +  FSQLRecord.FTransaction := aTransaction as TFB25Transaction;
1146 +  FSQLRecord.FTransactionSeqNo := FSQLRecord.FTransaction.TransactionSeqNo;
1147    Inc(FChangeSeqNo);
1148   end;
1149  
1150 < function TFB25Statement.InternalOpenCursor(aTransaction: ITransaction
1151 <  ): IResultSet;
1150 > function TFB25Statement.InternalOpenCursor(aTransaction: ITransaction;
1151 >  Scrollable: boolean): IResultSet;
1152   var TRHandle: TISC_TR_HANDLE;
1055    GUID : TGUID;
1153   begin
1154    if FSQLStatementType <> SQLSelect then
1155     IBError(ibxeIsASelectStatement,[]);
1156  
1157 +  if Scrollable then
1158 +    IBError(ibxeNoScrollableCursors,[]);
1159 +
1160   CheckTransaction(aTransaction);
1161    if not FPrepared then
1162      InternalPrepare;
1163    CheckHandle;
1164    if aTransaction <> FTransactionIntf then
1165      AddMonitor(aTransaction as TFB25Transaction);
1166 <  if (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1166 >  if FStaleReferenceChecks and (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1167      IBError(ibxeInterfaceOutofDate,[nil]);
1168  
1169 < with Firebird25ClientAPI do
1169 > with FFirebird25ClientAPI do
1170   begin
1171     if FCollectStatistics then
1172       GetPerfCounters(FBeforeStats);
# Line 1078 | Line 1178 | begin
1178                         SQLDialect,
1179                         FSQLParams.AsXSQLDA,
1180                         nil), True);
1081   if FCursor = '' then
1082   begin
1083     CreateGuid(GUID);
1084     FCursor := GUIDToString(GUID);
1085     Call(
1086       isc_dsql_set_cursor_name(StatusVector, @FHandle, PAnsiChar(FCursor), 0),
1087       True);
1088   end;
1181  
1182     if FCollectStatistics then
1183     begin
# Line 1105 | Line 1197 | begin
1197   Inc(FChangeSeqNo);
1198   end;
1199  
1200 + procedure TFB25Statement.ProcessSQL(sql: AnsiString; GenerateParamNames: boolean;
1201 +  var processedSQL: AnsiString);
1202 + begin
1203 +  FSQLParams.PreprocessSQL(sql,GenerateParamNames, processedSQL);
1204 + end;
1205 +
1206   procedure TFB25Statement.FreeHandle;
1207   var
1208    isc_res: ISC_STATUS;
# Line 1113 | Line 1211 | begin
1211    ReleaseInterfaces;
1212    try
1213      if FHandle <> nil then
1214 <    with Firebird25ClientAPI do
1214 >    with FFirebird25ClientAPI do
1215      begin
1216        isc_res :=
1217          Call(isc_dsql_free_statement(StatusVector, @FHandle, DSQL_drop), False);
# Line 1133 | Line 1231 | var
1231   begin
1232    if (FHandle <> nil) and (SQLStatementType = SQLSelect) and FOpen then
1233    try
1234 <    with Firebird25ClientAPI do
1234 >    with FFirebird25ClientAPI do
1235      begin
1236        isc_res := Call(
1237                     isc_dsql_free_statement(StatusVector, @FHandle, DSQL_close),
# Line 1154 | Line 1252 | begin
1252   end;
1253  
1254   constructor TFB25Statement.Create(Attachment: TFB25Attachment;
1255 <  Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer);
1255 >  Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer;
1256 >  CursorName: AnsiString);
1257   begin
1258    inherited Create(Attachment,Transaction,sql,aSQLDialect);
1259    FDBHandle := Attachment.Handle;
1260 +  FFirebird25ClientAPI := Attachment.Firebird25ClientAPI;
1261 +  OnDatabaseError := FFirebird25ClientAPI.IBDataBaseError;
1262    FSQLParams := TIBXINPUTSQLDA.Create(self);
1263    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1264 <  InternalPrepare;
1264 >  InternalPrepare(CursorName);
1265   end;
1266  
1267 < constructor TFB25Statement.CreateWithParameterNames(Attachment: TFB25Attachment;
1268 <  Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer;
1269 <  GenerateParamNames: boolean);
1267 > constructor TFB25Statement.CreateWithParameterNames(
1268 >  Attachment: TFB25Attachment; Transaction: ITransaction; sql: AnsiString;
1269 >  aSQLDialect: integer; GenerateParamNames: boolean;
1270 >  CaseSensitiveParams: boolean; CursorName: AnsiString);
1271   begin
1272    inherited CreateWithParameterNames(Attachment,Transaction,sql,aSQLDialect,GenerateParamNames);
1273    FDBHandle := Attachment.Handle;
1274 +  FFirebird25ClientAPI := Attachment.Firebird25ClientAPI;
1275 +  OnDatabaseError := FFirebird25ClientAPI.IBDataBaseError;
1276    FSQLParams := TIBXINPUTSQLDA.Create(self);
1277 +  FSQLParams.CaseSensitiveParams := CaseSensitiveParams;
1278    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1279 <  InternalPrepare;
1279 >  InternalPrepare(CursorName);
1280   end;
1281  
1282   destructor TFB25Statement.Destroy;
# Line 1191 | Line 1296 | begin
1296    if FEOF then
1297      IBError(ibxeEOF,[nil]);
1298  
1299 <  with Firebird25ClientAPI do
1299 >  with FFirebird25ClientAPI do
1300    begin
1301      { Go to the next record... }
1302      fetch_res :=
# Line 1217 | Line 1322 | begin
1322        FBOF := false;
1323        result := true;
1324      end;
1325 +    if FCollectStatistics then
1326 +    begin
1327 +      GetPerfCounters(FAfterStats);
1328 +      FStatisticsAvailable := true;
1329 +    end;
1330    end;
1331    FSQLRecord.RowChange;
1332    if FEOF then
# Line 1249 | Line 1359 | begin
1359      result := ''
1360    else
1361    begin
1362 <    RB := TSQLInfoResultsBuffer.Create(4*4096);
1362 >    RB := TSQLInfoResultsBuffer.Create(FFirebird25ClientAPI,4*4096);
1363      GetDsqlInfo(isc_info_sql_get_plan,RB);
1364       if RB.Count > 0 then
1365       Result := RB[0].GetAsString;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines