mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-02-04 05:34:53 +01:00
* fixes Mantis #14730 dealing with oldvalue=null
git-svn-id: trunk@19267 -
This commit is contained in:
parent
08c97e81bf
commit
448e3db450
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2006,6 +2006,7 @@ packages/fcl-db/tests/testsqlfiles.lpr svneol=native#text/plain
|
||||
packages/fcl-db/tests/testsqlscanner.lpi svneol=native#text/plain
|
||||
packages/fcl-db/tests/testsqlscanner.lpr svneol=native#text/plain
|
||||
packages/fcl-db/tests/testsqlscript.pas svneol=native#text/plain
|
||||
packages/fcl-db/tests/testwherenull.lpr svneol=native#text/plain
|
||||
packages/fcl-db/tests/toolsunit.pas svneol=native#text/plain
|
||||
packages/fcl-db/tests/xmlxsdexporttestcase1.pas svneol=native#text/plain
|
||||
packages/fcl-extra/Makefile svneol=native#text/plain
|
||||
|
||||
@ -1544,17 +1544,17 @@ Procedure TCustomSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind);
|
||||
|
||||
var FieldNamesQuoteChars : TQuoteChars;
|
||||
|
||||
procedure InitialiseModifyQuery(var qry : TCustomSQLQuery; aSQL: String);
|
||||
function InitialiseModifyQuery(var qry : TCustomSQLQuery): TCustomSQLQuery;
|
||||
|
||||
begin
|
||||
qry := TCustomSQLQuery.Create(nil);
|
||||
with qry do
|
||||
begin
|
||||
ParseSQL := False;
|
||||
DataBase := Self.DataBase;
|
||||
Transaction := Self.Transaction;
|
||||
SQL.text := aSQL;
|
||||
end;
|
||||
if not assigned(qry) then
|
||||
begin
|
||||
qry := TCustomSQLQuery.Create(nil);
|
||||
qry.ParseSQL := False;
|
||||
qry.DataBase := Self.DataBase;
|
||||
qry.Transaction := Self.Transaction;
|
||||
end;
|
||||
Result:=qry;
|
||||
end;
|
||||
|
||||
procedure UpdateWherePart(var sql_where : string;x : integer);
|
||||
@ -1562,8 +1562,11 @@ var FieldNamesQuoteChars : TQuoteChars;
|
||||
begin
|
||||
if (pfInKey in Fields[x].ProviderFlags) or
|
||||
((FUpdateMode = upWhereAll) and (pfInWhere in Fields[x].ProviderFlags)) or
|
||||
((FUpdateMode = UpWhereChanged) and (pfInWhere in Fields[x].ProviderFlags) and (fields[x].value <> fields[x].oldvalue)) then
|
||||
sql_where := sql_where + '(' + FieldNamesQuoteChars[0] + fields[x].FieldName + FieldNamesQuoteChars[1] + '= :"' + 'OLD_' + fields[x].FieldName + '") and ';
|
||||
((FUpdateMode = UpWhereChanged) and (pfInWhere in Fields[x].ProviderFlags) and (Fields[x].Value <> Fields[x].OldValue)) then
|
||||
if Fields[x].OldValue = NULL then
|
||||
sql_where := sql_where + FieldNamesQuoteChars[0] + Fields[x].FieldName + FieldNamesQuoteChars[1] + ' is null and '
|
||||
else
|
||||
sql_where := sql_where + '(' + FieldNamesQuoteChars[0] + Fields[x].FieldName + FieldNamesQuoteChars[1] + '= :"' + 'OLD_' + Fields[x].FieldName + '") and ';
|
||||
end;
|
||||
|
||||
function ModifyRecQuery : string;
|
||||
@ -1632,6 +1635,7 @@ var FieldNamesQuoteChars : TQuoteChars;
|
||||
end;
|
||||
|
||||
var qry : TCustomSQLQuery;
|
||||
s : string;
|
||||
x : integer;
|
||||
Fld : TField;
|
||||
|
||||
@ -1639,37 +1643,25 @@ begin
|
||||
FieldNamesQuoteChars := TSQLConnection(DataBase).FieldNameQuoteChars;
|
||||
|
||||
case UpdateKind of
|
||||
ukModify : begin
|
||||
if not assigned(FUpdateQry) then
|
||||
begin
|
||||
if (trim(FUpdateSQL.Text)<> '') then
|
||||
InitialiseModifyQuery(FUpdateQry,FUpdateSQL.Text)
|
||||
else
|
||||
InitialiseModifyQuery(FUpdateQry,ModifyRecQuery);
|
||||
end;
|
||||
qry := FUpdateQry;
|
||||
end;
|
||||
ukInsert : begin
|
||||
if not assigned(FInsertQry) then
|
||||
begin
|
||||
if (trim(FInsertSQL.Text)<> '') then
|
||||
InitialiseModifyQuery(FInsertQry,FInsertSQL.Text)
|
||||
else
|
||||
InitialiseModifyQuery(FInsertQry,InsertRecQuery);
|
||||
end;
|
||||
qry := FInsertQry;
|
||||
s := trim(FInsertSQL.Text);
|
||||
if s = '' then s := InsertRecQuery;
|
||||
qry := InitialiseModifyQuery(FInsertQry);
|
||||
end;
|
||||
ukModify : begin
|
||||
s := trim(FUpdateSQL.Text);
|
||||
if (s='') and (not assigned(FUpdateQry) or (UpdateMode<>upWhereKeyOnly)) then //first time or dynamic where part
|
||||
s := ModifyRecQuery;
|
||||
qry := InitialiseModifyQuery(FUpdateQry);
|
||||
end;
|
||||
ukDelete : begin
|
||||
if not assigned(FDeleteQry) then
|
||||
begin
|
||||
if (trim(FDeleteSQL.Text)<> '') then
|
||||
InitialiseModifyQuery(FDeleteQry,FDeleteSQL.Text)
|
||||
else
|
||||
InitialiseModifyQuery(FDeleteQry,DeleteRecQuery);
|
||||
end;
|
||||
qry := FDeleteQry;
|
||||
s := trim(FDeleteSQL.Text);
|
||||
if (s='') and (not assigned(FDeleteQry) or (UpdateMode<>upWhereKeyOnly)) then
|
||||
s := DeleteRecQuery;
|
||||
qry := InitialiseModifyQuery(FDeleteQry);
|
||||
end;
|
||||
end;
|
||||
if (qry.SQL.Text<>s) and (s<>'') then qry.SQL.Text:=s; //assign only when changed, to avoid UnPrepare/Prepare
|
||||
assert(qry.sql.Text<>'');
|
||||
with qry do
|
||||
begin
|
||||
|
||||
@ -32,6 +32,8 @@ type
|
||||
procedure SeveralEditsChange(ADataset: TCustomBufDataset);
|
||||
procedure DeleteAllChange(ADataset: TCustomBufDataset);
|
||||
procedure DeleteAllInsertChange(ADataset: TCustomBufDataset);
|
||||
procedure NullInsertChange(ADataset: TCustomBufDataset);
|
||||
procedure NullEditChange(ADataset: TCustomBufDataset);
|
||||
protected
|
||||
procedure SetUp; override;
|
||||
procedure TearDown; override;
|
||||
@ -53,6 +55,7 @@ type
|
||||
procedure SeveralEditsApplUpd;
|
||||
procedure DeleteAllApplUpd;
|
||||
procedure DeleteAllInsertApplUpd;
|
||||
procedure NullInsertUpdateApplUpd;
|
||||
|
||||
procedure TestBasicsXML;
|
||||
procedure TestSimpleEditXML;
|
||||
@ -99,6 +102,7 @@ begin
|
||||
if Inserts then
|
||||
begin
|
||||
ChangedDs := TSQLDBConnector(DBConnector).Query;
|
||||
ChangedDs.Close;
|
||||
TSQLQuery(ChangedDS).SQL.Text:='SELECT * FROM FPDEV WHERE (ID < 16) or (ID>100) ORDER BY ID';
|
||||
|
||||
OrgDs.IndexFieldNames:='ID';
|
||||
@ -274,14 +278,43 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestBufDatasetStreams.SetUp;
|
||||
procedure TTestBufDatasetStreams.NullInsertChange(ADataset: TCustomBufDataset);
|
||||
begin
|
||||
DBConnector.StartTest;
|
||||
with ADataset do
|
||||
begin
|
||||
AssertTrue(Locate('ID',11,[]));
|
||||
Delete; //11
|
||||
Delete; //12
|
||||
Delete; //13
|
||||
Delete; //14
|
||||
Append;
|
||||
FieldByName('ID').AsInteger:=11;
|
||||
//FieldByName('NAME').Clear;
|
||||
Post;
|
||||
AppendRecord([12,'AfterNull']);
|
||||
AppendRecord([13,null]);
|
||||
AppendRecord([14,'AfterNull']);
|
||||
//Append; Post;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestBufDatasetStreams.TearDown;
|
||||
procedure TTestBufDatasetStreams.NullEditChange(ADataset: TCustomBufDataset);
|
||||
var i: integer;
|
||||
begin
|
||||
DBConnector.StopTest;
|
||||
//depends on procedure TTestBufDatasetStreams.NullInsertChange
|
||||
if ADataSet is TSQLQuery then
|
||||
with ADataset as TSQLQuery do
|
||||
begin
|
||||
AssertTrue(Locate('ID',11,[]));
|
||||
for i:=11 to 14 do
|
||||
begin
|
||||
Edit;
|
||||
FieldByName('NAME').AsString:='TestName'+inttostr(i);
|
||||
Post;
|
||||
Next;
|
||||
end;
|
||||
UpdateMode:=upWhereAll; //test when also null fields will be in where
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestBufDatasetStreams.TestSimpleEditCancelUpd;
|
||||
@ -459,6 +492,24 @@ begin
|
||||
TestChangesApplyUpdates(@DeleteAllInsertChange, False);
|
||||
end;
|
||||
|
||||
procedure TTestBufDatasetStreams.NullInsertUpdateApplUpd;
|
||||
begin
|
||||
TestChangesApplyUpdates(@NullInsertChange, True);
|
||||
TestChangesApplyUpdates(@NullEditChange, True);
|
||||
end;
|
||||
|
||||
|
||||
procedure TTestBufDatasetStreams.SetUp;
|
||||
begin
|
||||
DBConnector.StartTest;
|
||||
end;
|
||||
|
||||
procedure TTestBufDatasetStreams.TearDown;
|
||||
begin
|
||||
DBConnector.StopTest;
|
||||
end;
|
||||
|
||||
|
||||
initialization
|
||||
if uppercase(dbconnectorname)='SQL' then
|
||||
RegisterTestDecorator(TDBBasicsTestSetup, TTestBufDatasetStreams);
|
||||
|
||||
85
packages/fcl-db/tests/testwherenull.lpr
Normal file
85
packages/fcl-db/tests/testwherenull.lpr
Normal file
@ -0,0 +1,85 @@
|
||||
program testWhereNULL;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||
cthreads,
|
||||
{$ENDIF}{$ENDIF}
|
||||
Classes, SysUtils,
|
||||
db, sqldb, sqlite3conn, variants;
|
||||
|
||||
|
||||
var
|
||||
Conn: TSQLite3Connection;
|
||||
Tran: TSQLTransaction;
|
||||
Q: TSQLQuery;
|
||||
|
||||
sql: string;
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
Conn:=TSQLite3Connection.Create(nil);
|
||||
Conn.DatabaseName:='test.db';
|
||||
|
||||
Tran:=TSQLTransaction.Create(nil);
|
||||
Tran.DataBase:=Conn;
|
||||
|
||||
Q:=TSQLQuery.Create(nil);
|
||||
Q.DataBase:=Conn;
|
||||
|
||||
Conn.Open;
|
||||
writeln('Connected');
|
||||
|
||||
Conn.ExecuteDirect('CREATE TEMPORARY TABLE t (int_field INT, string_field VARCHAR(30))');
|
||||
writeln('Temporary table created');
|
||||
|
||||
Q.SQL.Text:='SELECT * FROM t';
|
||||
Q.UpdateMode:=upWhereAll; // <-- UpdateMode is upWhereAll or upWhereCahnged
|
||||
Q.Open;
|
||||
Q.AppendRecord([NULL,'a']);
|
||||
Q.AppendRecord([2,'c']);
|
||||
Q.ApplyUpdates;
|
||||
Q.Close;
|
||||
|
||||
writeln('1. Bug: second row has instead of 2 in first column NULL');
|
||||
Q.Open;
|
||||
Q.Next;
|
||||
writeln('Value of ', Q.Fields[0].FieldName,' is: ', Q.Fields[0].AsString, ' expected: 2');
|
||||
Q.Close;
|
||||
|
||||
writeln;
|
||||
writeln('2. Case update of record, where some value is null (upWhereAll or upWhereChanged)');
|
||||
Q.Open;
|
||||
Q.Edit;
|
||||
Q.Fields[1].AsString:='b';
|
||||
Q.Post;
|
||||
Q.ApplyUpdates;
|
||||
Q.Close;
|
||||
|
||||
Q.Open;
|
||||
writeln('Value of ', Q.Fields[1].FieldName,' is: ', Q.Fields[1].AsString,' expected: b');
|
||||
Q.Close;
|
||||
|
||||
writeln;
|
||||
writeln('3. Case delete of record, where some value is null (upWhereAll or upWhereChanged)');
|
||||
Q.Open;
|
||||
Q.Delete;
|
||||
Q.ApplyUpdates;
|
||||
Q.Close;
|
||||
|
||||
Q.Open;
|
||||
writeln('Number of rows: ', Q.RecordCount, ' expected: 1');
|
||||
Q.Close;
|
||||
|
||||
//END
|
||||
Tran.Commit;
|
||||
Conn.Close;
|
||||
|
||||
Q.Free;
|
||||
Tran.Free;
|
||||
Conn.Free;
|
||||
writeln('End. Press any key');
|
||||
readln;
|
||||
end.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user