Zeos 8 fieldtype issues

Zeos driver older versions than 8.0 treated numericoid postgresql type as stDouble sql type (ZDbcPostgreSqlUtils.PostgreSQLToSQLType). In Zeos 8.0 is treated as stBigDecimal, resulting ftFMTBCD field type (result dataset field type), instead of ftDouble.

This issue causes wrong data conversion, for example, if on the server machine the decimal separator is “,” and on client machine is set to “.”.

Using an IDADataset resulted variant value type called with VarType results 258 (System.varUString - zeos 8) and 5 (System.varDouble - older than zeos 8).

Please check if you can adapt DA components or mark as a zeos issue.

Hi,

Can you create a DDL script that creates a table that reproduces this issue, pls?
I’ll review Zeos driver..

On client side we running SELECT CAST(3.7001 as decimal(15,4))
On server side in ZDatasetUtils.pas, ConvertDatasetToDbcType function, changing result to ftBCD or ftFloat for stBigDecimal is our workaround (it was ftFmtBCD)

If you need something else, please tell me

Hi,

in case of manual sql, as in your case, we detect datatypes according to Direct Access Component (= Zeos) information.

Note: you can change detected datatype to your own one in Schema Modeler (Windows).

in case of AutoSQL, we detect datatypes with Postgres_DoGetTableFields method.


another workaround - you can create own driver based on Zeos driver and override intVCLTypeToDAType method in TDAEZeosQuery class.

see example of it in TDAEUniDACQuery.intVCLTypeToDAType.

if you like this way, I can give more information how to create own driver based on existing Zeos driver.

We are running sql statements, so the schema modeler is not a solution.
intVCLTypeToDAType could be a solution.
I think that’s important to know about this, because others may struggle with the same problem.

Best regards

Hi,

simple driver can be like

unit uMyZeosDriver;
...
type
  TMyDAEZeosDriver = class (TDAEZeosDriver)
  protected
    function GetConnectionClass: TDAEConnectionClass; override;
  end;

  TMyDAEZeosConnection = class (TDAEZeosConnection)
  protected
    function GetDatasetClass: TDAEDatasetClass; override;
  end;

  TMyDAEZeosQuery = class(TDAEZeosQuery)
  protected
    function intVCLTypeToDAType(aFieldType: TFieldType; ASize: Integer = 0; ADecimalPrecision: Integer = 0; aDecimalScale: Integer = 0): TDADataType; override;
  end;

function GetDriverObject: IDADriver; stdcall;

implementation

function TMyDAEZeosDriver.GetConnectionClass: TDAEConnectionClass;
begin
  Result := TMyDAEZeosConnection;
end;

function TMyDAEZeosConnection.GetDatasetClass: TDAEDatasetClass;
begin
  Result := TMyDAEZeosQuery;
end;

function TMyDAEZeosQuery.intVCLTypeToDAType(aFieldType: TFieldType; ASize,
  ADecimalPrecision, aDecimalScale: Integer): TDADataType;
begin
  case aFieldType of
    ....
  else
    Result := inherited intVCLTypeToDAType(aFieldType, ASize, ADecimalPrecision, aDecimalScale);
  end;
end;

function GetDriverObject: IDADriver;
begin
  if (_driver = nil) then _driver := TMyDAEZeosDriver.Create(nil);
  result := _driver;
end;

initialization
  _driver := nil;
  UnregisterDriverProc(uDAZeosDriver.GetDriverObject);
  RegisterDriverProc(GetDriverObject);
finalization
  UnregisterDriverProc(GetDriverObject);
  FreeAndNIL(_driver);
end.

Note: if you need custom similar support in Stored procedures, you should create descendant of TDAEZeosStoredProcedure, override intVCLTypeToDAType in it and register that descendant with GetStoredProcedureClass similar to query.


usage: you should include uMyZeosDriver to your server data module instead of uZeosDriver.