Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Database/Data Access Controls    [ Add a report in this area ]  
Report #:  6142   Status: Closed
ClientDataSet.Locate('LargeIntField', 1, []) causes "constant 1 is not correct type"
Project:  Delphi Build #:  4.453
Version:    7.0 Submitted By:   Tom Birch
Report Type:  Basic functionality failure Date Reported:  10/7/2003 1:20:55 PM
Severity:    Serious / Highly visible problem Last Updated: 5/10/2004 5:19:03 PM
Platform:    All platforms Internal Tracking #:  
Resolution: Duplicate  Resolved in Build: : 7.0.8.1
Duplicate of:  3496
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description
TFilterExpr.PutConstant in DBCommon does not support LargeInt Constants.
Steps to Reproduce:
Add ClientDataSet
CreateDataSet with a LargeInt Field
Try to Locate LargeInt Field
Workarounds
None
Attachment
None
Comments

Brad White at 1/21/2004 9:28:45 AM -
This problem is also in D6, sp 2, RTL 3.
And it is not specific to ClientDataSets.
It affects any TDataSet that uses Locate,
SetRange, or FindKey against a LargeInt field.

All of our tables are in SQL Server, they
all have Int64 identifiers.  We use queries
to pull segments into ClientDataSets.
That all works.  It only fails when we
want to find a specific record in the table.

FindKey causes a runtime error when called
with Int64 key values.  It happens when the
dataset tries to assign the key value to a key
field.  TField.AssignValues does not accept
int64 values and throws the exception.

The TField is actually a Largeintfield, so if
it had overridden AssignValues, everything
would have worked, but it doesn't override it.

Here is the offending Code:
procedure TField.AssignValue(const Value: TVarRec);
begin
  with Value do
    case VType of
      vtInteger:
        AsInteger := VInteger;
      vtBoolean:
        AsBoolean := VBoolean;
      vtChar:
        AsString := VChar;
      vtExtended:
        AsFloat := VExtended^;
      vtString:
        AsString := VString^;
      vtPointer:
        if VPointer <> nil then Error;
      vtPChar:
        AsString := VPChar;
      vtObject:
        if (VObject = nil) or (VObject is TPersistent) then
          Assign(TPersistent(VObject))
        else
          Error;
      vtAnsiString:
        AsString := string(VAnsiString);
      vtCurrency:
        AsCurrency := VCurrency^;
      vtVariant:
        if not VarIsClear(VVariant^) then AsVariant := VVariant^;
      vtWideString:
        AsString := WideString(VWideString);
    else
      Error;
    end;
end;

Compare to this list in
Source\RTL\Sys\System.pas|{ TVarRec.VType values }
  vtInteger    = 0;
  vtBoolean    = 1;
  vtChar       = 2;
  vtExtended   = 3;
  vtString     = 4;
  vtPointer    = 5;
  vtPChar      = 6;
  vtObject     = 7;
*  vtClass      = 8;
*  vtWideChar   = 9;
*  vtPWideChar  = 10;
  vtAnsiString = 11;
  vtCurrency   = 12;
  vtVariant    = 13;
*  vtInterface  = 14;
  vtWideString = 15;
*  vtInt64      = 16;

* marks the variant types that are missing in
the AssignValue code.  Class and Interface make
sense to not be included, but clearly the rest
should be valid.


Dave Rowntree at 1/22/2004 9:04:40 AM -
Your comments are not valid for the CDS.Locate problem described in this report.

The VCL code you site is not the code causing the problem associated with CDS.Locate.

Brad White at 1/22/2004 2:51:06 PM -
You are correct.

We had traced into the FindKey failure.
Based on where it failed I expected
Locate and SetRange to also fail, which
they did.

In fact,
ClientDataSet.Locate and ClientDataSet.Filter
both fail in TFilterExpr.PutConstant in DBCommon.

ClientDataSet.FindKey and ClientDataSet.SetRange
both fail in TField.AssignValue in DB.

So, that was my mistake.

As an aside, TADODataSet has very similar looking
code for Locate but succeeds.
I haven't tested the other methods, but I still expect
ADODataSet.FindKey and ADODataSet.SetRange
to fail.

Server Response from: CODE1