I am calling a user-defined function and passing an argument that is in dot notation. For example,
of_testingnullarg( tab_2.tabpage_comp_info.dw_webcomp_info.object.dormant[i] )
The above function is purely to demonstrate this problem. It accepts a long parameter and uses isNull() and messagebox() to tell the user if the parameter is null or not. Here is its listing:
// of_testingnullarg( al_arg1 )
// strictly an experiment
if isNull(al_arg1) then
messageBox("al_arg1", "is null inside of_testingNullArg")
else
messageBox("al_arg1", "is NOT null inside of_testingNullArg, it is "+string(al_arg1))
end if
When the dormant[i] (referring to the first function call) control contains a number, there is no problem--the parameter inside of_testingnullarg will contain the same number, as expected. But when the dormant[i] control has read null from the database, I find that the parameter inside of_testingnullarg does NOT hold null. It holds a number such as 16. Null was passed in (according to isNull()), but the parameter inside of_testingnullarg holds a number. It is not a random number, it is consistent, but seems to be dependent on how many parameters the function accepts.
This problem does NOT reveal itself when I run the program inside the Powerbuilder IDE. (I am running Powerbuilder 12.5) It shows up only when I build the program and run the executable.
I have found that if I first do this, the problem goes away:
long ll_dormant
ll_dormant = tab_2.tabpage_comp_info.dw_webcomp_info.object.dormant[i]
of_testingnullarg( ll_dormant )
To summarize, the problem shows up when 3 things are true:
I think this must have something to do with a pointer on the call stack. It must be off 2 bytes or something. Is it common knowledge to always put the value into a variable first?
I have found out that dot-notation returns type 'ANY'. This is a problem when the value is NULL which is typeless. PowerBuilder is trying to do an implicit cast of a NULL Any value to a NULL Long and gets confused. The solution is to help PowerBuilder with the type BEFORE the function call (which is why putting it into a variable first worked). These also work:
of_testingnullarg( LONG(tab_2.tabpage_comp_info.dw_webcomp_info.object.dormant[i]) )
or
of_testingnullarg( tab_2.tabpage_comp_info.dw_webcomp_info.GetItemNumber(i, "dormant") )