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 47 by tony, Mon Jan 9 15:31:51 2017 UTC vs.
Revision 315 by tony, Thu Feb 25 11:56:36 2021 UTC

# Line 60 | Line 60
60   {                                                                        }
61   {************************************************************************}
62   unit FB25Statement;
63 + {$IFDEF MSWINDOWS}
64 + {$DEFINE WINDOWS}
65 + {$ENDIF}
66  
67   {$IFDEF FPC}
68 < {$mode objfpc}{$H+}
68 > {$mode delphi}
69   {$codepage UTF8}
70   {$interfaces COM}
71   {$ENDIF}
# Line 118 | Line 121 | type
121    TIBXSQLVAR = class(TSQLVarData)
122    private
123      FStatement: TFB25Statement;
124 +    FFirebird25ClientAPI: TFB25ClientAPI;
125      FBlob: IBlob;             {Cache references}
126      FArray: IArray;
127      FNullIndicator: short;
128      FOwnsSQLData: boolean;
129      FBlobMetaData: IBlobMetaData;
130      FArrayMetaData: IArrayMetaData;
131 +    FMetadataSize: short; {size of field from metadata}
132      FXSQLVAR: PXSQLVAR;       { Points to the PXSQLVAR in the owner object }
133    protected
134      function GetSQLType: cardinal; override;
135      function GetSubtype: integer; override;
136 <    function GetAliasName: string;  override;
137 <    function GetFieldName: string; override;
138 <    function GetOwnerName: string;  override;
139 <    function GetRelationName: string;  override;
136 >    function GetAliasName: AnsiString;  override;
137 >    function GetFieldName: AnsiString; override;
138 >    function GetOwnerName: AnsiString;  override;
139 >    function GetRelationName: AnsiString;  override;
140      function GetScale: integer; override;
141      function GetCharSetID: cardinal; override;
142      function GetCodePage: TSystemCodePage; override;
143 +    function GetCharSetWidth: integer; override;
144      function GetIsNull: Boolean;   override;
145      function GetIsNullable: boolean; override;
146 <    function GetSQLData: PChar;  override;
146 >    function GetSQLData: PByte;  override;
147      function GetDataLength: cardinal; override;
148 +    function GetSize: cardinal; override;
149      procedure SetIsNull(Value: Boolean); override;
150      procedure SetIsNullable(Value: Boolean);  override;
151 <    procedure SetSQLData(AValue: PChar; len: cardinal); override;
151 >    procedure SetSQLData(AValue: PByte; len: cardinal); override;
152      procedure SetScale(aValue: integer); override;
153      procedure SetDataLength(len: cardinal); override;
154      procedure SetSQLType(aValue: cardinal); override;
# Line 174 | Line 181 | type
181      function GetXSQLDA: PXSQLDA;
182    protected
183      FStatement: TFB25Statement;
184 +    FFirebird25ClientAPI: TFB25ClientAPI;
185      function GetTransactionSeqNo: integer; override;
186      procedure FreeXSQLDA;
187      function GetStatement: IStatement; override;
# Line 211 | Line 219 | type
219      procedure Bind;
220      function GetTransaction: TFB25Transaction; override;
221      procedure GetData(index: integer; var aIsNull: boolean; var len: short;
222 <      var data: PChar); override;
222 >      var data: PByte); override;
223      function IsInputDataArea: boolean; override;
224    end;
225  
# Line 226 | Line 234 | type
234      destructor Destroy; override;
235      {IResultSet}
236      function FetchNext: boolean;
237 <    function GetCursorName: string;
237 >    function GetCursorName: AnsiString;
238      function GetTransaction: ITransaction; override;
239      function IsEof: boolean;
240      procedure Close;
# Line 238 | Line 246 | type
246    private
247      FDBHandle: TISC_DB_HANDLE;
248      FHandle: TISC_STMT_HANDLE;
249 +    FFirebird25ClientAPI: TFB25ClientAPI;
250      FSQLParams: TIBXINPUTSQLDA;
251      FSQLRecord: TIBXOUTPUTSQLDA;
252 <    FCursor: String;               { Cursor name...}
252 >    FCursor: AnsiString;               { Cursor name...}
253      FCursorSeqNo: integer;
254      procedure GetPerfCounters(var counters: TPerfStatistics);
255    protected
# Line 249 | Line 258 | type
258      procedure InternalPrepare; override;
259      function InternalExecute(aTransaction: ITransaction): IResults; override;
260      function InternalOpenCursor(aTransaction: ITransaction): IResultSet; override;
261 +    procedure ProcessSQL(sql: AnsiString; GenerateParamNames: boolean; var processedSQL: AnsiString); override;
262      procedure FreeHandle; override;
263      procedure InternalClose(Force: boolean); override;
264    public
265      constructor Create(Attachment: TFB25Attachment; Transaction: ITransaction;
266 <      sql: string; aSQLDialect: integer);
266 >      sql: AnsiString; aSQLDialect: integer);
267      constructor CreateWithParameterNames(Attachment: TFB25Attachment;
268 <      Transaction: ITransaction; sql: string; aSQLDialect: integer; GenerateParamNames: boolean);
268 >      Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; GenerateParamNames: boolean;
269 >      CaseSensitiveParams: boolean=false);
270      destructor Destroy; override;
271      function FetchNext: boolean;
272  
# Line 263 | Line 274 | type
274      {IStatement}
275      function GetSQLParams: ISQLParams; override;
276      function GetMetaData: IMetaData; override;
277 <    function GetPlan: String;
277 >    function GetPlan: AnsiString;
278      function IsPrepared: boolean;
279      function CreateBlob(column: TColumnMetaData): IBlob; override;
280      function CreateArray(column: TColumnMetaData): IArray; override;
# Line 293 | Line 304 | begin
304      result := 0;
305   end;
306  
307 < function TIBXSQLVAR.GetAliasName: string;
307 > function TIBXSQLVAR.GetAliasName: AnsiString;
308   begin
309    result := strpas(FXSQLVAR^.aliasname);
310   end;
311  
312 < function TIBXSQLVAR.GetFieldName: string;
312 > function TIBXSQLVAR.GetFieldName: AnsiString;
313   begin
314    result := strpas(FXSQLVAR^.sqlname);
315   end;
316  
317 < function TIBXSQLVAR.GetOwnerName: string;
317 > function TIBXSQLVAR.GetOwnerName: AnsiString;
318   begin
319    result := strpas(FXSQLVAR^.ownname);
320   end;
321  
322 < function TIBXSQLVAR.GetRelationName: string;
322 > function TIBXSQLVAR.GetRelationName: AnsiString;
323   begin
324    result := strpas(FXSQLVAR^.relname);
325   end;
# Line 332 | Line 343 | begin
343    SQL_BLOB:
344      if (SQLSubType = 1)  then
345        {see http://firebirdsql.org/rlsnotesh/rlsnotes210.html}
346 <      result := FXSQLVAR^.sqlscale;
346 >      result := FXSQLVAR^.sqlscale and $FF;
347  
348    SQL_ARRAY:
349      if (GetRelationName <> '') and (GetFieldName <> '') then
# Line 343 | Line 354 | end;
354   function TIBXSQLVAR.GetCodePage: TSystemCodePage;
355   begin
356    result := CP_NONE;
357 <  with FirebirdClientAPI do
357 >  with Statement.GetAttachment do
358       CharSetID2CodePage(GetCharSetID,result);
359   end;
360  
361 + function TIBXSQLVAR.GetCharSetWidth: integer;
362 + begin
363 +  result := 1;
364 +  with Statement.GetAttachment DO
365 +    CharSetWidth(GetCharSetID,result);
366 + end;
367 +
368   function TIBXSQLVAR.GetIsNull: Boolean;
369   begin
370    result := IsNullable and (FNullIndicator = -1);
# Line 357 | Line 375 | begin
375    result := (FXSQLVAR^.sqltype and 1 = 1);
376   end;
377  
378 < function TIBXSQLVAR.GetSQLData: PChar;
378 > function TIBXSQLVAR.GetSQLData: PByte;
379   begin
380    Result := FXSQLVAR^.sqldata;
381   end;
# Line 367 | Line 385 | begin
385    Result := FXSQLVAR^.sqllen;
386   end;
387  
388 + function TIBXSQLVAR.GetSize: cardinal;
389 + begin
390 +  Result := FMetadataSize;
391 + end;
392 +
393   function TIBXSQLVAR.GetArrayMetaData: IArrayMetaData;
394   begin
395    if GetSQLType <> SQL_ARRAY then
# Line 438 | Line 461 | procedure TIBXSQLVAR.Initialize;
461   begin
462    inherited Initialize;
463    FOwnsSQLData := true;
464 <  with FirebirdClientAPI, FXSQLVar^ do
464 >  with FFirebird25ClientAPI, FXSQLVar^ do
465    begin
466 +    FMetadataSize := sqllen;
467      case sqltype and (not 1) of
468        SQL_TEXT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TIMESTAMP,
469        SQL_BLOB, SQL_ARRAY, SQL_QUAD, SQL_SHORT, SQL_BOOLEAN,
# Line 499 | Line 523 | begin
523        FXSQLVAR^.sqlind := nil;
524      end;
525    end;
526 +  Changed;
527   end;
528  
529 < procedure TIBXSQLVAR.SetSQLData(AValue: PChar; len: cardinal);
529 > procedure TIBXSQLVAR.SetSQLData(AValue: PByte; len: cardinal);
530   begin
531    if FOwnsSQLData then
532      FreeMem(FXSQLVAR^.sqldata);
533    FXSQLVAR^.sqldata := AValue;
534    FXSQLVAR^.sqllen := len;
535    FOwnsSQLData := false;
536 +  Changed;
537   end;
538  
539   procedure TIBXSQLVAR.SetScale(aValue: integer);
540   begin
541    FXSQLVAR^.sqlscale := aValue;
542 +  Changed;
543   end;
544  
545   procedure TIBXSQLVAR.SetDataLength(len: cardinal);
# Line 520 | Line 547 | begin
547    if not FOwnsSQLData then
548      FXSQLVAR^.sqldata := nil;
549    FXSQLVAR^.sqllen := len;
550 <  with FirebirdClientAPI do
550 >  with FFirebird25ClientAPI do
551      IBAlloc(FXSQLVAR^.sqldata, 0, FXSQLVAR^.sqllen);
552    FOwnsSQLData := true;
553 +  Changed;
554   end;
555  
556   procedure TIBXSQLVAR.SetSQLType(aValue: cardinal);
557   begin
558    FXSQLVAR^.sqltype := aValue or (FXSQLVAR^.sqltype and 1);
559 +  Changed;
560   end;
561  
562   procedure TIBXSQLVAR.SetCharSetID(aValue: cardinal);
563   begin
564    if aValue <> GetCharSetID then
565 <  case SQLType of
566 <  SQL_VARYING, SQL_TEXT:
567 <      FXSQLVAR^.sqlsubtype := (aValue and $FF) or (FXSQLVAR^.sqlsubtype and not $FF);
568 <
569 <  SQL_BLOB,
570 <  SQL_ARRAY:
571 <    IBError(ibxeInvalidDataConversion,[nil]);
565 >  begin
566 >    case SQLType of
567 >    SQL_VARYING, SQL_TEXT:
568 >        FXSQLVAR^.sqlsubtype := (aValue and $FF) or (FXSQLVAR^.sqlsubtype and not $FF);
569 >
570 >    SQL_BLOB,
571 >    SQL_ARRAY:
572 >      IBError(ibxeInvalidDataConversion,[nil]);
573 >    end;
574 >  Changed;
575    end;
576   end;
577  
# Line 547 | Line 579 | constructor TIBXSQLVAR.Create(aParent: T
579   begin
580    inherited Create(aParent,aIndex);
581    FStatement := aParent.Statement;
582 +  FFirebird25ClientAPI := aParent.FFirebird25ClientAPI;
583   end;
584  
585   procedure TIBXSQLVAR.FreeSQLData;
# Line 590 | Line 623 | begin
623        FResults.Column[i].RowChange;
624   end;
625  
626 < function TResultSet.GetCursorName: string;
626 > function TResultSet.GetCursorName: AnsiString;
627   begin
628    Result := FResults.FStatement.FCursor;
629   end;
# Line 617 | Line 650 | procedure TIBXINPUTSQLDA.Bind;
650   begin
651    if Count = 0 then
652      Count := 1;
653 <  with Firebird25ClientAPI do
653 >  with FFirebird25ClientAPI do
654    begin
655      if (FXSQLDA <> nil) then
656         if isc_dsql_describe_bind(StatusVector, @(FStatement.Handle), FStatement.SQLDialect,
# Line 649 | Line 682 | procedure TIBXOUTPUTSQLDA.Bind;
682   begin
683    { Allocate an initial output descriptor (with one column) }
684    Count := 1;
685 <  with Firebird25ClientAPI do
685 >  with FFirebird25ClientAPI do
686    begin
687      { Using isc_dsql_describe, get the right size for the columns... }
688      if isc_dsql_describe(StatusVector, @(FStatement.Handle), FStatement.SQLDialect, FXSQLDA) > 0 then
# Line 675 | Line 708 | begin
708   end;
709  
710   procedure TIBXOUTPUTSQLDA.GetData(index: integer; var aIsNull:boolean; var len: short;
711 <  var data: PChar);
711 >  var data: PByte);
712   begin
713    with TIBXSQLVAR(Column[index]), FXSQLVAR^ do
714    begin
# Line 684 | Line 717 | begin
717      len := sqllen;
718      if not IsNull and ((sqltype and (not 1)) = SQL_VARYING) then
719      begin
720 <      with FirebirdClientAPI do
720 >      with FFirebird25ClientAPI do
721          len := DecodeInteger(data,2);
722        Inc(data,2);
723      end;
# Line 701 | Line 734 | constructor TIBXSQLDA.Create(aStatement:
734   begin
735    inherited Create;
736    FStatement := aStatement;
737 +  FFirebird25ClientAPI := aStatement.FFirebird25ClientAPI;
738    FSize := 0;
739   //  writeln('Creating ',ClassName);
740   end;
# Line 787 | Line 821 | begin
821        OldSize := 0;
822      if Count > FSize then
823      begin
824 <      Firebird25ClientAPI.IBAlloc(FXSQLDA, OldSize, XSQLDA_LENGTH(Count));
824 >      FFirebird25ClientAPI.IBAlloc(FXSQLDA, OldSize, XSQLDA_LENGTH(Count));
825        SetLength(FColumnList, FCount);
826        FXSQLDA^.version := SQLDA_VERSION1;
827        p := @FXSQLDA^.sqlvar[0];
# Line 796 | Line 830 | begin
830          if i >= FSize then
831            FColumnList[i] := TIBXSQLVAR.Create(self,i);
832          TIBXSQLVAR(Column[i]).FXSQLVAR := p;
833 <        p := Pointer(PChar(p) + sizeof(FXSQLDA^.sqlvar));
833 >        p := Pointer(PAnsiChar(p) + sizeof(FXSQLDA^.sqlvar));
834        end;
835        FSize := inherited Count;
836      end;
# Line 850 | Line 884 | begin
884    {$ELSE}
885    counters[psUserTime] := 0;
886    {$ENDIF}
887 <  counters[psRealTime] := Int64(TimeStampToMSecs(DateTimeToTimeStamp(Now)));
887 >  counters[psRealTime] := TimeStampToMSecs(DateTimeToTimeStamp(Now));
888  
889    DBInfo := GetAttachment.GetDBInformation([isc_info_reads,isc_info_writes,
890           isc_info_fetches, isc_info_num_buffers, isc_info_current_memory,
# Line 885 | Line 919 | end;
919   procedure TFB25Statement.GetDsqlInfo(info_request: byte; buffer: ISQLInfoResults
920    );
921   begin
922 <  with Firebird25ClientAPI, buffer as TSQLInfoResultsBuffer do
922 >  with FFirebird25ClientAPI, buffer as TSQLInfoResultsBuffer do
923    if isc_dsql_sql_info(StatusVector, @(FHandle), 1, @info_request,
924                       GetBufSize, Buffer) > 0 then
925      IBDatabaseError;
# Line 902 | Line 936 | begin
936      IBError(ibxeEmptyQuery, [nil]);
937    try
938      CheckTransaction(FTransactionIntf);
939 <    with Firebird25ClientAPI do
939 >    with FFirebird25ClientAPI do
940      begin
941        Call(isc_dsql_alloc_statement2(StatusVector, @(FDBHandle),
942                                        @FHandle), True);
# Line 910 | Line 944 | begin
944        if FHasParamNames then
945        begin
946          if FProcessedSQL = '' then
947 <          FSQLParams.PreprocessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
947 >          ProcessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
948          Call(isc_dsql_prepare(StatusVector, @(TRHandle), @FHandle, 0,
949 <                 PChar(FProcessedSQL), FSQLDialect, nil), True);
949 >                 PAnsiChar(FProcessedSQL), FSQLDialect, nil), True);
950        end
951        else
952          Call(isc_dsql_prepare(StatusVector, @(TRHandle), @FHandle, 0,
953 <                 PChar(FSQL), FSQLDialect, nil), True);
953 >                 PAnsiChar(FSQL), FSQLDialect, nil), True);
954      end;
955      { After preparing the statement, query the stmt type and possibly
956        create a FSQLRecord "holder" }
# Line 954 | Line 988 | begin
988        if (FHandle <> nil) then
989          FreeHandle;
990        if E is EIBInterBaseError then
991 <        raise EIBInterBaseError.Create(EIBInterBaseError(E).SQLCode,
992 <                                       EIBInterBaseError(E).IBErrorCode,
959 <                                       EIBInterBaseError(E).Message +
960 <                                       sSQLErrorSeparator + FSQL)
961 <      else
962 <        raise;
991 >        E.Message := E.Message + sSQLErrorSeparator + FSQL;
992 >      raise;
993      end;
994    end;
995    FPrepared := true;
# Line 996 | Line 1026 | begin
1026  
1027    try
1028      TRHandle := (aTransaction as TFB25Transaction).Handle;
1029 <    with Firebird25ClientAPI do
1029 >    with FFirebird25ClientAPI do
1030      begin
1031        if FCollectStatistics then
1032          GetPerfCounters(FBeforeStats);
# Line 1035 | Line 1065 | begin
1065         RemoveMonitor(aTransaction as TFB25Transaction);
1066    end;
1067    FExecTransactionIntf := aTransaction;
1068 +  FSQLRecord.FTransaction := aTransaction as TFB25Transaction;
1069 +  FSQLRecord.FTransactionSeqNo := FSQLRecord.FTransaction.TransactionSeqNo;
1070    Inc(FChangeSeqNo);
1071   end;
1072  
# Line 1055 | Line 1087 | begin
1087    if (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1088      IBError(ibxeInterfaceOutofDate,[nil]);
1089  
1090 < with Firebird25ClientAPI do
1090 > with FFirebird25ClientAPI do
1091   begin
1092     if FCollectStatistics then
1093       GetPerfCounters(FBeforeStats);
# Line 1072 | Line 1104 | begin
1104       CreateGuid(GUID);
1105       FCursor := GUIDToString(GUID);
1106       Call(
1107 <       isc_dsql_set_cursor_name(StatusVector, @FHandle, PChar(FCursor), 0),
1107 >       isc_dsql_set_cursor_name(StatusVector, @FHandle, PAnsiChar(FCursor), 0),
1108         True);
1109     end;
1110  
# Line 1094 | Line 1126 | begin
1126   Inc(FChangeSeqNo);
1127   end;
1128  
1129 + procedure TFB25Statement.ProcessSQL(sql: AnsiString; GenerateParamNames: boolean;
1130 +  var processedSQL: AnsiString);
1131 + begin
1132 +  FSQLParams.PreprocessSQL(sql,GenerateParamNames, processedSQL);
1133 + end;
1134 +
1135   procedure TFB25Statement.FreeHandle;
1136   var
1137    isc_res: ISC_STATUS;
# Line 1102 | Line 1140 | begin
1140    ReleaseInterfaces;
1141    try
1142      if FHandle <> nil then
1143 <    with Firebird25ClientAPI do
1143 >    with FFirebird25ClientAPI do
1144      begin
1145        isc_res :=
1146          Call(isc_dsql_free_statement(StatusVector, @FHandle, DSQL_drop), False);
# Line 1122 | Line 1160 | var
1160   begin
1161    if (FHandle <> nil) and (SQLStatementType = SQLSelect) and FOpen then
1162    try
1163 <    with Firebird25ClientAPI do
1163 >    with FFirebird25ClientAPI do
1164      begin
1165        isc_res := Call(
1166                     isc_dsql_free_statement(StatusVector, @FHandle, DSQL_close),
# Line 1133 | Line 1171 | begin
1171          IBDatabaseError;
1172      end;
1173    finally
1174 <    if (FSQLRecord.FTransaction <> nil) and (FSQLRecord.FTransaction <> FTransactionIntf) then
1174 >    if (FSQLRecord.FTransaction <> nil) and (FSQLRecord.FTransaction <> (FTransactionIntf as TFB25Transaction)) then
1175        RemoveMonitor(FSQLRecord.FTransaction);
1176      FOpen := False;
1177      FExecTransactionIntf := nil;
# Line 1143 | Line 1181 | begin
1181   end;
1182  
1183   constructor TFB25Statement.Create(Attachment: TFB25Attachment;
1184 <  Transaction: ITransaction; sql: string; aSQLDialect: integer);
1184 >  Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer);
1185   begin
1186    inherited Create(Attachment,Transaction,sql,aSQLDialect);
1187    FDBHandle := Attachment.Handle;
1188 +  FFirebird25ClientAPI := Attachment.Firebird25ClientAPI;
1189 +  OnDatabaseError := FFirebird25ClientAPI.IBDataBaseError;
1190    FSQLParams := TIBXINPUTSQLDA.Create(self);
1191    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1192    InternalPrepare;
1193   end;
1194  
1195 < constructor TFB25Statement.CreateWithParameterNames(Attachment: TFB25Attachment;
1196 <  Transaction: ITransaction; sql: string; aSQLDialect: integer;
1197 <  GenerateParamNames: boolean);
1195 > constructor TFB25Statement.CreateWithParameterNames(
1196 >  Attachment: TFB25Attachment; Transaction: ITransaction; sql: AnsiString;
1197 >  aSQLDialect: integer; GenerateParamNames: boolean;
1198 >  CaseSensitiveParams: boolean);
1199   begin
1200    inherited CreateWithParameterNames(Attachment,Transaction,sql,aSQLDialect,GenerateParamNames);
1201    FDBHandle := Attachment.Handle;
1202 +  FFirebird25ClientAPI := Attachment.Firebird25ClientAPI;
1203 +  OnDatabaseError := FFirebird25ClientAPI.IBDataBaseError;
1204    FSQLParams := TIBXINPUTSQLDA.Create(self);
1205 +  FSQLParams.CaseSensitiveParams := CaseSensitiveParams;
1206    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1207    InternalPrepare;
1208   end;
# Line 1180 | Line 1224 | begin
1224    if FEOF then
1225      IBError(ibxeEOF,[nil]);
1226  
1227 <  with Firebird25ClientAPI do
1227 >  with FFirebird25ClientAPI do
1228    begin
1229      { Go to the next record... }
1230      fetch_res :=
# Line 1206 | Line 1250 | begin
1250        FBOF := false;
1251        result := true;
1252      end;
1253 +    if FCollectStatistics then
1254 +    begin
1255 +      GetPerfCounters(FAfterStats);
1256 +      FStatisticsAvailable := true;
1257 +    end;
1258    end;
1259    FSQLRecord.RowChange;
1260    if FEOF then
# Line 1228 | Line 1277 | begin
1277    Result := TMetaData(GetInterface(1));
1278   end;
1279  
1280 < function TFB25Statement.GetPlan: String;
1280 > function TFB25Statement.GetPlan: AnsiString;
1281   var
1282      RB: ISQLInfoResults;
1283   begin
# Line 1238 | Line 1287 | begin
1287      result := ''
1288    else
1289    begin
1290 <    RB := TSQLInfoResultsBuffer.Create(4*4096);
1290 >    RB := TSQLInfoResultsBuffer.Create(FFirebird25ClientAPI,4*4096);
1291      GetDsqlInfo(isc_info_sql_get_plan,RB);
1292       if RB.Count > 0 then
1293       Result := RB[0].GetAsString;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines