Page 1 of 1

[patch_done] empty varchar in mssql server return bad buffer

Posted: 21.02.2011, 17:31
by ChrisCross
i have a unit composed from
tZConnection connected to mssql using ntwdblib
tZQuery using tZConnection with following sql
SELECT top 1 name, convert(varchar(100), '') as name1, name as name2 from sysobjects

when open query return for name1 column the value of name column

i traced the problem into

ZDbcCachedResultSet.pas in fetch

Code: Select all

        //stString: RowAccessor.SetPChar(I, ResultSet.GetPChar(I));
        // gto: do we need PChar here? (Unicode problems)
        stString: RowAccessor.SetString(I, ResultSet.GetString(I));
the Resultset.GetString does not reset the result the value in
ZDbcDbLibResultSet.pas

function TZDBLibResultSet.GetString(ColumnIndex: Integer): AnsiString;

DL for name1 returns 1
Data return ' ' one space character

it is decreased and the Result is not set anymore and in Delphi 2007 remains the previous Result ( the value of name column in this example)

i made the following code change and work so far :

Code: Select all

function TZDBLibResultSet.GetString(ColumnIndex: Integer): AnsiString;
var
  DL: Integer;
  Data: Pointer;
  DT: Integer;
begin
  CheckClosed;
  CheckColumnIndex(ColumnIndex);

  DL := FPlainDriver.dbDatLen(FHandle, ColumnIndex);
  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);
  DT := DBLibColTypeCache[ColumnIndex];
  LastWasNull := Data = nil;

  Result := '';
  if Assigned(Data) then
  begin
    case DT of
      SQLCHAR, SQLTEXT:
        begin
          while (DL > 0) and (PAnsiChar(Integer(Data) + DL - 1)^ = ' ') do
                  Dec(DL);
          if DL > 0 then
          begin
            SetLength(Result, DL);
            Move(Data^, PAnsiChar(Result)^, DL);
          end;
        end;
      SQLIMAGE:
        begin
          SetLength(Result, DL);
          Move(Data^, PAnsiChar(Result)^, DL);
        end;
    else
      begin
        SetLength(Result, 4001);
        DL := FPlainDriver.dbconvert(FHandle, DT, Data, DL, SQLCHAR, Pointer(PAnsiChar(Result)), Length(Result));
        while (DL > 0) and (Result[DL] = ' ') do
            Dec(DL);
        SetLength(Result, DL);
      end;
    end;
  end;
  //else

  FDBLibConnection.CheckDBLibError(lcOther, 'GETSTRING');
end;
i saw that getPchar in older edition work because of a FTemp variable defined as String and cast to PChar as a result.

It this ok ? or it is other way around ?

Posted: 02.04.2011, 23:50
by mdaems
Hoi Chris,

Can you please mark exactly what you fixed? Some SVN diff report would be ideal.

Groeten,

Mark

Posted: 30.10.2011, 21:22
by mdaems
Patch applied to Zeos 7.X Testing branch on 20/11/2011 by seawolf. (SVN rev 949).

Mark