View Issue Details

IDProjectCategoryView StatusLast Update
0018672FPCDatabasepublic2018-07-18 14:23
ReporterAlexander S. KleninAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product VersionProduct Build 
Target Version3.2.0Fixed in Version3.1.1 
Summary0018672: Renaming dataset fails disgracefully when one of the field nat not be auto-renamed
DescriptionTDataset.SetName procedure auto-renames fields to prefix
them with the new dataset name instead of old.
If one of the fields fails to change name (most probably
because it will lead to a duplicate),
the exception is thrown and the whole renaming aborts.
This results in two problems:
1) Auto-renamings stops, even if only one field can not be renamed,
with half of fields renamed and half not renamed.
2) When using Lazaurs, Object Inspector thinks that renaming failed
and does not update, leading user to believe that the dataset was not
renamed, when in fact it was.

I suggest to catch EComponentError, collect failed fields,
and rethrow the exception at the end of procedure.
Then, Lazarus may be modified to catch that exception
and update the interface despite displaying the error.
TagsNo tags attached.
Fixed in Revision39470
FPCOldBugId
FPCTarget
Attached Files
  • field_name_rename.patch (1,531 bytes)
    Index: src/base/dataset.inc
    ===================================================================
    --- src/base/dataset.inc	(revision 31146)
    +++ src/base/dataset.inc	(working copy)
    @@ -1337,31 +1337,32 @@
     end;
     
     procedure TDataSet.SetName(const Value: TComponentName);
    -
    -function CheckName(const FieldName: string): string;
    -var i,j: integer;
    -begin
    -  Result := FieldName;
    -  i := 0;
    -  j := 0;
    -  while (i < Fields.Count) do begin
    -    if Result = Fields[i].FieldName then begin
    -      inc(j);
    -      Result := FieldName + IntToStr(j);
    -    end else Inc(i);
    +  function CheckName(const FieldName: string): string;
    +  var i,j: integer;
    +  begin
    +    Result := FieldName;
    +    i := 0;
    +    j := 0;
    +    while (i < Fields.Count) do begin
    +      if Result = Fields[i].Name then begin
    +        inc(j);
    +        Result := FieldName + IntToStr(j);
    +        i := 0;
    +      end
    +      else
    +        inc(i);
    +    end;
       end;
    -end;
     var i: integer;
    -    nm: string;
    -    old: string;
    +    OldName, OldFieldName: string;
     begin
       if Self.Name = Value then Exit;
    -  old := Self.Name;
    +  OldName := Self.Name;
       inherited SetName(Value);
       if (csDesigning in ComponentState) then
         for i := 0 to Fields.Count - 1 do begin
    -      nm := old + Fields[i].FieldName;
    -      if Copy(Fields[i].Name, 1, Length(nm)) = nm then
    +      OldFieldName := OldName + Fields[i].FieldName;
    +      if Copy(Fields[i].Name, 1, Length(OldFieldName)) = OldFieldName then
             Fields[i].Name := CheckName(Value + Fields[i].FieldName);
         end;
     end;
    
    field_name_rename.patch (1,531 bytes)

Activities

LacaK

2015-06-24 12:57

developer   ~0084698

Last edited: 2015-06-25 10:43

View 2 revisions

When I look at procedure TDataSet.SetName there is function CheckName, which should detect duplicate field names and alter field name to be unique.
But there may be situation, where duplicate field name is not detected (I am not sure if it is bug then?) ... counter "i" should be set to 0 after Result changes so new Result will be checked against all fields again.

Patch, which will make renaming more safe is attached.

LacaK

2015-06-25 10:41

developer  

field_name_rename.patch (1,531 bytes)
Index: src/base/dataset.inc
===================================================================
--- src/base/dataset.inc	(revision 31146)
+++ src/base/dataset.inc	(working copy)
@@ -1337,31 +1337,32 @@
 end;
 
 procedure TDataSet.SetName(const Value: TComponentName);
-
-function CheckName(const FieldName: string): string;
-var i,j: integer;
-begin
-  Result := FieldName;
-  i := 0;
-  j := 0;
-  while (i < Fields.Count) do begin
-    if Result = Fields[i].FieldName then begin
-      inc(j);
-      Result := FieldName + IntToStr(j);
-    end else Inc(i);
+  function CheckName(const FieldName: string): string;
+  var i,j: integer;
+  begin
+    Result := FieldName;
+    i := 0;
+    j := 0;
+    while (i < Fields.Count) do begin
+      if Result = Fields[i].Name then begin
+        inc(j);
+        Result := FieldName + IntToStr(j);
+        i := 0;
+      end
+      else
+        inc(i);
+    end;
   end;
-end;
 var i: integer;
-    nm: string;
-    old: string;
+    OldName, OldFieldName: string;
 begin
   if Self.Name = Value then Exit;
-  old := Self.Name;
+  OldName := Self.Name;
   inherited SetName(Value);
   if (csDesigning in ComponentState) then
     for i := 0 to Fields.Count - 1 do begin
-      nm := old + Fields[i].FieldName;
-      if Copy(Fields[i].Name, 1, Length(nm)) = nm then
+      OldFieldName := OldName + Fields[i].FieldName;
+      if Copy(Fields[i].Name, 1, Length(OldFieldName)) = OldFieldName then
         Fields[i].Name := CheckName(Value + Fields[i].FieldName);
     end;
 end;
field_name_rename.patch (1,531 bytes)

Michael Van Canneyt

2018-07-18 14:23

administrator   ~0109555

Fixed using improved patch of Laco

Issue History

Date Modified Username Field Change
2011-02-02 16:31 Alexander S. Klenin New Issue
2011-02-02 16:31 Alexander S. Klenin Status new => assigned
2011-02-02 16:31 Alexander S. Klenin Assigned To => Joost van der Sluis
2015-06-24 12:57 LacaK Note Added: 0084698
2015-06-25 10:41 LacaK File Added: field_name_rename.patch
2015-06-25 10:43 LacaK Note Edited: 0084698 View Revisions
2018-07-18 14:23 Michael Van Canneyt Fixed in Revision => 39470
2018-07-18 14:23 Michael Van Canneyt Note Added: 0109555
2018-07-18 14:23 Michael Van Canneyt Status assigned => resolved
2018-07-18 14:23 Michael Van Canneyt Fixed in Version => 3.1.1
2018-07-18 14:23 Michael Van Canneyt Resolution open => fixed
2018-07-18 14:23 Michael Van Canneyt Assigned To Joost van der Sluis => Michael Van Canneyt
2018-07-18 14:23 Michael Van Canneyt Target Version => 3.2.0