1

Global NONfunctionality

Creating a new database and added 4 global functions which all work as they should, but then added a fifth function which simply doesn't work.

The function just has 2 'text' parameters which it munges together in the way I want and there is no error shown on the global functions page, but when trying to use the function in a script, I get the error that it doesn't exist, despite prompting me with the function name when I first start typing it.

I changed the name, what the function does, parameter types and everything I could think of, but same problem. Everything looks correct, the other GFs work, but not this last one.

I then added another function to test and no matter what I did, it will not work. But…

The previous one that first had the error now works perfectly.

So, three things are now apparent:-

  • That problem function was actually completely correct
  • For some reason, GFs all work, except the last one, whatever it is.
  • This was not a problem with only 4 functions. They all worked.

I have since quit Ninox and will check to see if that clears the problem, but has anyone else come across this bizarre behaviour?

6 replies

null
    • Ninox developper
    • Jacques_TUR
    • 1 yr ago
    • Reported - view

    I’ve encountered this kind of issue several times before, and each time it was due to a global function calling a formula in a table, which in turn called another global function. It may seem trivial, but here is what actually happens:

    Global functions are compiled simultaneously, meaning they are all processed at the same time, regardless of one another. This works fine as long as there are no dependencies between them. Here’s a detailed explanation:

    1. Simultaneous Compilation of Global Functions

    F1 and F2, defined in the global functions space, are compiled together. As long as they don’t interact, there is no issue.

    2. Using a Formula in a Table

    If F1 calls a formula located in a table, that formula must be compiled to be used.

    • This formula, in turn, calls F2.

    3. Induced Dependency and Compilation Problem

    The compiler must compile the formula in order to compile F1. However, since the formula depends on F2, the compiler must also process F2 in this context.

    • The problem arises because F2 is also a global function compiled simultaneously with F1.

    • This dependency creates a chain where F1 depends on the formula and the formula depends on F2, resulting in a circular dependency.

     

    In summary, even if F1 and F2 are compiled in parallel, the fact that F1 calls a formula that requires F2 creates a circular dependency. The compiler ends up being unable to determine the proper order for compilation, which results in an error.

      • UKenGB
      • 1 yr ago
      • Reported - view

       Thanks, but I'm not convinced that's the issue here.

      First of all, if there is some sort of circular reference, that should surely be mentioned in the error, instead of simply stating the function could not be found - clearly a lie as it prompted the function name when starting to type. So it knew of the functions existence.

      Secondly, the function in question referenced no other function or formula. It simply concatenated (using '+' not concat()) the 2 text parameters with some additional literal text. This is as simple as a function can be really.

      Thirdly, when I added another simple textual and completely unrelated function (just to test) after this one that gave trouble, that first problem vanished, but the new one now did not work. There had been NO changes to the original problem function.

      Finally, after restarting Ninox, even that last function I added works.

      So Ninox was in a state when it was unable to process the last Global Function, whatever that was, yet all others worked and after a restart (of Ninox), they all work.

      To be honest, seems more like a bug to me.

      • Ninox developper
      • Jacques_TUR
      • 1 yr ago
      • Reported - view

       

      I understand that this may seem unbelievable, but if you understand how a compiler works, it becomes clearer. This happened to me several times, and I had to debug the compiler step-by-step to understand the phenomenon. At the same time, it’s quite instructive 🤗.

      Thus, in order to use just one of the global functions, Ninox must compile all of them at once. And if, among them, even one references a formula in a table, then it must also compile that formula before completing the compilation of the global functions. If that formula calls (directly or indirectly) a global function, then the compiler loops because it tries again to compile all the global functions, encounters the formula again, and so on.

      Moreover, the issue does not appear in the error messages because — and this is a shortcoming in Ninox — the concept of an error due to circular reference does not exist in this case. It crashes silently and simply reports that the function does not exist.

      Thus, this clearly explains the first two points:

      1. No error message;

      2. Even if the called function is not the one affected, it reports that it does not exist.

      Finally, I ran several tests with the attached application, and indeed, depending on the situation, a global function that is not actually involved might still work, although it doesn't seem stable. One case where it works is when a first function has created a circular reference at the time of compilation, allowing the next one to function correctly. This is just a quick preliminary test and would need further investigation, but I don’t have the energy to debug the compiler again tonight 😅.

      However, this could explain why the last function eventually worked.

      Let me know if any new issues arise with the global functions.

    • UKenGB
    • 8 days ago
    • Reported - view

    I had forgotten about this, but just noticed it again.

    I still don't see that the problem I experienced can possibly be explained by what  said above.

    Let say there are 100 Global Functions, that all work perfectly. One more is added that is unrelated to any other, is dependent on NOTHING else (just concatenates some text) and that 101st function just will not work. All the other 100 still work perfectly.

    Add another (102nd) function, similarly unrelated to and not dependent on anything and also maybe just some simple text stuff (no fields, no formula, no referenced functions) and this one does not work, but the 101st function now DOES work.

    Repeat ad infinitum (ok, I didn't test that many) and always the last function will not work, but all the others do.

    I just do not see this can have anything to do with any obscure circular references since there are NO such references in the functions that do not work.

    To me it looks like an obscure Ninox bug that above a certain number of global functions, it is unable to actually use the last one.

      • Ninox developper
      • Jacques_TUR
      • 6 days ago
      • Reported - view

       ,
      Your observation is interesting and I understand your reasoning. To move forward together on this, I’d like to suggest a small test protocol that should help us see things more clearly.
      The idea:
      Duplicate your database, then empty the content of each global function one by one, making sure to keep a return value of the correct type so you don’t trigger errors elsewhere in the database. For example:
          ∙    a function that returned text → ""
          ∙    a function that returned a number → 0
          ∙    a function that returned a boolean → false
          ∙    a function that returned a record set → (select myTable where false)
          ∙    a function that returned a single record → first((select myTable where false))
          ∙    a function that returned a typed array → an empty equivalent of the correct type
      The goal: in the end, all your global functions still exist (so calls elsewhere in the database remain valid), but none of them contain any internal dependency anymore.
      Then: add a new trivial global function and test it.
          ∙    If it works → the issue was indeed a hidden dependency somewhere in the content of your global functions.
          ∙    If it still doesn’t work → that would be a Ninox bug worth reporting, and I’d be very interested to see the case.
      To speed things up:
      Since emptying 100 functions one by one is tedious, start by working in batches of 10. Empty the first 10, test. If the problem persists, empty the next 10, test again, and so on. This will quickly identify which batch contains the cause, and you can then narrow it down inside that batch by dichotomy.
      Let me know how it goes, I’m curious to see the result.

      • UKenGB
      • 6 days ago
      • Reported - view

       That looks like worthwhile testing. I'll see what I can do and report the results back here, but don't hold your breath as I'm rather busy with a lot of other things right now.

Content aside

  • 1 Likes
  • 6 days agoLast active
  • 6Replies
  • 151Views
  • 4 Following