Firebird 2.1 final release
Moderators: gto, cipto_kh, EgonHugeist
Hi all,
I use only simple TZConnection+TZQuery combinantion.
The problem with double TZQuery.Open necessity seems to be solved with ZeosLib building with directive {$DEFINE FOSNOMETA}. But there is comment:
//PATCH TO DO NO METADATALOADING / UNTESTED HIGH RISK
Is there someone who can tell, where it can prove and how high the risk is?
This directive is used only in one specific place - the one where is the problem:
TZAbstractRODataset.InternalInitFieldDefs:
{$IFNDEF FOSNOMETA}
Required := IsWritable(I) and (IsNullable(I) = ntNoNulls);
{$ENDIF}
The AV come in this call stack:
TZAbstractRODataset.InternalInitFieldDefs -> TZAbstractResultSetMetadata.IsWritable(1) ->
TZAbstractResultSetMetadata.LoadColumns -> TZAbstractResultSetMetadata.LoadColumn ->
TZAbstractResultSetMetadata.ReadColumnByName -> TZAbstractResultSetMetadata.GetTableColumns -> TZInterbase6DatabaseMetadata.GetColumns -> TZAbstractDatabaseMetadata.AddResultSetToCache
Here the AV come IMHO because resultSet of previous internal metadata query has no records (maybe?).
Thanks Fisa.
I use only simple TZConnection+TZQuery combinantion.
The problem with double TZQuery.Open necessity seems to be solved with ZeosLib building with directive {$DEFINE FOSNOMETA}. But there is comment:
//PATCH TO DO NO METADATALOADING / UNTESTED HIGH RISK
Is there someone who can tell, where it can prove and how high the risk is?
This directive is used only in one specific place - the one where is the problem:
TZAbstractRODataset.InternalInitFieldDefs:
{$IFNDEF FOSNOMETA}
Required := IsWritable(I) and (IsNullable(I) = ntNoNulls);
{$ENDIF}
The AV come in this call stack:
TZAbstractRODataset.InternalInitFieldDefs -> TZAbstractResultSetMetadata.IsWritable(1) ->
TZAbstractResultSetMetadata.LoadColumns -> TZAbstractResultSetMetadata.LoadColumn ->
TZAbstractResultSetMetadata.ReadColumnByName -> TZAbstractResultSetMetadata.GetTableColumns -> TZInterbase6DatabaseMetadata.GetColumns -> TZAbstractDatabaseMetadata.AddResultSetToCache
Here the AV come IMHO because resultSet of previous internal metadata query has no records (maybe?).
Thanks Fisa.
Oh, God!
I just tested the latest ZEOSLIB_TESTING_REV387 with Firebird 2.1.1 without changing anything in my code and IT WORKED!!!! Waiting for this since a looong time. If I had skills to code Zeos I could help you in this, but I am just an user.
Thanks Draconius for publishing your test results!
Thanks Zeoslib team for this GREAT piece of software!
Prometeus
I just tested the latest ZEOSLIB_TESTING_REV387 with Firebird 2.1.1 without changing anything in my code and IT WORKED!!!! Waiting for this since a looong time. If I had skills to code Zeos I could help you in this, but I am just an user.
Thanks Draconius for publishing your test results!
Thanks Zeoslib team for this GREAT piece of software!
Prometeus
I've several day on resolving that problem and, taking a look at the bug fixes doc, I read that
(CORE-1868) The server could crash in isc_dsql_free_statement().
fixed by A. Peshkoff
I think that was the problem.
If you want I can send you the changes i've made .. anyway I did a new unit (specific for Firebird 2.1)
(CORE-1868) The server could crash in isc_dsql_free_statement().
fixed by A. Peshkoff
I think that was the problem.
If you want I can send you the changes i've made .. anyway I did a new unit (specific for Firebird 2.1)
I just curious how to make a driver like that. I think there is a lot of functionality addition between FB 2.0 and 2.1, isn't it? If it covers the API changed for FB 2.1 then it should be added.
As I know for example the 2.1 version has returning clause for insert or update and it is nice if the new 2.1 protocol can handle it
As I know for example the 2.1 version has returning clause for insert or update and it is nice if the new 2.1 protocol can handle it
here you can found all the dll to place in lib/firebird/windows/32bit/2.1.1.17910
Hello,
I got some problems with BLOB field using Firebird 2.1.1 . I guess this situation belongs to Firebird release, but not sure. Did someone got this problem too? The error message is something like "INVALID BLOB ID". I tried this with a restored database (filled with real data) through Firebird 2.1.1 and with a database created from zero through Firebird 2.1.1. The error appeared in both cases but not with all BLOBs.
I got some problems with BLOB field using Firebird 2.1.1 . I guess this situation belongs to Firebird release, but not sure. Did someone got this problem too? The error message is something like "INVALID BLOB ID". I tried this with a restored database (filled with real data) through Firebird 2.1.1 and with a database created from zero through Firebird 2.1.1. The error appeared in both cases but not with all BLOBs.
Last edited by Prometeus on 27.07.2008, 23:48, edited 2 times in total.
Hello,
No, this is the first time I saw this error. Until Firebird 2.04 no problems at all and with all database I have used with Firebird + Zeos. The worse part is that with the same update statement sometime the error appears but not always. And it is related with Blob fields indeed.
The statement is a simple update like 'UPDATE .... WHERE (x = y) AND (k > j)'. I am a bit busy with a project I'm involved and could not continue using version 2.1.1 in production database, so I came back to version 2.04 until this problem gets fixed. I saw at Firebird forums that there was an 'INVALID BLOB ID' bug that was fixed in previous releases but I never had got it until this 2.1.1 version.
Maybe its a Firebird bug. I'll try finding some time in order to check further this problem.
Thanks.
No, this is the first time I saw this error. Until Firebird 2.04 no problems at all and with all database I have used with Firebird + Zeos. The worse part is that with the same update statement sometime the error appears but not always. And it is related with Blob fields indeed.
The statement is a simple update like 'UPDATE .... WHERE (x = y) AND (k > j)'. I am a bit busy with a project I'm involved and could not continue using version 2.1.1 in production database, so I came back to version 2.04 until this problem gets fixed. I saw at Firebird forums that there was an 'INVALID BLOB ID' bug that was fixed in previous releases but I never had got it until this 2.1.1 version.
Maybe its a Firebird bug. I'll try finding some time in order to check further this problem.
Thanks.
Coulb be the problem you have?
Hello,
I am not sure as I detected this problem when editing a BLOB, not inserting twice as the bug you pointed out reported. I need to test it more, but there is an affirmation that changes occurred in FB 2.1 API for BLOB fields. That is a bad news if someone did not fix this in Zeos. So, I will be using previous version until this get fixed. It's a shame as Firebird 2.1 has great new features.
Thanks.
I am not sure as I detected this problem when editing a BLOB, not inserting twice as the bug you pointed out reported. I need to test it more, but there is an affirmation that changes occurred in FB 2.1 API for BLOB fields. That is a bad news if someone did not fix this in Zeos. So, I will be using previous version until this get fixed. It's a shame as Firebird 2.1 has great new features.
Thanks.
Until now I have found no problems.
I created a new test that perform a delete, an insert, an update
and a null update. Test works correctly.
procedure TZTestDbcInterbaseCase.TestUpdateBlobs;
var
Connection: IZConnection;
PreparedStatement: IZPreparedStatement;
Statement: IZStatement;
ResultSet: IZResultSet;
TextStream: TStream;
ImageStream: TMemoryStream;
TempStream: TStream;
begin
Connection := CreateDbcConnection;
Statement := Connection.CreateStatement;
CheckNotNull(Statement);
Statement.SetResultSetType(rtScrollInsensitive);
Statement.SetResultSetConcurrency(rcReadOnly);
Statement.ExecuteUpdate('DELETE FROM BLOB_VALUES WHERE B_ID='
+ IntToStr(TEST_ROW_ID));
TextStream := TStringStream.Create('ABCDEFG');
ImageStream := TMemoryStream.Create;
ImageStream.LoadFromFile('../../../database/images/zapotec.bmp');
PreparedStatement := Connection.PrepareStatement(
'INSERT INTO BLOB_VALUES (B_ID, B_TEXT, B_IMAGE) VALUES(?,?,?)');
PreparedStatement.SetInt(1, TEST_ROW_ID);
PreparedStatement.SetAsciiStream(2, TextStream);
PreparedStatement.SetBinaryStream(3, ImageStream);
CheckEquals(1, PreparedStatement.ExecuteUpdatePrepared);
ResultSet := Statement.ExecuteQuery('SELECT * FROM BLOB_VALUES'
+ ' WHERE b_id=' + IntToStr(TEST_ROW_ID));
CheckNotNull(ResultSet);
Check(ResultSet.Next);
CheckEquals(TEST_ROW_ID, ResultSet.GetIntByName('B_ID'));
TempStream := ResultSet.GetAsciiStreamByName('B_TEXT');
CheckEquals(TextStream, TempStream);
TempStream.Free;
TempStream := ResultSet.GetBinaryStreamByName('B_IMAGE');
CheckEquals(ImageStream, TempStream);
TempStream.Free;
// Update blob
TextStream.Free;
ImageStream.Free;
TextStream := TStringStream.Create('GFEDCBA');
ImageStream := TMemoryStream.Create;
ImageStream.LoadFromFile('../../../database/images/dogs.jpg');
PreparedStatement := Connection.PrepareStatement(
'UPDATE BLOB_VALUES SET B_TEXT =?,B_IMAGE=? WHERE B_ID=?');
PreparedStatement.SetInt(3, TEST_ROW_ID);
PreparedStatement.SetAsciiStream(1, TextStream);
PreparedStatement.SetBinaryStream(2, ImageStream);
CheckEquals(1, PreparedStatement.ExecuteUpdatePrepared);
ResultSet := Statement.ExecuteQuery('SELECT * FROM BLOB_VALUES'
+ ' WHERE b_id=' + IntToStr(TEST_ROW_ID));
CheckNotNull(ResultSet);
Check(ResultSet.Next);
CheckEquals(TEST_ROW_ID, ResultSet.GetIntByName('B_ID'));
TempStream := ResultSet.GetAsciiStreamByName('B_TEXT');
CheckEquals(TextStream, TempStream);
TempStream.Free;
TempStream := ResultSet.GetBinaryStreamByName('B_IMAGE');
CheckEquals(ImageStream, TempStream);
TempStream.Free;
// Update null binary blob
TextStream.Free;
TextStream := TStringStream.Create('GFEDCBA');
PreparedStatement := Connection.PrepareStatement(
'UPDATE BLOB_VALUES SET B_TEXT =?,B_IMAGE=? WHERE B_ID=?');
PreparedStatement.SetInt(3, TEST_ROW_ID);
PreparedStatement.SetAsciiStream(1, TextStream);
PreparedStatement.SetNull(2,stBinaryStream);
CheckEquals(1, PreparedStatement.ExecuteUpdatePrepared);
ResultSet := Statement.ExecuteQuery('SELECT * FROM BLOB_VALUES'
+ ' WHERE b_id=' + IntToStr(TEST_ROW_ID));
CheckNotNull(ResultSet);
Check(ResultSet.Next);
CheckEquals(TEST_ROW_ID, ResultSet.GetIntByName('B_ID'));
TempStream := ResultSet.GetAsciiStreamByName('B_TEXT');
CheckEquals(TextStream, TempStream);
CheckNull(ResultSet.GetBinaryStreamByName('B_IMAGE'));
TempStream.Free;
// Update null ascii blob
PreparedStatement := Connection.PrepareStatement(
'UPDATE BLOB_VALUES SET B_TEXT =?,B_IMAGE=? WHERE B_ID=?');
PreparedStatement.SetInt(3, TEST_ROW_ID);
PreparedStatement.SetNull(1,stAsciiStream);
PreparedStatement.SetNull(2,stBinaryStream);
CheckEquals(1, PreparedStatement.ExecuteUpdatePrepared);
ResultSet := Statement.ExecuteQuery('SELECT * FROM BLOB_VALUES'
+ ' WHERE b_id=' + IntToStr(TEST_ROW_ID));
CheckNotNull(ResultSet);
Check(ResultSet.Next);
CheckEquals(TEST_ROW_ID, ResultSet.GetIntByName('B_ID'));
CheckNull(ResultSet.GetAsciiStreamByName('B_TEXT'));
CheckNull(ResultSet.GetBinaryStreamByName('B_IMAGE'));
ResultSet.Close;
TextStream.Free;
ImageStream.Free;
Statement.Close;
end;
I created a new test that perform a delete, an insert, an update
and a null update. Test works correctly.
procedure TZTestDbcInterbaseCase.TestUpdateBlobs;
var
Connection: IZConnection;
PreparedStatement: IZPreparedStatement;
Statement: IZStatement;
ResultSet: IZResultSet;
TextStream: TStream;
ImageStream: TMemoryStream;
TempStream: TStream;
begin
Connection := CreateDbcConnection;
Statement := Connection.CreateStatement;
CheckNotNull(Statement);
Statement.SetResultSetType(rtScrollInsensitive);
Statement.SetResultSetConcurrency(rcReadOnly);
Statement.ExecuteUpdate('DELETE FROM BLOB_VALUES WHERE B_ID='
+ IntToStr(TEST_ROW_ID));
TextStream := TStringStream.Create('ABCDEFG');
ImageStream := TMemoryStream.Create;
ImageStream.LoadFromFile('../../../database/images/zapotec.bmp');
PreparedStatement := Connection.PrepareStatement(
'INSERT INTO BLOB_VALUES (B_ID, B_TEXT, B_IMAGE) VALUES(?,?,?)');
PreparedStatement.SetInt(1, TEST_ROW_ID);
PreparedStatement.SetAsciiStream(2, TextStream);
PreparedStatement.SetBinaryStream(3, ImageStream);
CheckEquals(1, PreparedStatement.ExecuteUpdatePrepared);
ResultSet := Statement.ExecuteQuery('SELECT * FROM BLOB_VALUES'
+ ' WHERE b_id=' + IntToStr(TEST_ROW_ID));
CheckNotNull(ResultSet);
Check(ResultSet.Next);
CheckEquals(TEST_ROW_ID, ResultSet.GetIntByName('B_ID'));
TempStream := ResultSet.GetAsciiStreamByName('B_TEXT');
CheckEquals(TextStream, TempStream);
TempStream.Free;
TempStream := ResultSet.GetBinaryStreamByName('B_IMAGE');
CheckEquals(ImageStream, TempStream);
TempStream.Free;
// Update blob
TextStream.Free;
ImageStream.Free;
TextStream := TStringStream.Create('GFEDCBA');
ImageStream := TMemoryStream.Create;
ImageStream.LoadFromFile('../../../database/images/dogs.jpg');
PreparedStatement := Connection.PrepareStatement(
'UPDATE BLOB_VALUES SET B_TEXT =?,B_IMAGE=? WHERE B_ID=?');
PreparedStatement.SetInt(3, TEST_ROW_ID);
PreparedStatement.SetAsciiStream(1, TextStream);
PreparedStatement.SetBinaryStream(2, ImageStream);
CheckEquals(1, PreparedStatement.ExecuteUpdatePrepared);
ResultSet := Statement.ExecuteQuery('SELECT * FROM BLOB_VALUES'
+ ' WHERE b_id=' + IntToStr(TEST_ROW_ID));
CheckNotNull(ResultSet);
Check(ResultSet.Next);
CheckEquals(TEST_ROW_ID, ResultSet.GetIntByName('B_ID'));
TempStream := ResultSet.GetAsciiStreamByName('B_TEXT');
CheckEquals(TextStream, TempStream);
TempStream.Free;
TempStream := ResultSet.GetBinaryStreamByName('B_IMAGE');
CheckEquals(ImageStream, TempStream);
TempStream.Free;
// Update null binary blob
TextStream.Free;
TextStream := TStringStream.Create('GFEDCBA');
PreparedStatement := Connection.PrepareStatement(
'UPDATE BLOB_VALUES SET B_TEXT =?,B_IMAGE=? WHERE B_ID=?');
PreparedStatement.SetInt(3, TEST_ROW_ID);
PreparedStatement.SetAsciiStream(1, TextStream);
PreparedStatement.SetNull(2,stBinaryStream);
CheckEquals(1, PreparedStatement.ExecuteUpdatePrepared);
ResultSet := Statement.ExecuteQuery('SELECT * FROM BLOB_VALUES'
+ ' WHERE b_id=' + IntToStr(TEST_ROW_ID));
CheckNotNull(ResultSet);
Check(ResultSet.Next);
CheckEquals(TEST_ROW_ID, ResultSet.GetIntByName('B_ID'));
TempStream := ResultSet.GetAsciiStreamByName('B_TEXT');
CheckEquals(TextStream, TempStream);
CheckNull(ResultSet.GetBinaryStreamByName('B_IMAGE'));
TempStream.Free;
// Update null ascii blob
PreparedStatement := Connection.PrepareStatement(
'UPDATE BLOB_VALUES SET B_TEXT =?,B_IMAGE=? WHERE B_ID=?');
PreparedStatement.SetInt(3, TEST_ROW_ID);
PreparedStatement.SetNull(1,stAsciiStream);
PreparedStatement.SetNull(2,stBinaryStream);
CheckEquals(1, PreparedStatement.ExecuteUpdatePrepared);
ResultSet := Statement.ExecuteQuery('SELECT * FROM BLOB_VALUES'
+ ' WHERE b_id=' + IntToStr(TEST_ROW_ID));
CheckNotNull(ResultSet);
Check(ResultSet.Next);
CheckEquals(TEST_ROW_ID, ResultSet.GetIntByName('B_ID'));
CheckNull(ResultSet.GetAsciiStreamByName('B_TEXT'));
CheckNull(ResultSet.GetBinaryStreamByName('B_IMAGE'));
ResultSet.Close;
TextStream.Free;
ImageStream.Free;
Statement.Close;
end;