diff --git a/src/Parsers/ASTFunction.cpp b/src/Parsers/ASTFunction.cpp index 18a47eb2126..9027579495a 100644 --- a/src/Parsers/ASTFunction.cpp +++ b/src/Parsers/ASTFunction.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -234,7 +235,9 @@ void ASTFunction::formatImplWithoutAlias(const FormatSettings & settings, Format * interpreted as a comment. Instead, negate the literal * in place. Another possible solution is to use parentheses, * 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") { @@ -251,26 +254,17 @@ void ASTFunction::formatImplWithoutAlias(const FormatSettings & settings, Format { // The parser doesn't create decimal literals, but // 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; - // We compare to zero so we don't care about scale. - if (int_value >= 0) - { - return false; - } - - settings.ostr << ValueType{-int_value, + settings.ostr << ValueType{ + -int_value, value.getScale()}; } else if constexpr (std::is_arithmetic_v) { - if (value >= 0) - { - return false; - } - // We don't need parentheses around a single - // literal. - settings.ostr << -value; + using ResultType = typename NumberTraits::ResultOfNegate::Type; + settings.ostr << -static_cast(value); return true; } diff --git a/tests/queries/0_stateless/01566_negate_formatting.reference b/tests/queries/0_stateless/01566_negate_formatting.reference index b955d4cbbc5..88eda68bb7e 100644 --- a/tests/queries/0_stateless/01566_negate_formatting.reference +++ b/tests/queries/0_stateless/01566_negate_formatting.reference @@ -8,7 +8,7 @@ SELECT -1 IN (-1) explain syntax select negate(1.), negate(-1.), - -1., -(-1.), (-1.) in (-1.); SELECT - -1., + -1, 1, 1, 1, @@ -18,3 +18,17 @@ SELECT -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.) diff --git a/tests/queries/0_stateless/01566_negate_formatting.sql b/tests/queries/0_stateless/01566_negate_formatting.sql index 035ff80e8d8..65e983fbdd1 100644 --- a/tests/queries/0_stateless/01566_negate_formatting.sql +++ b/tests/queries/0_stateless/01566_negate_formatting.sql @@ -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(-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.);