Replace not done after a previous replace with searched string not found

Replace not done after a previous replace with searched string not found

1
NewbieNewbie
1

    Apr 30, 2010#1

    I was on 16.00.0.1032 when I read Not found search string of a replace exits macro with UE 16.00.0.1038, fixed with 16.00.0.1040.

    I was having problems with a macro skipping commands if a Find/Replace found no entries. I upgraded to 16.00.0.1040 but still see the same behavior.

    I'm using Perl Regexp and have the following construct in a SQL formatting macro.

    Code: Select all

    InsertMode
    ColumnModeOff
    HexOff
    PerlReOn
        (other commands here)
    Top
    Find RegExp " ON dbo\."
    Replace "\r\n    ON dbo."
    Top
    Find RegExp " WITH FILLFACTOR"
    Replace "\r\n    WITH FILLFACTOR"
    Top
    Find RegExp "(CREATE.*INDEX )"
    Replace "SET NOCOUNT ON;\r\nIF (SELECT INDEXPROPERTY(OBJECT_ID('~1'), '~2', 'IndexID') IS NULL)\r\n  $1"
        (other commands here)
    I wrote the macro originally against a SQL file that contained the "ON dbo." and "WITH FILLFACTOR" clauses. In that file, all three replaces work just fine.

    Code: Select all

    -- The macro always works on this line...
    CREATE INDEX ix_name ON dbo.tablename (field1, field2) WITH FILLFACTOR = 100;
    
    -- ... turning it into this code block (this is what it should look like).
    SET NOCOUNT ON;
    IF (SELECT INDEXPROPERTY(OBJECT_ID('~1'), '~2', 'IndexID') IS NULL)
      CREATE INDEX ix_name
        ON dbo.tablename (field1, field2)
        WITH FILLFACTOR = 100;
    I then ran it against a file without the fillfactor clause, and the third find/replace ("SET NOCOUNT") did not occur.

    Code: Select all

    -- This line...
    CREATE INDEX ix_name ON dbo.tablename (field1, field2);
    
    -- ... becomes this code block (note the missing SET NOCOUNT - it should be there!).
    CREATE INDEX ix_name
        ON dbo.tablename (field1, field2);
    If I alter the file so that the "ON dbo." fails to find a match, the fillfactor Find/Replace no longer works but the "SET NOCOUNT" replace now works.

    Code: Select all

    -- This line...
    CREATE INDEX ix_name ON tablename (field1, field2) WITH FILLFACTOR = 100;
    
    -- ... becomes this code block (note that the WITH FILLFACTOR is not on its own line).
    SET NOCOUNT ON;
    IF (SELECT INDEXPROPERTY(OBJECT_ID('~1'), '~2', 'IndexID') IS NULL)
      CREATE INDEX ix_name ON tablename (field1, field2) WITH FILLFACTOR = 100;
    Even better, if I modify the file such that the "dbo" and "FILLFACTOR" replaces do not find a match, the "NOCOUNT" replace works.

    Code: Select all

    -- This line...
    CREATE INDEX ix_name ON tablename (field1, field2);
    
    -- ... becomes this code block (technically correct, but why does it work now when it didn't above?).
    SET NOCOUNT ON;
    IF (SELECT INDEXPROPERTY(OBJECT_ID('~1'), '~2', 'IndexID') IS NULL)
      CREATE INDEX ix_name ON tablename (field1, field2);
    In all of this, macro commands that follow the above commands DO execute, so I know that the macro continues after any of the finds fail.

    Near as I can tell, a failed Find/Replace is corrupting something inside of UE. Another Find or Find/Replace resets this "something", at the cost of its own functionality. To test this, as a work-around I modified the code as shown below:

    Code: Select all

    Top
    Find RegExp "."
    Top
    Find RegExp " ON dbo\."
    Replace "\r\n    ON dbo."
    Top
    Find RegExp "."
    Top
    Find RegExp " WITH FILLFACTOR"
    Replace "\r\n    WITH FILLFACTOR"
    Top
    Find RegExp "."
    Top
    Find RegExp "(CREATE.*INDEX )"
    Replace "SET NOCOUNT ON;\r\nIF (SELECT INDEXPROPERTY(OBJECT_ID('~1'), '~2', 'IndexID') IS NULL)\r\n  $1"
    The extra Finds are always successful, since they look for any character starting at the top of the file. Since they work, they reset the internal problem and allow the other finds to properly succeed or fail based on the file contents.

    6,681583
    Grand MasterGrand Master
    6,681583

      May 01, 2010#2

      I created following macro for looking into this issue which has nothing to do with the replace problem of UE v16.00.0.1038 as I found out.

      Code: Select all

      InsertMode
      ColumnModeOff
      HexOff
      UnixReOff
      NewFile
      "-- Line to reformat:
      CREATE INDEX ix_name ON dbo.tablename (field1, field2);
      "
      Top
      Find " ON dbo."
      Replace "^p    ON dbo."
      Top
      Find " WITH FILLFACTOR"
      Replace "^p    WITH FILLFACTOR"
      Top
      Find RegExp "^(CREATE*INDEX ^)"
      Replace "SET NOCOUNT ON;^pIF (SELECT INDEXPROPERTY(OBJECT_ID('~1'), '~2', 'IndexID') IS NULL)^p  ^1"
      IfFound
      Bottom
      "Macro successful."
      Else
      Bottom
      "Macro failed!"
      EndIf
      I executed this macro with enabled macro property Continue if search string not found respectively Continue if a Find with Replace not found with several versions of UltraEdit down to the oldest one I have archived - version 10.10c. No version of UltraEdit created a "Macro successful." message at bottom of the file which really surprised me.

      Using now UE v10.10c for the following tests I exchanged the first 2 replaces in the macro resulting in the replace sequence

      Code: Select all

      Top
      Find " WITH FILLFACTOR"
      Replace "^p    WITH FILLFACTOR"
      Top
      Find " ON dbo."
      Replace "^p    ON dbo."
      Top
      This time I was not astonished that I could see the "Macro successful." message at bottom of the file, but "ON dbo." was not on a new line. So it does not matter if after a not successful replace the next replace is a normal or a regular expression replace.

      For my next test I converted the single replaces into replace all commands. I use in my macros always replace all wherever possible instead of single replaces to avoid cursor moving in the file which results in display updates making macros slower.

      Code: Select all

      InsertMode
      ColumnModeOff
      HexOff
      UnixReOff
      NewFile
      "-- Line to reformat:
      CREATE INDEX ix_name ON dbo.tablename (field1, field2);
      "
      Top
      Find " ON dbo."
      Replace All "^p    ON dbo."
      Find " WITH FILLFACTOR"
      Replace All "^p    WITH FILLFACTOR"
      Find RegExp "^(CREATE*INDEX ^)"
      Replace All "SET NOCOUNT ON;^pIF (SELECT INDEXPROPERTY(OBJECT_ID('~1'), '~2', 'IndexID') IS NULL)^p  ^1"
      IfFound
      Bottom
      "Macro successful."
      Else
      Bottom
      "Macro failed!"
      EndIf
      This macro executed successfully with UE v10.10c. So there is no problem using replace all commands.

      Next I thought what happens when I run the single replaces without repositioning the cursor all the time to top of the file by doing the replaces in the correct order using first following macro code:

      Code: Select all

      InsertMode
      ColumnModeOff
      HexOff
      UnixReOff
      NewFile
      "-- Line to reformat:
      CREATE INDEX ix_name ON dbo.tablename (field1, field2) WITH FILLFACTOR = 100;
      "
      Top
      Find RegExp "^(CREATE*INDEX ^)"
      Replace "SET NOCOUNT ON;^pIF (SELECT INDEXPROPERTY(OBJECT_ID('~1'), '~2', 'IndexID') IS NULL)^p  ^1"
      Find " ON dbo."
      Replace "^p    ON dbo."
      Find " WITH FILLFACTOR"
      Replace "^p    WITH FILLFACTOR"
      That macro produced the correct result which was no surprise because every searched string is present in the new file. Therefore I deleted "ON" from seventh line of the macro and executed it again. The result was that third replace did nothing although the cursor was after macro execution on line 4 column 16 and therefore left the searched string " WITH FILLFACTOR" not found by the third replace.

      I could not believe it, but after some further tests I must confirm that you have detected a bug existing in all versions of UltraEdit:

      Running two or more single replaces in a sequence one after the other with just cursor moving commands between them results in a wrong behavior of a single replace when the above single replace could not find the searched string.

      I cannot believe it that nobody else has been run into this problem before including myself. I sent already a bug reporting email to IDM about this issue. You found already by yourself a workaround. Below is another workaround. Executing Key BACKSPACE at top of the file does nothing on the file, but avoids running into this bug.

      Code: Select all

      Top
      Find " ON dbo."
      Replace "^p    ON dbo."
      Top
      Key BACKSPACE
      Find " WITH FILLFACTOR"
      Replace "^p    WITH FILLFACTOR"
      Top
      Key BACKSPACE
      Find RegExp "^(CREATE*INDEX ^)"
      Replace "SET NOCOUNT ON;^pIF (SELECT INDEXPROPERTY(OBJECT_ID('~1'), '~2', 'IndexID') IS NULL)^p  ^1"
      I'm quite sure that the IDM developers are looking quickly into this issue. Hopefully fixing this bug does not result in different results of old macros taking into account that this bug exists since years (all the time?).
      Best regards from an UC/UE/UES for Windows user from Austria