I then went and modified my own test case, and the one reported in QC and noticed that both of these test cases still exhibited the problem in D2005. I talked to a couple of friends in Scotts Valley, and they confirmed the behavior as still being present in Win32 in D2005. So, it turns out that the fix only made it to the VCL.NET side of things. At least that source is similar enough to figure out what's going on.
The problem exists in TDataset.GetCalcFields. Take a look at the VCL.NET implementation in D2005 for the complete code. However, I still needed to get the fix into our codebase, and we won't be upgrading everything to D2005 for a little bit yet. We also can't just patch the VCL in the DB.pas unit since we are using runtime packages on our app servers in order to pass VCL components around.
With all of these requirements in place, I set out to create a descendant of TSQLQuery and override GetCalcFields. This turned out to be problematic, however, due to the fixed code's need to set the FEOF private variable in TDataset. I realized that the EOF property is read-only and that the backing field is private, so I used Hallvard's Hack #1. This works absolutely flawlessly, and I now have the fix isolated to one place so that when we upgrade to D2005, I can simply remove this new component in the handful of places that it gets used.
Here is the implementation code that I finally came up with:
type TDatasetEx = class(TDataset) published property EOF; end; procedure TDRMSQLQuery.SetEOF(Value: boolean); begin PBoolean(Integer(Self) + (Integer(GetPropInfo(TDatasetEx, 'EOF').GetProc) and $00FFFFFF))^ := Value; end; {$WARNINGS OFF} // We are guaranteed that the only time we both set and use eofBak is when // State = dsInactive. Therefore, we don't care about the warning. procedure TDRMSQLQuery.GetCalcFields(Buffer: PChar); var eofBak: Boolean; begin if (State = dsInactive) then begin eofBak := EOF; SetEOF(False); end; try inherited GetCalcFields(Buffer); finally if (State = dsInactive) then SetEOF(eofBak); end; end;
Notes:
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.