Access Violation when ApplyUpdates in BeforePost succeeds but TDataSet.Post fails

Hello,

I’ve been tracking an AV and I found the following issue:

There was a field in our table that was set as required in the schema, but was not actually required in the database.

If I leave the field empty, the InternalApplyUpdates in the InternalBeforePost of the TDADataTable will succeed, saving the changes, but then in the InternalPost it fails, because TDataset.Post fails due to the required field. So far this is ok.

But if you try to post the same record again, you get an AV. The TDADataTable.InternalBeforePost will call GetDelta.EndChange but in this method, lRecord^.CurrentChange is now nil, which causes an AV.

I think this is a very particular case, but the record should not be left in such an inconsistent state that it causes an AV.

Thanks,
Arturo.

We have a TDAMemDataTable descendant which checks for required fields before calling TDAMemDataTable.InternalBeforePost:

procedure TBhsDAMemDataTable.CheckRequiredFields;
resourcestring
  stFieldMustHaveAValue = 'The field ''%s'' must have a value!';
var
  ix: Integer;
begin
  for ix := 0 to (Fields.Count - 1) do
    if (Fields[ix].Required) and (Fields[ix].IsNull) then
    begin
      Dataset.Fields[ix].FocusControl;
      raise EDatabaseError.CreateFmt(stFieldMustHaveAValue, [Trim(Fields[ix].DisplayLabel)]);
    end;
end;

procedure TBhsDAMemDataTable.InternalBeforePost(Sender: TDataset);
begin
  CheckRequiredFields;
  inherited; // Call inherited after checking for required fields
end;

In this case, we were using TDAMemDataTable and not our modified descendant, and that’s why we were getting the AV, but I wanted to add this in case this is useful: I think the required fields in TDAMemDataTable should be checked BEFORE calling apply updates, not afterward (as it is now, because required fields are checked in the InternalPost method).

However, even with this change, it is important that the table doesn’t try to post a delta it already posted, but was left as an active delta because of the error in TDataset.Post.

Arturo.

Hi,

can you create a simple testcase that reproduces this case, pls?
you can attach it here or drop email to support@