|
@@ -24,10 +24,10 @@ type
|
|
TPQCursor = Class(TSQLCursor)
|
|
TPQCursor = Class(TSQLCursor)
|
|
protected
|
|
protected
|
|
Statement : string;
|
|
Statement : string;
|
|
|
|
+ StmtName : string;
|
|
tr : TPQTrans;
|
|
tr : TPQTrans;
|
|
res : PPGresult;
|
|
res : PPGresult;
|
|
CurTuple : integer;
|
|
CurTuple : integer;
|
|
- Nr : string;
|
|
|
|
FieldBinding : array of integer;
|
|
FieldBinding : array of integer;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -117,9 +117,11 @@ const Oid_Bool = 16;
|
|
Oid_Unknown = 705;
|
|
Oid_Unknown = 705;
|
|
Oid_bpchar = 1042;
|
|
Oid_bpchar = 1042;
|
|
Oid_varchar = 1043;
|
|
Oid_varchar = 1043;
|
|
- Oid_timestamp = 1114;
|
|
|
|
oid_date = 1082;
|
|
oid_date = 1082;
|
|
oid_time = 1083;
|
|
oid_time = 1083;
|
|
|
|
+ Oid_timeTZ = 1266;
|
|
|
|
+ Oid_timestamp = 1114;
|
|
|
|
+ Oid_timestampTZ = 1184;
|
|
oid_numeric = 1700;
|
|
oid_numeric = 1700;
|
|
Oid_uuid = 2950;
|
|
Oid_uuid = 2950;
|
|
|
|
|
|
@@ -411,9 +413,11 @@ begin
|
|
Oid_int2 : Result := ftSmallInt;
|
|
Oid_int2 : Result := ftSmallInt;
|
|
Oid_Float4 : Result := ftFloat;
|
|
Oid_Float4 : Result := ftFloat;
|
|
Oid_Float8 : Result := ftFloat;
|
|
Oid_Float8 : Result := ftFloat;
|
|
- Oid_TimeStamp : Result := ftDateTime;
|
|
|
|
|
|
+ Oid_TimeStamp,
|
|
|
|
+ Oid_TimeStampTZ : Result := ftDateTime;
|
|
Oid_Date : Result := ftDate;
|
|
Oid_Date : Result := ftDate;
|
|
- Oid_Time : Result := ftTime;
|
|
|
|
|
|
+ Oid_Time,
|
|
|
|
+ Oid_TimeTZ : Result := ftTime;
|
|
Oid_Bool : Result := ftBoolean;
|
|
Oid_Bool : Result := ftBoolean;
|
|
Oid_Numeric : begin
|
|
Oid_Numeric : begin
|
|
Result := ftBCD;
|
|
Result := ftBCD;
|
|
@@ -516,16 +520,16 @@ begin
|
|
with (cursor as TPQCursor) do
|
|
with (cursor as TPQCursor) do
|
|
begin
|
|
begin
|
|
FPrepared := False;
|
|
FPrepared := False;
|
|
- nr := inttostr(FCursorcount);
|
|
|
|
- inc(FCursorCount);
|
|
|
|
// Prior to v8 there is no support for cursors and parameters.
|
|
// Prior to v8 there is no support for cursors and parameters.
|
|
// So that's not supported.
|
|
// So that's not supported.
|
|
if FStatementType in [stInsert,stUpdate,stDelete, stSelect] then
|
|
if FStatementType in [stInsert,stUpdate,stDelete, stSelect] then
|
|
begin
|
|
begin
|
|
|
|
+ StmtName := 'prepst'+inttostr(FCursorCount);
|
|
|
|
+ inc(FCursorCount);
|
|
tr := TPQTrans(aTransaction.Handle);
|
|
tr := TPQTrans(aTransaction.Handle);
|
|
// Only available for pq 8.0, so don't use it...
|
|
// Only available for pq 8.0, so don't use it...
|
|
// Res := pqprepare(tr,'prepst'+name+nr,pchar(buf),params.Count,pchar(''));
|
|
// Res := pqprepare(tr,'prepst'+name+nr,pchar(buf),params.Count,pchar(''));
|
|
- s := 'prepare prepst'+nr+' ';
|
|
|
|
|
|
+ s := 'prepare '+StmtName+' ';
|
|
if Assigned(AParams) and (AParams.count > 0) then
|
|
if Assigned(AParams) and (AParams.count > 0) then
|
|
begin
|
|
begin
|
|
s := s + '(';
|
|
s := s + '(';
|
|
@@ -548,6 +552,15 @@ begin
|
|
pqclear(res);
|
|
pqclear(res);
|
|
DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self)
|
|
DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self)
|
|
end;
|
|
end;
|
|
|
|
+ // if statement is INSERT, UPDATE, DELETE with RETURNING clause, then
|
|
|
|
+ // override the statement type derrived by parsing the query.
|
|
|
|
+ if (FStatementType in [stInsert,stUpdate,stDelete]) and (pos('RETURNING', upcase(s)) > 0) then
|
|
|
|
+ begin
|
|
|
|
+ PQclear(res);
|
|
|
|
+ res := PQdescribePrepared(tr.PGConn,pchar(StmtName));
|
|
|
|
+ if (PQresultStatus(res) = PGRES_COMMAND_OK) and (PQnfields(res) > 0) then
|
|
|
|
+ FStatementType := stSelect;
|
|
|
|
+ end;
|
|
FPrepared := True;
|
|
FPrepared := True;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
@@ -563,7 +576,7 @@ begin
|
|
if not tr.ErrorOccured then
|
|
if not tr.ErrorOccured then
|
|
begin
|
|
begin
|
|
PQclear(res);
|
|
PQclear(res);
|
|
- res := pqexec(tr.PGConn,pchar('deallocate prepst'+nr));
|
|
|
|
|
|
+ res := pqexec(tr.PGConn,pchar('deallocate '+StmtName));
|
|
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
|
|
if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
|
|
begin
|
|
begin
|
|
pqclear(res);
|
|
pqclear(res);
|
|
@@ -630,12 +643,12 @@ begin
|
|
end
|
|
end
|
|
else
|
|
else
|
|
FreeAndNil(ar[i]);
|
|
FreeAndNil(ar[i]);
|
|
- res := PQexecPrepared(tr.PGConn,pchar('prepst'+nr),Aparams.count,@Ar[0],@Lengths[0],@Formats[0],1);
|
|
|
|
|
|
+ res := PQexecPrepared(tr.PGConn,pchar(StmtName),Aparams.count,@Ar[0],@Lengths[0],@Formats[0],1);
|
|
for i := 0 to AParams.count -1 do
|
|
for i := 0 to AParams.count -1 do
|
|
FreeMem(ar[i]);
|
|
FreeMem(ar[i]);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- res := PQexecPrepared(tr.PGConn,pchar('prepst'+nr),0,nil,nil,nil,1);
|
|
|
|
|
|
+ res := PQexecPrepared(tr.PGConn,pchar(StmtName),0,nil,nil,nil,1);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|