Skip to content
Permalink
Browse files

TSQLDBOracleStatement.ExecutePrepared refactoring

(VData header patch is not needed for Delphi Win64)
  • Loading branch information...
Arnaud Bouchez
Arnaud Bouchez committed Nov 6, 2019
1 parent 55efb8e commit a95a9c7817cfc1f1dfafd9cf195fa74c4d2a4b69
Showing with 18 additions and 21 deletions.
  1. +1 −2 SynCommons.pas
  2. +16 −18 SynDBOracle.pas
  3. +1 −1 SynopseCommit.inc
PPtrInt(p)^ := 0 else
VarClearProc(PVarData(p)^);
end;

{$endif FPC}

procedure MoveSmall(Source, Dest: Pointer; Count: PtrUInt);
TStrRec = packed record
{$ifdef UNICODE}
{$ifdef CPU64}
/// padding bytes for 16 byte alignment of the header
/// padding bytes for 16 bytes alignment of the header
_Padding: LongInt;
{$endif}
/// the associated code page used for this string
@@ -2671,9 +2671,9 @@ procedure TSQLDBOracleStatement.ExecutePrepared;
num_val: OCINumber;
tmp: RawUTF8;
str_val: POCIString;
{$ifdef CPU64}
{$ifdef FPC_64}
wasStringHacked: TByteDynArray;
{$endif}
{$endif FPC_64}
label txt;
begin
if (fStatement=nil) then
@@ -2915,22 +2915,20 @@ procedure TSQLDBOracleStatement.ExecutePrepared;
VDBTYPE := SQLT_BIN;
oData := pointer(VData);
end else begin
VDBTYPE := SQLT_LVB;
{$ifdef CPU64}
if Length(VData)>MaxInt shr 2 then
raise ESQLDBOracle.CreateUTF8('%.ExecutePrepared: Maximum blob parameter ' +
'length exceeded for parameter #%: %',[self,i+1,KB(oLength)]);
// Oracle expect SQLT_LVB layout as raw data prepended by int32 data length
// in case of CPU64 TSQLDBParam.VData is a RawByteString and length
// is stored as SizeInt = Int64 (not int32) -> change header
{$ifdef FPC} // @VData[1] won't call UniqueString() under FPC :(
VDBTYPE := SQLT_LVB; // layout: raw data prepended by int32 len
{$ifdef FPC_64}
// in case of FPC+CPU64 TSQLDBParam.VData is a RawByteString and
// length is stored as SizeInt = Int64 (not int32) -> patch
// (no patch needed for Delphi, in which len is always longint)
if Length(VData)>MaxInt then
raise ESQLDBOracle.CreateUTF8('%.ExecutePrepared: % blob length ' +
'exceeds max size for parameter #%',[self,KB(oLength),i+1]);
UniqueString(VData); // for thread-safety
{$endif}
PInteger(PtrUInt(@VData[1])-sizeof(Integer))^ := oLength;
PInteger(PtrInt(VData)-sizeof(Integer))^ := oLength;
if wasStringHacked=nil then
SetLength(wasStringHacked,fParamCount shr 3+1);
SetBitPtr(pointer(wasStringHacked),i); // to restore the original header
{$endif CPU64}
SetBitPtr(pointer(wasStringHacked),i); // for unpatching below
{$endif FPC_64}
oData := Pointer(PtrInt(VData)-sizeof(Integer));
Inc(oLength,sizeof(Integer));
end;
@@ -2956,12 +2954,12 @@ procedure TSQLDBOracleStatement.ExecutePrepared;
FetchTest(Status); // error + set fRowCount+fCurrentRow+fRowFetchedCurrent
Status := OCI_SUCCESS; // mark OK for fBoundCursor[] below
finally
{$ifdef CPU64}
if wasStringHacked<>nil then // restore hacked strings length ASAP
{$ifdef FPC_64}
if wasStringHacked<>nil then // restore patched strings length ASAP
for i := 0 to fParamCount-1 do
if GetBitPtr(pointer(wasStringHacked),i) then
PInteger(PtrInt(fParams[i].VData)-sizeof(Integer))^ := 0;
{$endif}
{$endif FPC_64}
for i := 0 to ociArraysCount-1 do
OCI.Check(nil,self,OCI.ObjectFree(Env, fError, ociArrays[i], OCI_OBJECTFREE_FORCE), fError, false, sllError);
// 3. release and/or retrieve OUT bound parameters
@@ -1 +1 @@
'1.18.5444'
'1.18.5445'

0 comments on commit a95a9c7

Please sign in to comment.
You can’t perform that action at this time.