4GL compares NULL differently
Posted in 2005
A user on I4GL 7.32.UC2 (C compiler, Solaris 2.6) reported that an IF test like "IF m_inv_amt != 0" on a DECIMAL variable holding NULL sometimes evaluated TRUE and sometimes FALSE, inconsistently though repeatably. Replies noted that comparisons involving NULL are effectively undefined/unknown and advised explicitly testing IS NULL first, while the poster cited manual text saying such comparisons should yield FALSE. Testing "= 0" gave the same inconsistency; the workaround is awkward given large legacy code. No definitive cause or fix is recorded.
Auto-generated by DrWatson from the posts below — may be imperfect; read the full thread.
Topics: Connectivity: ESQL/C, 4GL & Embedded SQL
4GL 7.32.UC2 Solaris 2.6 4GL must compare NULL to any not-NULL value as FALSE. And it acts this way... sometimes. Please review the following sample: >>>>>>>>>>>>>>>>>> DEFINE m_inv_amt DECIMAL(12,2) FUNCTION AmtUsed() IF m_inv_amt != 0 THEN RETURN true ELSE RETURN false END IF END FUNCTION <<<<<<<<<<<<<<<<<< When m_inv_amt is NULL, AmtUsed() returns FALSE at one moment, and TRUE at another. And the FALSE/TRUE sequence doesn't change from run to run. Is it a known bug or a new feature?
P.S. 4GL C compiler.
Denis Melnikov wrote: > P.S. 4GL C compiler. > > Because any equality or inequality test against null is specifically undefined You have to test 'is null'ness before applying your !=0 or whatever tests -- Clive
"Denis Melnikov" <dm'lnik@regent.ru> wrote: > 4GL 7.32.UC2 > Solaris 2.6 > > 4GL must compare NULL to any not-NULL value as FALSE. > And it acts this way... sometimes. > > Please review the following sample: > >>>>>>>>>>>>>>>>>>> > DEFINE m_inv_amt DECIMAL(12,2) > > FUNCTION AmtUsed() > > IF m_inv_amt != 0 THEN > RETURN true > ELSE > RETURN false > END IF > END FUNCTION > <<<<<<<<<<<<<<<<<< > > When m_inv_amt is NULL, AmtUsed() returns FALSE at one moment, > and TRUE at another. And the FALSE/TRUE sequence doesn't > change from run to run. > > Is it a known bug or a new feature? I'm not quite ready to call it either. Just out of curiosity, what happens if you write: IF m_inv_amt = 0 THEN Do you get a more consistent result? I ask because of the comments in the I4GL Concepts and Use Guide. Null values are discussed and the manual does tell you (on page 8-27 of manual Part No. 000-8875) that "If you compare a null value to anything else, the result is NULL. Is 'A' equal to unknown? The only answer can be unknown. Thus every comparison expression has not two but three possible results: TRUE, FALSE, and unknown, or NULL." The manual goes on to tell you that NULL (unknown) will be treated as FALSE when evaluated by statements such as IF and WHILE. My question comes from the fact that you are not testing to see if the value of m_inv_amt is equal to zero, but rather, is m_inv_amt not equal to zero. It is the 'not' part of the comparison that has my interest. It has been a while since I've had the pleasure of working with pure I4GL, but we never took the result of a possible NULL for granted. If the possibility for a NULL value exists, I would suggest you check specifically for NULL. In any case, I'll be interested to see if you get other responses to this. -- June Hunt
> Because any equality or inequality test against null is specifically > undefined No! IBM Informix 4GL Reference Manual Version 7.32: "If any operand of a 4GL Boolean comparison is NULL, the value of the comparison is FALSE (rather than NULL), unless the IS NULL keywords are also included in the expression." > You have to test 'is null'ness before applying your !=0 or whatever tests This is workaround which we have to use in our new code. Unfortunatelly we have the great amount of legacy code without the workaround. > -- > Clive
"June C. Hunt" <june.c.hunt@gmail.com> '''''''/'''''''' ' '''''''' ''''''''': news:3s9da3FmqgjbU1@individual.net... > "Denis Melnikov" <dm'lnik@regent.ru> wrote: > > 4GL 7.32.UC2 > > Solaris 2.6 > > > > 4GL must compare NULL to any not-NULL value as FALSE. > > And it acts this way... sometimes. > > > > Please review the following sample: > > > >>>>>>>>>>>>>>>>>>> > > DEFINE m_inv_amt DECIMAL(12,2) > > > > FUNCTION AmtUsed() > > > > IF m_inv_amt != 0 THEN > > RETURN true > > ELSE > > RETURN false > > END IF > > END FUNCTION > > <<<<<<<<<<<<<<<<<< > > > > When m_inv_amt is NULL, AmtUsed() returns FALSE at one moment, > > and TRUE at another. And the FALSE/TRUE sequence doesn't > > change from run to run. > > > > Is it a known bug or a new feature? > > I'm not quite ready to call it either. Just out of curiosity, what happens > if you write: > IF m_inv_amt = 0 THEN > > Do you get a more consistent result? No, we have the same inconsistency. > I ask because of the comments in the I4GL Concepts and Use Guide. Null > values are discussed and the manual does tell you (on page 8-27 of manual > Part No. 000-8875) that "If you compare a null value to anything else, the > result is NULL. Is 'A' equal to unknown? The only answer can be unknown. > Thus every comparison expression has not two but three possible results: > TRUE, FALSE, and unknown, or NULL." The manual goes on to tell you that > NULL (unknown) will be treated as FALSE when evaluated by statements such as > IF and WHILE. My question comes from the fact that you are not testing to > see if the value of m_inv_amt is equal to zero, but rather, is m_inv_amt not > equal to zero. It's because we need to handle "not-zero" and all other possibilities including NULL. > It is the 'not' part of the comparison that has my interest. > > It has been a while since I've had the pleasure of working with pure I4GL, > but we never took the result of a possible NULL for granted. If the > possibility for a NULL value exists, I would suggest you check specifically > for NULL. In any case, I'll be interested to see if you get other responses > to this. Thank you for advice.