Browse Source

* 32/64 bit, handle ExecPrepared result correctly

Michaël Van Canneyt 2 years ago
parent
commit
9c0a59b069
1 changed files with 43 additions and 7 deletions
  1. 43 7
      packages/fcl-db/src/sqldb/postgres/pqconnection.pp

+ 43 - 7
packages/fcl-db/src/sqldb/postgres/pqconnection.pp

@@ -18,6 +18,7 @@ unit PQConnection;
 {$mode objfpc}{$H+}
 
 {$Define LinkDynamically}
+{$define PQDEBUG}
 
 interface
 
@@ -39,9 +40,10 @@ type
 
   TPGHandle = Class(TSQLHandle)
   strict private
-    class var _HID : Integer;
+
+    class var _HID : {$IFDEF CPU64} Int64 {$ELSE} Integer {$ENDIF};
   private
-    FHandleID : Integer;
+    FHandleID : {$IFDEF CPU64} Int64 {$ELSE} Integer {$ENDIF};
     FConnected: Boolean;
     FCOnnection: TPQConnection;
     FDBName : String;
@@ -63,7 +65,7 @@ type
     Function CheckConnectionStatus(doRaise : Boolean = True) : Boolean;
     Function DescribePrepared(StmtName : String): PPGresult;
     Function Exec(aSQL : String; aClearResult : Boolean; aError : String = '') : PPGresult;
-  Public
+    function ExecPrepared(stmtName: AnsiString; nParams:longint; paramValues:PPchar; paramLengths:Plongint;paramFormats:Plongint; aClearResult : Boolean) : PPGresult;
     Constructor Create(aConnection : TPQConnection;aDBName :string);
     Destructor Destroy; override;
     procedure CheckResultError(var res: PPGresult; Actions : TCheckResultActions; const ErrMsg: string);
@@ -267,7 +269,11 @@ begin
   FConnection:=aConnection;
   FCursorList:=TThreadList.Create;
   FCursorList.Duplicates:=dupIgnore;
+  {$IFDEF CPU64}
+  FHandleID:=InterlockedIncrement64(_HID);
+  {$ElSE}
   FHandleID:=InterlockedIncrement(_HID);
+  {$ENDIF}
   {$IFDEF PQDEBUG}
   Writeln('>>> ',FHandleID,' [',TThread.CurrentThread.ThreadID, ']  allocating handle ');
   {$ENDIF}
@@ -833,6 +839,25 @@ begin
   CheckResultError(Result,acts,aError);
 end;
 
+function TPGHandle.ExecPrepared(stmtName: AnsiString; nParams: longint;
+  paramValues: PPchar; paramLengths: Plongint; paramFormats: Plongint;
+  aClearResult: Boolean): PPGresult;
+
+var
+  s : string;
+  acts : TCheckResultActions;
+
+begin
+  {$IFDEF PQDEBUG}
+  Writeln('>>> ',FHandleID,' [',TThread.CurrentThread.ThreadID, ']  executr prepared ',StmtName);
+  {$ENDIF}
+  Result:=PQexecPrepared(NativeConn,pansichar(StmtName),nParams,ParamValues,paramlengths,paramformats,1);
+  acts:=[];
+  if aClearResult then
+    include(acts,craClear);
+  CheckResultError(Result,acts,'Error executing prepared statement '+stmtName);
+end;
+
 procedure TPGHandle.CheckResultError(var res: PPGresult; Actions: TCheckResultActions; const ErrMsg: string);
 
   Procedure MaybeAdd(Var S : String; Prefix,Msg : String);
@@ -935,7 +960,13 @@ begin
     Writeln('>>> ',IntToStr(FHandleID)+' [',TThread.CurrentThread.ThreadID, ']  Error: ',lMessage,' - ',Serr);
     {$ENDIF}
     raise E;
-    end;
+    end
+  else
+    if craClear in Actions then
+      begin
+      PQClear(res);
+      res:=nil;
+      end;
 end;
 
 function TPQConnection.TranslateFldType(res: PPGresult; Tuple: integer; out
@@ -1155,6 +1186,7 @@ begin
     s := s + ' as ' + buf;
     if LogEvent(detActualSQL) then
       Log(detActualSQL,S);
+    PQCurs.Res:=Nil;
     PQCurs.Res:=PQCurs.Handle.Exec(S,False,SErrPrepareFailed);
     // if statement is INSERT, UPDATE, DELETE with RETURNING clause, then
     // override the statement type derived by parsing the query.
@@ -1218,6 +1250,7 @@ begin
   PQCurs:=cursor as TPQCursor;
   PQCurs.CurTuple:=-1;
   PQclear(PQCurs.res);
+  PQCurs.Res:=Nil;
   if PQCurs.FStatementType in [stInsert,stUpdate,stDelete,stSelect] then
     begin
     if LogEvent(detParamValue) then
@@ -1266,6 +1299,9 @@ begin
           else
             s := GetAsString(AParams[i]);
         end; {case}
+        {$IFDEF PQDEBUG}
+        WriteLn('Setting param ',aParams[i].Name,'(',aParams[i].DataType,') to ',S);
+        {$ENDIF}
         if not handled then
           begin
           l:=length(s);
@@ -1280,12 +1316,13 @@ begin
         end
       else
         FreeAndNil(ar[i]);
-      PQCurs.res := PQexecPrepared(PQCurs.Handle.NativeConn,pchar(PQCurs.StmtName),AParams.Count,@Ar[0],@Lengths[0],@Formats[0],1);
+      PQCurs.res := PQCurs.Handle.ExecPrepared(PQCurs.StmtName,AParams.Count,@Ar[0],@Lengths[0],@Formats[0],False);
+//      PQCurs.res := PQexecPrepared(PQCurs.Handle.NativeConn,pchar(PQCurs.StmtName),AParams.Count,@Ar[0],@Lengths[0],@Formats[0],1);
       for i := 0 to AParams.Count -1 do
         FreeMem(ar[i]);
       end
     else
-      PQCurs.res := PQexecPrepared(PQCurs.Handle.NativeConn,pchar(PQCurs.StmtName),0,nil,nil,nil,1);
+      PQCurs.res := PQCurs.Handle.ExecPrepared(PQCurs.StmtName,0,nil,nil,nil,False);
     end
   else
     begin
@@ -1304,7 +1341,6 @@ begin
       end
     else
       s := PQCurs.Statement;
-    PQCurs.Res:=Nil;
     PQCurs.Res:=PQCurs.Handle.Exec(S,False,SErrExecuteFailed);
     end;
   PQCurs.FSelectable := assigned(PQCurs.res) and (PQresultStatus(PQCurs.res)=PGRES_TUPLES_OK);