In the case of POWER, Postgres has both a decimal and double version[1], and 
Calcite should do the same.

However, I take your point that if the function returns a double, then 
constant-reduction should create a double literal.

I am concerned that developers will accidentally create double literals, when 
double literals are not possible in SQL (until we implement DOUBLE ‘3.14’ 
syntax, as discussed in [2]). Until then, is it better to store the Rex 
equivalent of CAST(‘3.14’ AS DOUBLE)?

Julian

[1] https://www.postgresql.org/docs/8.2/functions-math.html
[2] https://issues.apache.org/jira/browse/CALCITE-6052 

> On Jan 30, 2024, at 3:21 PM, Mihai Budiu <mbu...@gmail.com> wrote:
> 
> Well, irrespective of the type of the arguments, the POWER function returns a 
> double value.
> 
> These are the 4 implementations in SqlFunctions:
> 
> public static double power(double b0, double b1) {
>    return Math.pow(b0, b1);
>  }
> 
>  public static double power(double b0, BigDecimal b1) {
>    return Math.pow(b0, b1.doubleValue());
>  }
> 
>  public static double power(BigDecimal b0, double b1) {
>    return Math.pow(b0.doubleValue(), b1);
>  }
> 
>  public static double power(BigDecimal b0, BigDecimal b1) {
>    return Math.pow(b0.doubleValue(), b1.doubleValue());
>  }
> 
> The problem is that, for the query below, the optimizer will then convert the 
> double result of power into a BigDecimal, rounding it in the process.
> 
> Mihai
> ________________________________
> From: Julian Hyde <jhyde.apa...@gmail.com>
> Sent: Tuesday, January 30, 2024 3:03 PM
> To: dev@calcite.apache.org <dev@calcite.apache.org>
> Subject: Re: Storing RexLiteral as BigDecimal values
> 
> It’s surprising to me that 1004.3e0 should have type DOUBLE or REAL; I would 
> expect it to have type DECIMAL(5, 1), where it can be represented exactly.
> 
>> On Jan 30, 2024, at 2:53 PM, Mihai Budiu <mbu...@gmail.com> wrote:
>> 
>> e0 shows that these are DOUBLE values.
>> Moreover, power returns a DOUBLE value.
>> In FP the result is the wrong one, but that's the semantics of the power 
>> function in FP.
>> 
>> Mihai
>> ________________________________
>> From: Julian Hyde <jhyde.apa...@gmail.com>
>> Sent: Tuesday, January 30, 2024 2:50 PM
>> To: dev@calcite.apache.org <dev@calcite.apache.org>
>> Subject: Re: Storing RexLiteral as BigDecimal values
>> 
>> The inputs are decimals, and the correct answer is 1008618.49, also a 
>> decimal, and cannot be exactly represented as a binary floating point. I’m 
>> not sure why in this case you want a binary floating point.
>> 
>>> On Jan 30, 2024, at 2:46 PM, Mihai Budiu <mbu...@gmail.com> wrote:
>>> 
>>> I am evaluating this expression: SELECT power(1004.3e0, 2e0)
>>> The result in Java, or Postgres, when formatted as a string, is 
>>> 1008618.4899999999
>>> The result produced by the Calcite simplification code is 1008618.49
>>> The simplification code can produce RexLiterals - that's where this would 
>>> be useful.
>>> This rounding error is not really necessary.
>>> 
>>> Mihai
>>> ________________________________
>>> From: Julian Hyde <jhyde.apa...@gmail.com>
>>> Sent: Tuesday, January 30, 2024 2:40 PM
>>> To: dev@calcite.apache.org <dev@calcite.apache.org>
>>> Subject: Re: Storing RexLiteral as BigDecimal values
>>> 
>>> Can you give a scenario where a RexLiteral should have a double value?
>>> 
>>>> On Jan 30, 2024, at 2:36 PM, Mihai Budiu <mbu...@gmail.com> wrote:
>>>> 
>>>> Hello,
>>>> 
>>>> I have a question about the representation of RexLiteral values.
>>>> Currently DOUBLE-valued literals are represented using a BigDecimal.
>>>> This causes small rounding errors, introduced in the RexBuilder.clean() 
>>>> function.
>>>> This causes FP expressions that are evaluated at compilation-time to 
>>>> produce results that are slightly off from the same expressions that may 
>>>> be evaluated at runtime, for no real reason. For example, I am running 
>>>> some Postgres tests for FP values, and they fail because of this small 
>>>> difference.
>>>> 
>>>> I know that FP values cannot be compared for equality, and tests are 
>>>> supposed to have some slack, but I think that this particular rounding 
>>>> error is not necessary.
>>>> 
>>>> Why can't RexLiteral actually store a Double value internally when the 
>>>> type is Double?
>>>> Is this a bug or is there a deeper reason for this representation?
>>>> If it's a bug I can file a JIRA issue and probably fix it.
>>>> 
>>>> Thank you,
>>>> Mihai
>>> 
>> 
> 

Reply via email to