Skip to content

[CALCITE-7443] Incorrect simplification for large interval#4845

Open
mihaibudiu wants to merge 1 commit intoapache:mainfrom
mihaibudiu:issue7443
Open

[CALCITE-7443] Incorrect simplification for large interval#4845
mihaibudiu wants to merge 1 commit intoapache:mainfrom
mihaibudiu:issue7443

Conversation

@mihaibudiu
Copy link
Contributor

Jira Link

https://issues.apache.org/jira/browse/CALCITE-7443

Changes Proposed

This PR changes all arithmetic on values of type INTERVAL to use checked arithmetic.

Currently, using the default conformance, Calcite's arithmetic obeys the Java rules, i.e., overflow is just wrap-around. There is a conformance flag which allows you to change this behavior; checked arithmetic will throw on overflow (at runtime).

Values such as intervals are encoded into long/integer values, and arithmetic on intervals is compiled into suitably scaled computations in Java. However, I can argue that there is no reason for interval arithmetic to wrap-around; in fact, if it does, it can produce very surprising results, since the encoding of intervals into integers is not part of any spec (it is an implementation detail).

We already had a visitor to convert unchecked arithmetic into checked arithmetic. Previously the visitor was only invoked when the conformance required checked arithmetic. Now the visitor is always invoked, and it performs the following rewrites:

  • any operation that has an operand of type interval and a result of type interval is rewritten to use checked arithmetic
  • other arithmetic operations are rewritten to be checked only if conformance requires it, keeping the previous behavior

Signed-off-by: Mihai Budiu <mbudiu@feldera.com>
// Do not rewrite operator if the type is e.g., DOUBLE or DATE
(this.allArithmetic && SqlTypeName.EXACT_TYPES.contains(resultType))
// But always rewrite if the type is an INTERVAL and any operand is INTERVAL
// This will not rewrite date subtraction, for example
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if the comments are finished, because there's no further content after "for example".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the example is "it will not rewrite date subtraction"

!error

SELECT INTERVAL 3000000 months / .0001;
java.lang.ArithmeticException: Overflow
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this outputs a more complete error message; I'll take a look at the code later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reviewing the code, it seems the error message wasn't thrown by Calcite, but rather by the Java API, which makes sense now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message is not informative, it is the innermost exception, which is not very helpful. But this is the best we can do now.

(this.allArithmetic && SqlTypeName.EXACT_TYPES.contains(resultType))
// But always rewrite if the type is an INTERVAL and any operand is INTERVAL
// This will not rewrite date subtraction, for example
|| (resultIsInterval && anyOperandIsInterval);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the condition anyOperandIsInterval needed?🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid rewriting date subtraction

Copy link
Member

@caicancai caicancai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the comments for "for example" were improved, I had no further questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants