Thread

  1. Question about ECPGset_noind_null() and ECPGis_noind_null()

    Boszormenyi Zoltan <zb@cybertec.at> — 2009-11-19T13:29:05Z

    Hi,
    
    my question is that what platform were these
    functions developed and tested?
    
    We have come across a value that fails a NOT NULL
    constraint upon INSERT under HP-UX/IA64, but not
    under x86-64 Linux. The value in question is
    1.9999999999999998 assigned to a "double" variable.
    Under HP-UX/IA64, testing with risnull() from
    the application indeed returns true, but under
    Linux/x86-64 returns false.
    
    I will test rsetnull() results on real Informix under
    HP-UX/IA64.
    
    Best regards,
    Zoltán Böszörményi
    
    -- 
    Bible has answers for everything. Proof:
    "But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
    than these cometh of evil." (Matthew 5:37) - basics of digital technology.
    "May your kingdom come" - superficial description of plate tectonics
    
    ----------------------------------
    Zoltán Böszörményi
    Cybertec Schönig & Schönig GmbH
    http://www.postgresql.at/
    
    
    
  2. Re: Question about ECPGset_noind_null() and ECPGis_noind_null()

    Boszormenyi Zoltan <zb@cybertec.at> — 2009-11-19T19:12:24Z

    Boszormenyi Zoltan írta:
    > Hi,
    >
    > my question is that what platform were these
    > functions developed and tested?
    >
    > We have come across a value that fails a NOT NULL
    > constraint upon INSERT under HP-UX/IA64, but not
    > under x86-64 Linux. The value in question is
    > 1.9999999999999998 assigned to a "double" variable.
    > Under HP-UX/IA64, testing with risnull() from
    > the application indeed returns true, but under
    > Linux/x86-64 returns false.
    >
    > I will test rsetnull() results on real Informix under
    > HP-UX/IA64.
    >   
    
    I have tested it under ESQL/C on HP-UX/ia64 and
    this happened:
    - rsetnull() on a double value creates
      FF FF FF FF FF FF FF FF
    - the value causing the error above is
      3F FF FF FF FF FF FF FF
    
    It seems that this function in ecpglib/misc.c has
    an off-by-one bug as it's interpreted by the HP-UX CC:
    
    static bool
    _check(unsigned char *ptr, int length)
    {
            for (; length > 0 && ptr[--length] == 0xff;);
            if (length <= 0)
                    return true;
            return false;
    }
    
    I suspect that GCC does the "--length" after checking
    "length > 0" and before checking the "ptr[...] == 0xff",
    but HP CC does it before checking "length > 0".
    
    The attached patch solves the problem.
    
    Best regards,
    Zoltán Böszörményi
    
    -- 
    Bible has answers for everything. Proof:
    "But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
    than these cometh of evil." (Matthew 5:37) - basics of digital technology.
    "May your kingdom come" - superficial description of plate tectonics
    
    ----------------------------------
    Zoltán Böszörményi
    Cybertec Schönig & Schönig GmbH
    http://www.postgresql.at/
    
    
  3. Re: Question about ECPGset_noind_null() and ECPGis_noind_null()

    Tom Lane <tgl@sss.pgh.pa.us> — 2009-11-19T19:33:47Z

    Boszormenyi Zoltan <zb@cybertec.at> writes:
    >         for (; length > 0 && ptr[--length] == 0xff;);
    
    > I suspect that GCC does the "--length" after checking
    > "length > 0" and before checking the "ptr[...] == 0xff",
    > but HP CC does it before checking "length > 0".
    
    If it does, that is *unquestionably* a bug in HP's CC and should be
    reported to them.  However, the code is sufficiently unreadable to
    be worth rewriting anyhow.  Your suggestion is an improvement but
    personally I'd plump for
    
    	int	i;
    
    	for (i = 0; i < length; i++)
    		if (ptr[i] != 0xff)
    			return false;
    	return true;
    
    			regards, tom lane
    
    
  4. Re: Question about ECPGset_noind_null() and ECPGis_noind_null()

    Andrew Dunstan <andrew@dunslane.net> — 2009-11-19T19:46:50Z

    
    Tom Lane wrote:
    > Boszormenyi Zoltan <zb@cybertec.at> writes:
    >   
    >>         for (; length > 0 && ptr[--length] == 0xff;);
    >>     
    >
    >   
    >> I suspect that GCC does the "--length" after checking
    >> "length > 0" and before checking the "ptr[...] == 0xff",
    >> but HP CC does it before checking "length > 0".
    >>     
    >
    > If it does, that is *unquestionably* a bug in HP's CC and should be
    > reported to them.  
    >   
    
    Wow, I recall fighting HP over a bad compiler bug (although not as bad 
    as this would be) 15 years ago. Their official response amounted to "we 
    don't care and we're not going to fix it". Maybe not much has changed.
    
    cheers
    
    andrew
    
    
  5. Re: Question about ECPGset_noind_null() and ECPGis_noind_null()

    Boszormenyi Zoltan <zb@cybertec.at> — 2009-11-19T20:32:51Z

    Tom Lane írta:
    > Boszormenyi Zoltan <zb@cybertec.at> writes:
    >   
    >>         for (; length > 0 && ptr[--length] == 0xff;);
    >>     
    >
    >   
    >> I suspect that GCC does the "--length" after checking
    >> "length > 0" and before checking the "ptr[...] == 0xff",
    >> but HP CC does it before checking "length > 0".
    >>     
    >
    > If it does, that is *unquestionably* a bug in HP's CC and should be
    > reported to them.
    
    Is it *really* a bug? I recalled a comment from my C teacher
    in '92 or '93 about this exact issue, that the prefix/postfix
    increment/decrement operators are executed in the
    statement in an implementation-defined order, i.e. they
    can be freely reordered or placed anywhere in the
    expression, provided that the postfix operator's evaluation
    is earlier than the usage of the variable it's used on and
    evaluation is later than the variable usage in the postfix case.
    This means that their usage has to be minimized so the
    result is unambiguous. I.e. in the common usage:
    
        str1[pos1++] = str2[pos2++];
    
    these execution orders are possible and all give the same result:
    
    1.  evaluate str2[pos2]
        increment pos2
        assign the above value to str1[pos1]
        increment pos1
    or
    2.  evaluate str2[pos2]
        assign the above value to str1[pos1]
        increment pos2
        increment pos1
    or
    3.  evaluate str2[pos2]
        assign the above value to str1[pos1]
        increment pos1
        increment pos2
    
    In the case of
        for (; length > 0 && ptr[--length] == 0xff;);
    the different evaluation orders may give different
    expression results.
    
    But 17 years is a long time, the C language specification
    has changed a lot. GCC definitely does the most sensible
    order but I didn't know this behaviour is specified in the
    C language.
    
    >   However, the code is sufficiently unreadable to
    > be worth rewriting anyhow.  Your suggestion is an improvement but
    > personally I'd plump for
    >
    > 	int	i;
    >
    > 	for (i = 0; i < length; i++)
    > 		if (ptr[i] != 0xff)
    > 			return false;
    > 	return true;
    >   
    
    Yes, it's better than my version.
    
    Best regards,
    Zoltán Böszörményi
    
    > 			regards, tom lane
    >
    >   
    
    
    -- 
    Bible has answers for everything. Proof:
    "But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
    than these cometh of evil." (Matthew 5:37) - basics of digital technology.
    "May your kingdom come" - superficial description of plate tectonics
    
    ----------------------------------
    Zoltán Böszörményi
    Cybertec Schönig & Schönig GmbH
    http://www.postgresql.at/
    
    
    
  6. Re: Question about ECPGset_noind_null() and ECPGis_noind_null()

    Boszormenyi Zoltan <zb@cybertec.at> — 2009-11-19T20:36:29Z

    Boszormenyi Zoltan írta:
    > Tom Lane írta:
    >   
    >> Boszormenyi Zoltan <zb@cybertec.at> writes:
    >>   
    >>     
    >>>         for (; length > 0 && ptr[--length] == 0xff;);
    >>>     
    >>>       
    >>   
    >>     
    >>> I suspect that GCC does the "--length" after checking
    >>> "length > 0" and before checking the "ptr[...] == 0xff",
    >>> but HP CC does it before checking "length > 0".
    >>>     
    >>>       
    >> If it does, that is *unquestionably* a bug in HP's CC and should be
    >> reported to them.
    >>     
    >
    > Is it *really* a bug? I recalled a comment from my C teacher
    > in '92 or '93 about this exact issue, that the prefix/postfix
    > increment/decrement operators are executed in the
    > statement in an implementation-defined order, i.e. they
    > can be freely reordered or placed anywhere in the
    > expression, provided that the postfix operator's evaluation
    >   
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    Above is the prefix case obviously...
    
    > is earlier than the usage of the variable it's used on and
    > evaluation is later than the variable usage in the postfix case.
    > This means that their usage has to be minimized so the
    > result is unambiguous.
    
    -- 
    Bible has answers for everything. Proof:
    "But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
    than these cometh of evil." (Matthew 5:37) - basics of digital technology.
    "May your kingdom come" - superficial description of plate tectonics
    
    ----------------------------------
    Zoltán Böszörményi
    Cybertec Schönig & Schönig GmbH
    http://www.postgresql.at/
    
    
    
  7. Re: Question about ECPGset_noind_null() and ECPGis_noind_null()

    Andrew Dunstan <andrew@dunslane.net> — 2009-11-19T20:38:53Z

    
    Boszormenyi Zoltan wrote:
    >
    > Is it *really* a bug? I recalled a comment from my C teacher
    > in '92 or '93 about this exact issue, that the prefix/postfix
    > increment/decrement operators are executed in the
    > statement in an implementation-defined order, 
    >   
    
    Not if they come after a short-circuit operator such as && - after all, 
    that's what short-circuit evaluation implies. If the left hand operand 
    of && is false the right hand should not be evaluated at all.
    
    cheers
    
    andrew
    
    
  8. Re: Question about ECPGset_noind_null() and ECPGis_noind_null()

    Tom Lane <tgl@sss.pgh.pa.us> — 2009-11-19T20:51:12Z

    Andrew Dunstan <andrew@dunslane.net> writes:
    > Boszormenyi Zoltan wrote:
    >> Is it *really* a bug? I recalled a comment from my C teacher
    >> in '92 or '93 about this exact issue, that the prefix/postfix
    >> increment/decrement operators are executed in the
    >> statement in an implementation-defined order, 
    
    > Not if they come after a short-circuit operator such as && - after all, 
    > that's what short-circuit evaluation implies. If the left hand operand 
    > of && is false the right hand should not be evaluated at all.
    
    Yes.  && is a sequence point and the compiler is not allowed to move
    side-effects across a sequence point.  What your C teacher was warning
    you against was things like
    	a[i] = i++;
    '=' is not a sequence point so it's undefined which array index
    will be stored into.
    
    			regards, tom lane
    
    
  9. Re: Question about ECPGset_noind_null() and ECPGis_noind_null()

    Boszormenyi Zoltan <zb@cybertec.at> — 2009-11-19T21:00:52Z

    Tom Lane írta:
    > Andrew Dunstan <andrew@dunslane.net> writes:
    >   
    >> Boszormenyi Zoltan wrote:
    >>     
    >>> Is it *really* a bug? I recalled a comment from my C teacher
    >>> in '92 or '93 about this exact issue, that the prefix/postfix
    >>> increment/decrement operators are executed in the
    >>> statement in an implementation-defined order, 
    >>>       
    >
    >   
    >> Not if they come after a short-circuit operator such as && - after all, 
    >> that's what short-circuit evaluation implies. If the left hand operand 
    >> of && is false the right hand should not be evaluated at all.
    >>     
    >
    > Yes.  && is a sequence point and the compiler is not allowed to move
    > side-effects across a sequence point.  What your C teacher was warning
    > you against was things like
    > 	a[i] = i++;
    > '=' is not a sequence point so it's undefined which array index
    > will be stored into.
    >
    > 			regards, tom lane
    >   
    
    Thanks to both of you, this was really informative.
    Actually my C teacher didn't mention such optimization barriers.
    It seems I need to look up the raw C language specs...
    
    Best regards,
    Zoltán Böszörményi
    
    -- 
    Bible has answers for everything. Proof:
    "But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
    than these cometh of evil." (Matthew 5:37) - basics of digital technology.
    "May your kingdom come" - superficial description of plate tectonics
    
    ----------------------------------
    Zoltán Böszörményi
    Cybertec Schönig & Schönig GmbH
    http://www.postgresql.at/