Skip to content

Commit

Permalink
TSQLDBOracleStatement.ExecutePrepared refactoring
Browse files Browse the repository at this point in the history
(VData header patch is not needed for Delphi Win64)
  • Loading branch information
Arnaud Bouchez committed Nov 6, 2019
1 parent 55efb8e commit a95a9c7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 21 deletions.
3 changes: 1 addition & 2 deletions SynCommons.pas
Expand Up @@ -17090,7 +17090,6 @@ procedure VarClear(var v: variant); // defined here for proper inlining
PPtrInt(p)^ := 0 else
VarClearProc(PVarData(p)^);
end;

{$endif FPC}

procedure MoveSmall(Source, Dest: Pointer; Count: PtrUInt);
Expand Down Expand Up @@ -20634,7 +20633,7 @@ TStrRec = record // see TAnsiRec/TUnicodeRec in astrings/ustrings.inc
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
Expand Down
34 changes: 16 additions & 18 deletions SynDBOracle.pas
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion SynopseCommit.inc
@@ -1 +1 @@
'1.18.5444'
'1.18.5445'

0 comments on commit a95a9c7

Please sign in to comment.