Page 1 of 1

[solved] PostgreSQL WideMemo field

Posted: 15.10.2013, 17:18
by markus
Hi,
I've recently updated my Zeos source code from svn, and i've stumbled upon such problem:
When using AsString method of TField on text column from DB i get Access Violation when value in column is empty string.
If it's NULL or column have actual value then it works ok.

This error occurs first in rev. 2746.

Best regards,
Marek

Re: PostgreSQL WideMemo field

Posted: 16.10.2013, 20:35
by EgonHugeist
Hi Marek,

I made a testcase to reproduce your report:

Code: Select all

procedure TZGenericTestDbcResultSetMBCs.TestClobEmptyString;
var
  Query: TZQuery;
  TextLob: String;
begin
  Query := CreateQuery;
  try
    with Query do
    begin
      SQL.Text := 'DELETE FROM blob_values where b_id = '+ IntToStr(TEST_ROW_ID-2);
      ExecSQL;
      if StartsWith(LowerCase(Connection.Protocol), 'oracle') then
        TextLob := 'b_clob'
      else if StartsWith(LowerCase(Connection.Protocol), 'sqlite') then
        TextLob := 'b_text'
      else
        TextLob := 'b_text';
      Sql.Text := 'INSERT INTO blob_values (b_id,'+TextLob+')'
        + ' VALUES (:b_id,:b_text)';
      CheckEquals(2, Params.Count);
      Params[0].DataType := ftInteger;
      {$IFDEF WITH_WIDEMEMO}
      if Connection.DbcConnection.GetConSettings.CPType = cCP_UTF16 then
        Params[1].DataType := ftWideMemo
      else
      {$ENDIF}
        Params[1].DataType := ftMemo;
      Params[0].AsInteger := TEST_ROW_ID-2;
      {$IFDEF WITH_WIDEMEMO}
      if Connection.DbcConnection.GetConSettings.CPType = cCP_UTF16 then
        Params[1].AsWideString := ''
      else
      {$ENDIF}
        Params[1].AsString := '';
      ExecSQL;

      CheckEquals(1, RowsAffected);

      SQL.Text := 'SELECT * FROM blob_values where b_id = '+ IntToStr(TEST_ROW_ID-2);
      CheckEquals(0, Query.Params.Count);

      Open;
      CheckEquals(1, RecordCount);
      CheckEquals(False, IsEmpty);
      CheckEquals(TEST_ROW_ID-2, FieldByName('b_id').AsInteger);
      CheckEquals(False, FieldByName(TextLob).IsNull, 'Memo is not empty.');
      CheckEquals('', FieldByName(TextLob).AsString, 'Empty but not null String');
      Close;
      SQL.Text := 'DELETE FROM blob_values where b_id = '+ IntToStr(TEST_ROW_ID-1);
      ExecSQL;
    end;
  finally
    Query.Free;
  end;
end;
But i can't see the AV your are talking about. Can you have a look and tell me what i have to change to catch the bug?

EDIT: Found a possible index overflow for empty strings and fixed this by switching to pointers. R2839 \testing-7.2

Re: PostgreSQL WideMemo field

Posted: 18.10.2013, 21:52
by markus
Hi Michael,

Sorry for late reply, i've downloaded latest rev from svn and i don't have this error anymore.
Thanks a lot for your support.

Best regards,
Marek