Skip to content

Conversation

@erichgess
Copy link
Contributor

@erichgess erichgess commented Mar 2, 2023

I hereby agree to the terms of the RisingWave Labs, Inc. Contributor License Agreement.

What's changed and what's your intention?

This addresses Issue #8025 .

With this change, the exp operator will now return an Underflow error if the the operand is small enough that the result is 0 and it will return an Overflow error if the operand is large enough that the result is Inf. This change is meant to create consistency between architectures which return 0 or Inf when the operand is too small/big and architectures which would fault. It also mirrors the Postgres logic, improving the consistency between RisingWave and Postgres.

The change adds a sequence of if checks to determine if exp returning 0 or Inf is valid or invalid. It's valid for exp to return 0 only when the operand is -Inf and it's valid for exp to return Inf only when the operand is Inf. For any other operand, a result of 0 or Inf indicates underflow or overflow, respectively. The logic in this PR checks the value of the operand to see if it is -Inf or Inf and, if it's not, then it checks if the result is 0 or Inf and returns an error if it is.

This PR also adds two new error variants to ExprError: NumericUnderflow and NumericOverflow which increases the precision of the error message returned to the user and better reflects the errors returned by Postgres. The exp operation uses these errors rather than the previous NumericOutOfRange error. I checked all uses of the NumericOutOfRange error to see if any can be changed to use either NumericUnderflow or NumericOverflow, but most of the situations they are used to not provide enough information to determine if an error was an underflow or overflow, AFAICT. One benchmark test, which checks specifically for overflow errors, was updated to use the new NumericOverflow.

Checklist For Contributors

  • I have written necessary rustdoc comments
  • I have added necessary unit tests and integration tests
  • I have added fuzzing tests or opened an issue to track them. (Optional, recommended for new SQL features Sqlsmith: Sql feature generation #7934).
  • I have demonstrated that backward compatibility is not broken by breaking changes and created issues to track deprecated features to be removed in the future. (Please refer to the issue)
  • All checks passed in ./risedev check (or alias, ./risedev c)

Checklist For Reviewers

  • I have requested macro/micro-benchmarks as this PR can affect performance substantially, and the results are shown.

Documentation

Click here for Documentation

Types of user-facing changes

Please keep the types that apply to your changes, and remove the others.

  • SQL commands, functions, and operators

Release note

  • The exp operator will now return an Overflow error if the operand is too large (e.g. exp(1000)) and it will return an Underflow error if the operand is too small (e.g., exp(-1000)). These changes are intended for consistency between architectures that will return errors when the operand is too large or too small, and architectures which return Inf and 0.

@lmatz lmatz requested review from lmatz and xiangjinwu March 2, 2023 13:27
@erichgess
Copy link
Contributor Author

I did not see any instructions on running fuzz tests in Dev Guide, so I don't know how to verify if the Fuzz tests work locally.

@lmatz
Copy link
Contributor

lmatz commented Mar 2, 2023

I did not see any instructions on running fuzz tests in Dev Guide, so I don't know how to verify if the Fuzz tests work locally.

It seems the failure of fuzz tests has nothing to do with this PR. I will try update branch to see if the test can be triggered once again and pass.

Generally LGTM, thanks for your contribution!

@kwannoel
Copy link
Contributor

kwannoel commented Mar 2, 2023

I did not see any instructions on running fuzz tests in Dev Guide, so I don't know how to verify if the Fuzz tests work locally.

Have taken a look at it, failure is due to a separate issue. Have submitted a fix and added some docs too: #8312.

Thanks for your contribution and for flagging this :)

@erichgess
Copy link
Contributor Author

erichgess commented Mar 2, 2023

I did not see any instructions on running fuzz tests in Dev Guide, so I don't know how to verify if the Fuzz tests work locally.

It seems the failure of fuzz tests has nothing to do with this PR. I will try update branch to see if the test can be triggered once again and pass.

Generally LGTM, thanks for your contribution!

No problem.

Since this PR has changes that would be user facing, what should I do about the last check box? Leaving it unchecked shows the PR as having 5/6 tasks done and I'm not sure if that's acceptable or if I should delete the last check box and just have the release notes I wrote.

@kwannoel
Copy link
Contributor

kwannoel commented Mar 3, 2023

I did not see any instructions on running fuzz tests in Dev Guide, so I don't know how to verify if the Fuzz tests work locally.

It seems the failure of fuzz tests has nothing to do with this PR. I will try update branch to see if the test can be triggered once again and pass.
Generally LGTM, thanks for your contribution!

No problem.

Since this PR has changes that would be user facing, what should I do about the last check box? Leaving it unchecked shows the PR as having 5/6 tasks done and I'm not sure if that's acceptable or if I should delete the last check box and just have the release notes I wrote.

You can leave it unchecked, release notes look good. Thanks!

@lmatz lmatz added the user-facing-changes Contains changes that are visible to users label Mar 3, 2023
Copy link
Contributor

@xiangjinwu xiangjinwu left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you!

#[cfg(test)]
mod tests {
use super::*;
use crate::hummock::file_cache::test_utils::tempdir;
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems these storage changes are included by accident?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I noticed that the unit tests in cache.rs were using a tempdir function that would use /risingwave for temp directories if the env var RISINGWAVE_CI was set. Since, this is using a temp directory to store the same cache data files as the unit tests in cache.rs, I thought it would make sense to update this code to use the same tempdir function as cache.rs.

I can undo this change if desired.

Comment on lines +55 to +58
fn legal_input() {
let res = exp_f64(0.0.into()).unwrap();
assert_eq!(res, OrderedF64::from(1.0));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Also test for NaN, -Inf and Inf?

Copy link
Contributor Author

@erichgess erichgess Mar 3, 2023

Choose a reason for hiding this comment

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

Thanks. Added missing unit tests.

@xiangjinwu xiangjinwu changed the title fix(exp PG compatibility): if a very large or very small operand is used, then exp errors fix(expr): exp follows PostgreSQL overflow/underflow behavior Mar 3, 2023
Copy link
Contributor

@lmatz lmatz left a comment

Choose a reason for hiding this comment

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

LGTM

@lmatz lmatz added this pull request to the merge queue Mar 3, 2023
Merged via the queue into risingwavelabs:main with commit 2c0ebd4 Mar 3, 2023
@erichgess erichgess deleted the 8025-exp-error-semantics branch March 3, 2023 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

user-facing-changes Contains changes that are visible to users

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants