List of Bug Fixes in Update 4 (Database Pack) for Delphi and C++Builder 2009

By: Kris Houser

Abstract: Lists the bugs that were fixed in Update 4 for Delphi and C++Builder 2009

This article lists all the fixes included in Update 4 (Database Pack) for Delphi and C++Builder 2009, and for RAD Studio 2009.

If you have the initial release of Delphi or C++Builder 2009, or RAD Studio 2009, you can download updates free of charge from the registered users page.

If you're unsure which release you have, select Help | About in the IDE.

  Fix List

QC #: Date Reported: Area:
7527 3/5/2004 Database\Data Aware Controls\TDBGrid
Description: Steps:
Update: DBGrid doesn't repaint itself correctly when scroll bars get are toggled from off, to on, to off. (This is really seen in master detail apps... when a master record has 0 detail and another master record has serveral detail records)

[QC Short Description]
TDBGrid vertical scrollbar dissappears

[QC Description]
When you have a master/detail record, and the detail is shown using a TDBGrid, then the vertical scrollbar dissappear randomly, even if there are more records than will fit! You can see the right border outline of the scrollbar though, including the thumb thingy moving. It's as if the grid has resized slightly over the scrollbar.

See attached test-case.
QC Entry 7527
1. Compile and Run the attached test-case 2. Record 4 is active in the top grid; note that the bottom detail grid needs a scrollbar to show all records 3. In the top grid activate the record with 5 in the first field 4. Go back to the record 4 exp: Scrollbar in the bottom detail grid should be displayed as in step 2 act: Scollbar is hidden If you repeat steps 3 and 4, notice how the grid scrollbar appears and dissappears. You can just about make out the outline of the scrollbar on the right, including the thumb thingy shadow moving as you scroll!

QC #: Date Reported: Area:
35001 10/9/2006 Database\Data Aware Controls\TDBGrid
Description: Steps:
[QC Short Description]
MDIChild's active control focus is not set correctly for a DBGrid.
(Applies to Delphi 7)
[QC Description]
If you have a TWinControl on the MDIForm that can get the focus and then you click on the last active MDI Child, the MDI Child's active control isn't focused for Windows, but the VCL thinks it is and doesn't execute a Windows.SetFocus on it.

The problem is that the SetActiveControl call in TCustomForm.FocusControl doesn't do anything because there was no change in the ActiveControl of the MDIChild. But the "ActiveControl" isn't Focused().
QC Entry 35001
1. Download and start the attached project 2. Click on the button on the left panel 3. Click on a non-selected row of the DBGrid in the MDIChild Expected: The row is now selected Actually: Nothing happens.
QC #: Date Reported: Area:
50327 8/10/2007 Database\ADO
Description: Steps:
[QC Short Description]
TADODataSet throws "invalid variant operation" exception

[QC Description]
Technical stuff

OS.........: Windows XP SP2 and Windows Vista Business
MDAC.......: 2.81.1117.0
Compiler...: Delphi 2007 for Win32 (11.0.2709.7128)
Database...: MS-SQL Server 2005 Developer and Express with SP2 (9.0.3042)
QC Entry 50327
TDBXWeaverBugsSuite.Native.DB.Test.exe connection=mssqlconnection -s:TestRaid_263745

=or=

Take a look at the example source code (attachment) and you can see everything works fine with an access database/tables.

Try the same thing with MS-SQL 2005 tables where the primary keys are BIGINT and the foreign key ADDR_ID in the second table is also an BIGINT.



Debugging


--> ADODB.PAS

Failure in

procedure TCustomADODataSet.RefreshParams;

in sub function

function MasterFieldsChanged: boolean;
{ .. }
if Parameters.ParamByName(MasterField.FieldName).Value <> MasterField.Value then // <-- This creates the "invalid variant operation"
{ ... }


How to solve?

Seems to be a problem with trying to compare an varDecimal with varInt64?
QC #: Date Reported: Area:
67891 10/14/2008 Database\TField\TStringField\TWideStringField
Description: Steps:
[QC Short Description]
TWideStringField.IsNull returns wrong result

[QC Description]
TWideStringField.IsNull method provides wrong results in Delphi 2009, and works differently in comparison to previous Delphi versions.

When assigning an empty string to a WideStringField it returns True in 2009, but False in 2007.
QC Entry 67891
TDBXWeaverBugsSuite.Native.DB.Test.exe connection=mssqlconnection -s:TestRaid_265858

Run the attached sample and click Test. See how the AnsiStringIsNull and WideStringIsNull fields are filled.

The attached archive also contains screenshots with the results for different Delphi versions.
QC #: Date Reported: Area:
68045 10/18/2008 Database\ADO
Description: Steps:
[QC Short Description]
TADOQuery/Table converts empty string to null

[QC Description]
The command
adotable1['varchar_field'] := '';
converts the empty string to null

This is not desirable and it is different from D7 and D2007.
QC Entry 68045
TDBXWeaverBugsSuite.Native.DB.Test.exe connection=mssqlconnection -s:TestRaid_265947

==or==

Connect a TADOTable to any table (e.g. MS Access, MS SQL Server) that has at least a varchar field and one row.

Open the table, edit the varchar field and assign an empty string to it.

e.g.
adotable1.open;
adotable1.edit;
adotable1['varchar_field'] := '';
adotable1.post;

if adotable1['varchar_field'] = '' then
showmessage('OK') //expected
else
showmessage('PROBLEM') //actual


QC #: Date Reported: Area:
68492 11/1/2008 Database\ADO
Description: Steps:
[QC Short Description]
Assign TParam to TParameter

[QC Description]
Exception occurs if TParam (DataType = ftInteger and Value = 1) assign to TParameter.
Error Message: "Arguments are the wrong type, are out of accetable range, or are in conflict with one another".

This error occurs in TDataSetProvider and i can't migrate our project from D2007 to D2009.
We have multitier application with TClientDataSet -> TRemoteDataModule -> TDataSetProvider -> TADOQuery.

TClientDataSet doesn't open if CommandText has params like as 'EXEC spProcedure :PARAM' and param's DataType is ftInteger and Value is 1)

I have developed simple example project.
QC Entry 68492
TDBXWeaverBugsSuite.Native.DB.Test.exe connection=mssqlconnection -s:TestRaid_266288

==or=

procedure TForm1.Button1Click(Sender: TObject);
var
c1: TParams;
c2: TParameters;

p1: TParam;
p2: TParameter;
begin
c1 := TParams.Create(TParam);
try
p1 := c1.CreateParam(ftInteger, 'TEST', ptInput);
p1.Value := 1;

c2 := TParameters.Create(ADOCommand1, TParameter);
try
p2 := TParameter.Create(c2);
p2.Assign(p1); // Exception!!!!
finally
c2.Free;
end;
finally
c1.Free;
end;
end;
QC #: Date Reported: Area:
68616 11/5/2008 Database\ADO
Description: Steps:
[QC Short Description]
TAdoStoredProc returns parameter's value without decimal places

[QC Description]
TAdoStoredProc invokes simple stored proc in MsSqlServer which returns a decimal value
(ex. 150.55)

In D2009 TAdoStoredProc returns 15055 instead of 150.55.

In D2007 TAdoStoredProc returns correct value (ex. 150.55)

QC Entry 68616


Note from Tomohiro Takahashi
<<<<<<<<<<
Please see comment and workaround at QC.
If a instance of TAdoStoredProc is created at Design Time, we get correct value.
>>>>>>>>>>
TDBXWeaverBugsSuite.Native.DB.Test.exe connection=mssqlconnection -s:TestRaid_266369

1. create a simple stored proc in mssqlserver which returs a numeric value

create procedure [dbo].[test] (@t1 numeric(12,2), @t2 numeric(12,2) output) as
begin
set @t2 = @t1 + 0.55;
end;

2. Create a simple form with two TEdit and one TButton object

3. Attach this code in Tbutton.OnClick event

procedure TForm1.Button1Click(Sender: TObject);
var
SP: TAdoStoredProc;
begin
SP := TAdoStoredProc.Create(Self);
SP.Connection := AdoConnection1;
SP.ProcedureName := 'Test';
SP.Parameters.Refresh;


SP.Parameters.ParamByName('@t1').Value := StrToFloat(Edit1.Text) ;
SP.Parameters.ParamByName('@t2').Value := null;


SP.ExecProc;
Edit2.Text := SP.Parameters.ParamByName('@t2').Value;
SP.Free;
end;

4. run the project .

Enter value in Edit1. (ex. 150)
Press the button.
Edit2 shows 15055 instead of 150.55 !
QC #: Date Reported: Area:
69413 11/28/2008 Database\Data Access Controls\TTable
Description: Steps:
[QC Short Description]
TTable.Exists always returns False

[QC Description]
This is related to QC report number 69409 because the code in TTable.GetFileName relies on the database Directory property which does not contain a valid string.

This worked fine under D2007

See also Raid# 266976, which causes this bug too.

QC Entry 69413
Drop a TDatabase, TTable and a TButton on a form Set the TDatabse DatabaseName to 'LocalDB' Set the TDatabase AliasName to a DBDEMOS Set the TTable DatabaseName to 'LocalDB' and set it's TableName to customer.db In the Buttons OnClick event add this code ShowMessage('Table1.Exists = ' + BoolToStr(Table1.Exists, True)); Run it and click the button. It always results in Table1.Exists = False A lot of conditional opening of tables is based on this and it's a complete showstopper for me.
QC #: Date Reported: Area:
69409 11/28/2008 Database\Data Access Controls\TDatabase
Description: Steps:
[QC Short Description]
Getting or Setting TDatabase Directory property fails

[QC Description]
There are string handling issues with TDatabase GetDirectory and SetDirectory.

Attempting to read the Directory property returns what appears to be an uninitialized string of characters.

Setting the property to a known path and subsequently reading it back gives the same obscure results.

This worked fine under D2007
QC Entry 69409
Drop a TDatabase, TTable and a TButton on a form Set the TDatabse DatabaseName to 'LocalDB' Set the TDatabase AliasName to a DBDEMOS Set the TTable DatabaseName to 'LocalDB' and set it's TableName to customer.db In the Buttons OnClick event add this code Table1.Open; ShowMessage(Database1.Directory); Run it and click the button. The table is opened but the message dialog (Ctrl C copied to paste here) shows --------------------------- Project1 --------------------------- ??????????????????????????????????????????????????" << note: this was originally chinese, wingdings type characters --------------------------- OK --------------------------- If you also add an AfterConnect event handler on the TDatabase and add the following code Database1.Directory := 'C:\Program Files\Common Files\CodeGear Shared\Data'; You still get a similar result as before when clicking the button So you can't read or write the Directory property. Note: After initial submission of this report, the strange characters (some chinese, wingdings type stuff etc.) changed to all question marks
QC #: Date Reported: Area:
69432 11/29/2008 Database\Data Access Controls\TTable
Description: Steps:
[QC Short Description]
Error opening table when field has a DefaultExpression

[QC Description]
There seems to be an issue with the GetDefaultExpression function in the TBDEDataSet.ConstraintCallBack function in the DBTables unit.

I was getting the following error when opening the TTable which has persistent fields and two of them (TBooleanFields) have a DefaultExpression set to FALSE.

"Preparation of field default failed.
Token not found.
Token: €€€€€€Ì << these look like euro symbols and accented characters
Line Number: 1"

I traced into the above function and found that after calling this line:

StrCopy(ADataSources.szSQLExprImport, GetPAnsiChar(Field.DefaultExpression));

The value in ADataSources.szSQLExprImport is all corrupt characters.

If I remove the DefaultExpressions from the two fields, the table opens without error.

I cannot replicate this in a simple test project but within a large application with several tables, queries, datamodules, etc. the error happens every time. The strange characters can vary each time though.

This worked fine under D2007


QC Entry 69432
I tried the following The GetPAnsiChar is as follows function GetPAnsiChar(const S: string): PAnsiChar; begin if S <> '' then Result := PAnsiChar(AnsiString(S)) else Result := ''; end; But if I replace the original line with this: StrCopy(ADataSources.szSQLExprImport, PAnsiChar(AnsiString(Field.DefaultExpression))); Then the error doesn't occur any more and ADataSources.szSQLExprImport always contains a valid value (FALSE in my case) Now, this looks to me to be doing exactly the same thing but I think something is going wrong when calling GetPAnsiChar instead which causes it to return the corrupt string. I've spent ages trying to replicate it outside the main application but cannot do so. It only raises the error when I run the big application with lots of tables/queries open If pushed I could probably send you a screen vid of the situation happening in the debugger.
QC #: Date Reported: Area:
69700 12/8/2008 Database\TField
Description: Steps:
[QC Short Description]
New field types added in Delphi 2009 are not registered. This includes TLongWordField, TShortintField, TByteField, and TExtendedField.

[QC Description]
TByteField, arguably the most useful field for storing enumerated types, is not registered.
QC Entry 69700
Examine DBReg.pas and look for these new field types in the RegisterFields call:

RegisterFields([TStringField, TIntegerField, TSmallintField, TWordField,
TFloatField, TCurrencyField, TBCDField, TFMTBcdField, TBooleanField, TDateField,
TVarBytesField, TBytesField, TTimeField, TDateTimeField, TSQLTimeStampField,
TBlobField, TMemoField, TGraphicField, TAutoIncField, TLargeIntField,
TADTField, TArrayField, TDataSetField, TReferenceField, TAggregateField,
TWideStringField, TVariantField, TGuidField, TInterfaceField, TIDispatchField,
TWideMemoField]);

QC #: Date Reported: Area:
70521 1/14/2009 Database\Data Aware Controls\TDBGrid
Description: Steps:
[QC Short Description]
DBGrid-InplaceEditor ignores pasted text

[QC Description]
The DBGrid InplaceEditor ignores text that was pasted from the clipboard if the field has an EditMask.

This is because the TCustomMaskEdit overrides the WM_PASTE (and WM_CUT) message handler and if as mask is specified, the default handler isn't called. The default handler sends a WM_COMMAND(EN_CHANGE) to the parent but without calling the default handler this message isn't sent to the DBGrid and the content of the edit is never copied to the internal InplaceEdit text field.
QC Entry 70521
1. Open the attached project 2. Start the project (This will copy '12.12.08' into the clipboard) 3. Click into the FLD_DATE field in the grid (show inplace editor) 4. Paste the clipboard text into the control by pressing Ctrl+V 5. Use TAB, ENTER or the mouse to leave the edit mode Expected: '12.12.08' is now in the field. Actual: The field is still empty.
QC #: Date Reported: Area:
71123 2/3/2009 Database\Data Access Controls\TQuery
Description: Steps:
[QC Short Description]
Param data string truncation with 2byte char in TParam and BDE

[QC Description]
When passed 2byte char string to TParam of TQuery, data truncates as if the string is made up of only 1byte char.

This seems because of VCL bugs in 2 location.
In line 9596 in DB.pas,
Result := Length(VarToStr(FData)) + 1;
this should be,
Result := Length(AnsiString(VarToStr(FData))) + 1;

And line 1457 in DBTables.pas,
AnsiToNativeBuf(DrvLocale, PAnsiChar(AnsiString(NativeStr)), Buffer, Length(NativeStr) + 1) else
this should be,
AnsiToNativeBuf(DrvLocale, PAnsiChar(AnsiString(NativeStr)), Buffer, Length(AnsiString(NativeStr)) + 1) else

I think there is some other points to correct like above, like BLOB text handling.
QC Entry 71123
Run an attached project under Japanese locale.

1. Click "Create Table" button. TestTbl.DB is created, and DBGrid will display data.
2. Click "Query SBCS" button. DBGrid display 1 line what we expected.
3. Click "Query DBCS" button.

Exp: One data record display on DBGrid. F1 field is 2. (F2 is DBCS character)
Act: No record is selected.

D2007 works fine.
QC #: Date Reported: Area:
71082 2/3/2009 Database\DataSnap\Server
Description: Steps:
[QC Short Description]
TDataSetProvider.OnDataRequest fails with variant error

QC Entry 71082
UnitTest: http://dtg-svn/svn/bdstests/trunk/UnitTest/projects/database/datasnap/rdm/native32/DataSnapRDM.Native.DB.Test.dpr

-sTest_AS_DataRequest.

Server:
Setup a basic DataSnap server with a TSQLConnection, TSQLDataSet, and TDataSetProvider (and TDSServer, TDSServerClass, TDSTCPServerTranspot for DataSnap 2009 connectivity).

Add an event handler for TDataSetProvider.OnDataRequest to do something simple, like setting the result to the input parameter.

Client:
Setup a basic DataSnap client with a TSQLConnection, TDSProviderConnection, and TClientDataSet. Hook everything up so the data set gets data from the data set in the server.

Call TClientDataSet.DataRequest. The server will throw a variant exception.

Cause:
The problem appears to be in DSServer.pas:TDSProviderDataModuleAdapter.AS_DataRequest. The local Data: OleVariant variable is being assigned DataStream.AsVariant. The problem is that DataStream is already an OleVariant, and Variants evidently don't know how to convert themselves to a Variant. :)

Seriously though, this results in Variants.pas:_DispInvoke being called against the DataStream variant. _DispInvoke doesn't know how to handle basic variant types (like varInteger and VarOleStr), so FindCustomVariantType fails to find a handler, and VarInvalidOp is called.

The problem is solved by changing this line in DSServer.pas from:
Data := DataStream.AsVariant;
to
Data := DataStream;

Or, alternatively, remove the local Data variable completely and change this line:

Result := FProviderDataModule.Providers[ProviderName].DataRequest(Data);
to
Result := FProviderDataModule.Providers[ProviderName].DataRequest(DataStream);

I did the latter and saved a copy in my project folder, rebuilt the server, and the error was resolved.
QC #: Date Reported: Area:
66318 9/2/2008 Database\Core VCL\Lookup
Description: Steps:
[QC Short Description]
DBExpress and ClientDataSet can't locate record with Chinese

QC Entry 66318
TDBXBugsTiburonBugsSuite.Native.DB.Test.exe connection=mssqlconnection -s:TestRaid_265035

-----

1. add sqlconnection, sqltabel, datasetprovider, clientdataset, datasource, and dbgrid into form.
2. connect them to an interbase db.
3. add edit and button to the form.
4. write code:
procedure TForm1.Button1Click(Sender: TObject);
begin
if ClientDataSet1.Locate('CHARFIELD', edit1.text, []) then
showmessage('Found');
end;

then run it.

I used a table with an unicode column.
I can see the date by DBGrid, and I can edit or insert it.
But, ClientDataSet just can locate English string. can't work with Greek, Hebrew, and Chinese.
I copy the string from DBGrid to Edit directly, but it can't work too.
QC #: Date Reported: Area:
67121 9/24/2008 Database\DBExpress
Description: Steps:
[QC Short Description]
D2009 dbExpress wrongly uses WideString where D20007 used String

[QC Description]
Our Oracle applications in D2007 use String for *all* fields of all tables and stored procedures, never WideString.

Just recompiling in D2009 *all* querys and stored procedures fail with type mismatch errors "expecting String actual WideString".

My guess is that D2009 is wrongly identifying our database as Unicode. I don't know how D2009 identifies if an Oracle10 database is Unicode-enabled or not, but in our case it must be doing it the wrong way.
I think the right way should be something like:

SELECT value FROM nls_database_parameters
where parameter = 'NLS_CHARACTERSET'

In our database that query returns WE8ISO8859P15. Unless that query returns UTF8, UTF16... you shouldn't force us to use Widestrings.

For us using Widestrings throughout all our applications, combined with QC 4790 is a real showstopper.

(An alternative solution would be to add a property SqlConnection.UseUnicode with values Always/Never/Default, so users could decide themselves if they want to use WideStrings).

Example of a query in D2007:

object ConexionOracle: TSQLConnection
ConnectionName = 'Oracledesarrollo'
DriverName = 'Oracle'
GetDriverFunc = 'getSQLDriverORACLE'
LibraryName = 'dbxora30.dll'
Params.Strings = (
'DriverName=Oracle'
'DriverUnit=DBXDynalink'

'DriverPackageLoader=TDBXDynalinkDriverLoader,DBXDynalinkDriver10' +
'0.bpl'

'DriverAssemblyLoader=Borland.Data.TDBXDynalinkDriverLoader,Borla' +
'nd.Data.DbxDynalinkDriver,Version=11.0.5000.0,Culture=neutral,Pu' +
'blicKeyToken=91d62ebb5b0d1b1b'

'MetaDataPackageLoader=TDBXOracleMetaDataCommandFactory,DbxReadOn' +
'lyMetaData100.bpl'

'MetaDataAssemblyLoader=Borland.Data.TDBXOracleMetaDataCommandFac' +
'tory,Borland.Data.DbxReadOnlyMetaData,Version=11.0.5000.0,Cultur' +
'e=neutral,PublicKeyToken=91d62ebb5b0d1b1b'
'DataBase=DESARROLLO'
'User_Name=xxxx'
'Password=xxxxx'
'BlobSize=-1'
'ErrorResourceFile='
'LocaleCode=0000'
'Oracle TransIsolation=ReadCommited'
'RowsetSize=20'
'OS Authentication=False'
'Multiple Transaction=False'
'Trim Char=False'
'Decimal Separator=,')
TableScope = [tsSynonym, tsTable, tsView]
VendorLib = 'OCI.DLL'
Left = 88
Top = 24
end
object QRoles: TSQLQuery
MaxBlobSize = -1
Params = <>
SQL.Strings = (
'SELECT ROLE'
'FROM SESSION_ROLES'
'')
SQLConnection = ConexionOracle
Left = 216
Top = 24
object QRolesROLE: TStringField
FieldName = 'ROLE'
Size = 30
end
end

As you can see, the field is returned as string. If I try to repeat that in D2009 I get this:


object SQLConnection1: TSQLConnection
ConnectionName = 'Oracledesarrollo'
DriverName = 'ORACLE'
GetDriverFunc = 'getSQLDriverORACLE'
LibraryName = 'dbxora.dll'
Params.Strings = (
'drivername=ORACLE'
'database=DESARROLLO'
'user_name=XXXXX'
'password=XXXXX'
'blobsize=-1'
'localecode=0000'
'oracle transisolation=ReadCommited'
'rowsetsize=20'
'os authentication=False'
'multiple transaction=False'
'trim char=False'
'decimal separator=,')
VendorLib = 'oci.dll'
Connected = True
Left = 128
Top = 80
end
object SQLQuery1: TSQLQuery
MaxBlobSize = -1
Params = <>
SQL.Strings = (
'SELECT ROLE'
'FROM SESSION_ROLES')
SQLConnection = SQLConnection1
Left = 216
Top = 80
object SQLQuery1ROLE: TWideStringField
FieldName = 'ROLE'
Required = True
Size = 30
end
end


QC Entry 67121
TDBXWeaverBugsSuite.Native.DB.Test.exe connection=mssqlconnection -s:TestRaid_265464

I can't know what you need to reproduce it because I don't know what mechanism dbExpress uses to decide if a database is Unicode.

I think it's very likely that if you create a Oracle10g database with characterset WE8ISO8859P15 and connect using this client:

http://download.oracle.com/otn/nt/instantclient/10204/instantclient-basic-win32-10.2.0.4.zip

you can reproduce it.
QC #: Date Reported: Area:
62992 6/5/2008 Database\DBExpress
Description: Steps:
[QC Short Description]
DBExpress Problems reading/writing Text/Binary Blob Data in Interbase 7 and Blackfish

[QC Description]
Interbase 7 problems:
Reading / Writing Text/Binary Blob Data

BlackfishSQL Problems
Writiing Binary Blobs

Oracle I have not tested?????


example data - working fine for MS-SQL DBExpress driver--->
Read Text Blob
Var
BStream : TStream;
Blobfeld: TField;
St: String;

st := dmodul.quauswahl.FieldByName(zs).asstring; //it seems to make problems with Interbase

alternative this will be OK for MSSQL und MySQL
Blobfeld := dmodul.quauswahl.FieldByName(zs);
BStream:= dmodul.Quauswahl.CreateBlobStream(blobfeld,
bmRead);
try
sz := BStream.Size;
if sz > 0 then
begin
BStream.Read( .
End;
finally
BStream.Free;
end;

Write Text Blob
Var SParM: TParams;
Rtftxt: String;
SParM := TParams.Create(self);

dmodul.quauswahl.Close;
dmodul.quauswahl.SQL.Clear;
dmodul.quauswahl.SQL.Add( Insert Into BlobTab(ID,BLOBFLD)VALUES(1,:par) );
SParM.CreateParam(ftBlob,'par',ptInput);
SParM.ParamByName('par').asstring := rtftxt; // for real text
//or with TMemo Field . SParM.ParamByName('par').Assign( TMemo(TMemoControl).lines);
dmodul.quauswahl.Params := SParM;
dmodul.quauswahl.ExecSQL; //Interbase have problems here
dmodul.quauswahl.Close;

Read Binary Blob
var
Stream: TStream;
query: TSQLquery;
fld: TField;
if not query.FieldByName(zs).isnull then //Interbase results NULL also for non NULL fields
begin
fld := query.FieldByName(zs);
Stream := query.CreateBlobStream(fld, bmRead); //Blackfish MySQL and MSSQL are OK; not Interbase
End;

Write Binary Blob
FStream := TMemoryStream.Create;
FStream.LoadFromFile (binfiledlg.FileName );
dmodul.quleer1.Close;
dmodul.quleer1.SQL.Clear;
dmodul.quleer1.SQL.Add( Insert Into BlobTab(ID,BLOBFLD)VALUES(1,:par) );
dmodul.quleer1.Params[p].DataType := ftBlob;
dmodul.quleer1.Params[p].SetBlobData(FStream.Memory,FStream.Size);
dmodul.quleer1.ExecSQL; //Blackfish and Interbase do not work error in DBXPlatform.pas row 249
dmodul.quleer1.Close;

QC Entry 62992
TDBXTiburonBugsSuite.Native.DB.Test.exe connection=BLACKFISHSQLCONNECTION -s:TestRaid_262742
QC #: Date Reported: Area:
10013 2/14/2008 Database\DBExpress
Description: Steps:
A multithreaded application using the DBX4 Informix driver + the DBXPool delegate will cause a "Connection Name in Use" Informix exception to be thrown.

The customer had previously been using the Luxena DBX driver with a 3rd party connection pool product from RemObjects and the error did not occur with that driver.

TDBXTiburonBugsSuite.Native.DB.Test.exe connection=informixconnection -s:TestRaid_257750
(run multiple times to ensure it doesn't fail)

===original===

I have attached a test case that reproduces the error most of the time.

It spawns multiple threads that open a connection to an Informix database, open a TSQLtable ad iterates through the rows and then closes the database at the end.

Please modify the connection to the database and choose a small table to iterate through. Please modify the column name on line 54 of IFxThreadUnit.pas and choose an alternative varchar column for your table.
QC #: Date Reported: Area:
66685 9/15/2008 11:10:30 AM Database\Data Aware Controls
Description: Steps:
[QC Short Description]
Missing multiplications with SizeOf(Char)

[QC Description]
I found an occurence of this sort of construct :

TStream.Write(UnicodeString[1], Length(UnicodeString));

As far as I understand, this misses the SizeOf(WideChar) multiplication.


After I hit the first occurance, I searched the whole sources folder for the
substring "[1], Length(", and look what I found :


D:\Temp\CodeGear_RAD Studio_6.0_source_3168.2\Win32\db\DBCtrls.pas
2019 if PasswordChar <> #0 then FillChar(S[1], Length(S), PasswordChar);

Search the whole sources folder for the substring "[1], Length("

Any occurance that uses arrays containing anything wider than a byte (like UnicodeString) should be fixed,
by adding a multiplication with SizeOf(elementtype).

QC #: Date Reported: Area:
51871 9/12/2007 Database\Drivers\InterBase
Description: Steps:
[QC Short Description]
"Invalid transaction object" with Interbase and some DDL statements

[QC Description]
Some DDL commands (alter table...) do not raise error until Commit is issued. But transaction is not completely released, so subsequent Rollback and TSQLConnection.Close/Free fail.
QC Entry 51871
TDBXWeaverBugsSuite.Native.DB.test.exe connection=ibconnection -s:TestRaid_266258

==or==

1: DBXTransaction:=SQLConnection1.BeginTransaction(TDBXIsolations.ReadCommitted);
2: try
3: SQLQuery1.ExecSQL();
4: SQLConnection1.CommitFreeAndNil(DBXTransaction);
5: except
6: SQLConnection1.RollbackFreeAndNil(DBXTransaction);
7: end;
8: SQLConnection1.Close;

SQLConnection1 should be some Interbase connection.
SQLQuery1 should contain:
alter table TABLE1 add
foreign key (FIELD1) references TABLE2 (FIELD2)

TABLE1.FIELD1 should contain values that do not exist in TABLE2.FIELD2, so the alter fails with "violation of FOREIGN KEY constraint "PK..." on table "TABLE2""

Problem is, that this does not raise an exception on line 3 (execsql), but on line 4 (commit). Subsequently rollback (line 6) fails and Close (line 8) also raises an exception.

Interbase only! Other databases/drivers always raise an exception during ExecSQL.
QC #: Date Reported: Area:
68752 11/10/2008 Database\TParams
Description: Steps:
[QC Short Description]
TParam.GetDataSize return incorrect value for Blob data type

[QC Description]
If we have a TParam object (Q) of ftBlob and we assign a string to it:

Q.Value := 'TEST';

Invoke Q.GetDataSize will return 4. But if invoke TParams.AsBytes it would return a TBytes of length 8.

This create a problem in procedure SetQueryProcParams of SqlExpr.pas:

procedure SetQueryProcParams(const Sender: TSQLConnection;
const Command: TDBXCommand; const Params: TParams; ProcParams: TList = nil);
begin
...
ftBlob, ftGraphic..ftTypedBinary,ftOraBlob,ftOraClob:
begin
Buffer := TDBByteBuffer.Create(Param.GetDataSize);
Buffer.Append(Param.AsBytes);
ExtractedBytes := Buffer.GetBytes;
Value.SetDynamicBytes(0, ExtractedBytes, 0, Length(ExtractedBytes));
end;
...
end;

Invoke "Buffer.Append(Param.AsBytes)" will always raise ERangeError exception with message 'CheckSpace'.

The reason is simple. Buffer is allocated 4 bytes of space but we later append 8 bytes of data to it and thus the ERangeError was raised.

I am not sure if this is a bug or it is by design. Should we let the program decide the encoding of string data store into a blob field? If we let the program decide, the blob field data may not accessible by legacy program that always treat the blob field string data as ANSI encoding.
QC Entry 68752
TDBXWeaverBugsSuite.Native.DB.Test.exe connection=mssqlconnection -s:TestRaid_266480

Run the following in Delphi 2009:

var P: TParams;
Q: TParam;
i, j: integer;
begin
P := TParams.Create;
try
Q := P.CreateParam(ftBlob, 'Blob', ptInput);
Q.Value := 'TEST';

i := Q.GetDataSize;
j := Length(Q.AsBytes);
finally
P.Free;
end;
end;

variable i return 4
variable j return 8
QC #: Date Reported: Area:
69634 12/5/2008 Database\DataSnap\Server
Description: Steps:
[QC Short Description]
Datasnap error

[QC Description]
I see no attention to this problem since the report of Christopher on sep.

I’m testing D2009 and tried to enhance the Datasnap and thin client solutions video at:
http://dn.codegear.com/article/38587

and the execution stopped with the “unexpected metadata type” error. Digging into the DB & DBXDBReaders units I found some incomplete functions:

Function TDBXDataSetTable.GetColumns sets the valueType var, and sends to ToDataType function in the DBXDBReaders unit. The case/of list there is missing few types options of the TFieldType type, and returns error when encountering these types, for example autoinc, currency etc.
QC Entry 69634
DataSnapAccess.Native.DB.Test.exe connection=asaconnection -s:ComponentDatasetTest
QC #: Date Reported: Area:
68685 11/7/2008 Database\dbExpressCore
Description: Steps:
[QC Short Description]
TDBXDriverRegistry.UnregisterDriverClass is malfunction

[QC Description]
A method "TDBXDriverRegistry.UnregisterDriverClass" in unit DBXCommon.pas isn't programming correctly:

class procedure TDBXDriverRegistry.UnregisterDriverClass(DriverName: String);
var
Index: Integer;
begin
if DBXDriverRegistry.FDriverClasses.Find(DriverName, Index) then
begin
DBXDriverRegistry.FDriverClasses.Delete(Index);
end;
end;

FDriverClasses.Find will only function well if the string list is sorted. However, FDriverClasses never get sorted.

QC Entry 68685
TDBXTiburonBugsSuite.Native.DB.Test.exe connection=ibconnection -s:TestRaid_267173

==or==

Run the following code to show the error:

var S: TStringList;
begin
// Using memory connection factory
TDBXConnectionFactory.SetConnectionFactory(TDBXMemoryConnectionFactory.Create);

// Register driver classes
TDBXDriverRegistry.RegisterDriverClass('C', TDBXDynalinkDriverNative);
TDBXDriverRegistry.RegisterDriverClass('B', TDBXDynalinkDriverNative);
TDBXDriverRegistry.RegisterDriverClass('A', TDBXDynalinkDriverNative);

// Display Registered Classes
S := TStringList.Create;
try
TDBXConnectionFactory.GetConnectionFactory.GetRegisteredDriverNames(S);
ShowMessage(S.Text);
finally
S.Free;
end;

// Unregister driver classes
TDBXDriverRegistry.UnregisterDriverClass('C');
TDBXDriverRegistry.UnregisterDriverClass('B');
TDBXDriverRegistry.UnregisterDriverClass('A');

// Display Registered Classes again (expected empty)
S := TStringList.Create;
try
TDBXConnectionFactory.GetConnectionFactory.GetRegisteredDriverNames(S);
ShowMessage(S.Text);
finally
S.Free;
end;
end;

The example purposely register the driver name in unsorted manner to show the problem. If the name are
registered in order (e.g.: A, B, C), it works fine.
QC #: Date Reported: Area:
69826 12/11/2008 Database\DBExpress
Description: Steps:
[QC Short Description]
AV when Connection Failed using DBX with MySQL5.0.

[QC Description]
Access Violation occurs when Connection Failed using DBX with MySQL5.0.

added by Ssyop
<<<<<<<<<<
AV occurs when 'ServerCharSet' parameter is set to utf8, sjis etc...
If is it blank, AV does not occur.
>>>>>>>>>>
QC Entry 69826
TDBXWeaverBugsSuite.native.db.test.exe connection=mysqlconnection_utf8 -s:oTestRaid_267326

1) Set wrong Params 'HostName' or 'Database' or 'User_Name' or 'Password' on SQLConnection1.
2) SQLConnection1.Connected := True;
3) Error message:

Access violation at address 1000BC6A in module 'libmysql.dll'. Read of address 00000358.
QC #: Date Reported: Area:
67233 9/26/2008 Database\dbExpressCore
Description: Steps:
[QC Short Description]
AutoUnloadDriver is not working as is

[QC Description]
In Delphi 2009 DBX4 framework, there is a new property TDBXPropertyNames.AutoUnloadDriver. This is state in the DBXCommon.pas about the property:

"If set to true, dynalink drivers will automatically unload their dll, when there are no longer any open connections that use the driver."

I expect setting the property to true will make the database connection library to be unloaded when connection is closed.

However, I find no way to activate this function thru current DBX4 implementation.

After tracing the DBX source code, I found the cause of the problem. The Dynalink Driver class has the following constructor:

constructor TDBXDynalinkDriver.Create(DBXDriverDef: TDBXDriverDef; DBXDriverLoader: TDBXDynalinkDriverCommonLoaderClass);
begin
inherited Create(DBXDriverDef);
FDriverLoaderClass := DBXDriverLoader;
// '' makes this the default command factory.
//
AddCommandFactory('', CreateDynalinkCommand);
if (DriverProperties = nil) or not DriverProperties.GetBoolean(TDBXPropertyNames.AutoUnloadDriver) then
CacheUntilFinalization;
end;

To make AutoUnloadDriver work as it should, the clue is to avoid invoke CacheUntilFinalization in the constructor. In order to do that, we must make sure DriverProperties is not nil and AutoUnloadDriver property has value "True".
QC Entry 67233
1. Create a new VCL application 2. Drop a TSQLConnection (SQLConnection1) instance and define properties for Interbase connection. To enable AutoUnloadDriver, add a new param (AutoUnloadDriver=True) into SQLConnection.Params 3. Drop a TButton (Button1) and write OnClick event: SQLConnection1.Open; 4. Drop another TButton (Button2) and write OnClick event: SQLConnection1.Close; 5. Run the application in debug mode. Make sure you bring out a "Event Log" debug window to trace how the database connection dll is loaded and unloaded. 6. Press Button1 to open the database connection, the Event Log windows will show database connection library has loaded. 7. Press Button2 to Close the database connection, the event log windows show nothing about the database connection library. 8. Close the application will only unload the database connection library.
QC #: Date Reported: Area:
70591 1/17/2009 Database\DBExpress\TSQLConnection
Description: Steps:
[QC Short Description]
SQLConnection Problems in Update3

[QC Description]
Th SQLConnection has a backward problem again. No driver options again .
I´m using Vista x64 SP2 ...
QC Entry 70591
Steps to reproduce : - Create a new application - Put a SQLConnection - Change Driver property in Object Inspector - Click on + Nothing appear ... I´m using Vista x64 SP2 ...
QC #: Date Reported: Area:
67210 9/26/2008 Database\dbExpressCore
Description: Steps:
[QC Short Description]
TSQLConnection Driver property and DBX .ini file deployment

[QC Description]
dbExpress applications compiled with Delphi 2009 now require the presence of the dbxdrivers.ini and dbxconnections.ini files (either in the current directory or with information specified in the registry?).

It used to be possible to deploy applications compiled with Delphi without the dbxdrivers.ini and dbxconnections.ini (and this should still be possible, of course).
QC Entry 67210
Produce a VCL Forms application with dbExpress (a TSQLConnection component pointing to some database is enough) and try to deploy it to a clean machine - without Delphi on it.



Server Response from: ETNASC01