more stable formatting for negate()

This commit is contained in:
Alexander Kuzmenkov 2021-04-16 19:28:07 +03:00
parent bd49e696c4
commit b991cbf9d6
3 changed files with 27 additions and 17 deletions

View File

@ -3,6 +3,7 @@
#include <Common/quoteString.h> #include <Common/quoteString.h>
#include <Common/SipHash.h> #include <Common/SipHash.h>
#include <Common/typeid_cast.h> #include <Common/typeid_cast.h>
#include <DataTypes/NumberTraits.h>
#include <IO/Operators.h> #include <IO/Operators.h>
#include <IO/WriteBufferFromString.h> #include <IO/WriteBufferFromString.h>
#include <IO/WriteHelpers.h> #include <IO/WriteHelpers.h>
@ -234,7 +235,9 @@ void ASTFunction::formatImplWithoutAlias(const FormatSettings & settings, Format
* interpreted as a comment. Instead, negate the literal * interpreted as a comment. Instead, negate the literal
* in place. Another possible solution is to use parentheses, * in place. Another possible solution is to use parentheses,
* but the old comment said it is impossible, without mentioning * but the old comment said it is impossible, without mentioning
* the reason. * the reason. We should also negate the nonnegative literals,
* for symmetry. We print the negated value without parentheses,
* because they are not needed around a single literal.
*/ */
if (literal && name == "negate") if (literal && name == "negate")
{ {
@ -251,26 +254,17 @@ void ASTFunction::formatImplWithoutAlias(const FormatSettings & settings, Format
{ {
// The parser doesn't create decimal literals, but // The parser doesn't create decimal literals, but
// they can be produced by constant folding or the // they can be produced by constant folding or the
// fuzzer. // fuzzer. Decimals are always signed, so no need
// to deduce the result type like we do for ints.
const auto int_value = value.getValue().value; const auto int_value = value.getValue().value;
// We compare to zero so we don't care about scale. settings.ostr << ValueType{
if (int_value >= 0) -int_value,
{
return false;
}
settings.ostr << ValueType{-int_value,
value.getScale()}; value.getScale()};
} }
else if constexpr (std::is_arithmetic_v<ValueType>) else if constexpr (std::is_arithmetic_v<ValueType>)
{ {
if (value >= 0) using ResultType = typename NumberTraits::ResultOfNegate<ValueType>::Type;
{ settings.ostr << -static_cast<ResultType>(value);
return false;
}
// We don't need parentheses around a single
// literal.
settings.ostr << -value;
return true; return true;
} }

View File

@ -8,7 +8,7 @@ SELECT
-1 IN (-1) -1 IN (-1)
explain syntax select negate(1.), negate(-1.), - -1., -(-1.), (-1.) in (-1.); explain syntax select negate(1.), negate(-1.), - -1., -(-1.), (-1.) in (-1.);
SELECT SELECT
-1., -1,
1, 1,
1, 1,
1, 1,
@ -18,3 +18,17 @@ SELECT
-9223372036854775808, -9223372036854775808,
-9223372036854775808, -9223372036854775808,
-9223372036854775808 -9223372036854775808
explain syntax select negate(0), negate(-0), - -0, -(-0), (-0) in (-0);
SELECT
0,
0,
0,
0,
0 IN (0)
explain syntax select negate(0.), negate(-0.), - -0., -(-0.), (-0.) in (-0.);
SELECT
-0,
0,
0,
0,
-0. IN (-0.)

View File

@ -2,3 +2,5 @@
explain syntax select negate(1), negate(-1), - -1, -(-1), (-1) in (-1); explain syntax select negate(1), negate(-1), - -1, -(-1), (-1) in (-1);
explain syntax select negate(1.), negate(-1.), - -1., -(-1.), (-1.) in (-1.); explain syntax select negate(1.), negate(-1.), - -1., -(-1.), (-1.) in (-1.);
explain syntax select negate(-9223372036854775808), -(-9223372036854775808), - -9223372036854775808; explain syntax select negate(-9223372036854775808), -(-9223372036854775808), - -9223372036854775808;
explain syntax select negate(0), negate(-0), - -0, -(-0), (-0) in (-0);
explain syntax select negate(0.), negate(-0.), - -0., -(-0.), (-0.) in (-0.);