-
Notifications
You must be signed in to change notification settings - Fork 526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(common): implement logical type for int256 #9028
Conversation
de8bfa6
to
7102e8f
Compare
It seems like |
By skimming through some smart contract implementations,
Besides, looking into the two most popular implementations of ETH nodes, i.e. https://github.com/ethereum/go-ethereum and https://github.com/ledgerwatch/erigon, both of them seem to use https://pkg.go.dev/github.com/holiman/uint256#section-readme library and this library only provides But the current user who requested Therefore, I have no strong opinion on this. We can support |
Codecov Report
@@ Coverage Diff @@
## main #9028 +/- ##
==========================================
- Coverage 70.87% 70.85% -0.03%
==========================================
Files 1197 1197
Lines 199031 199250 +219
==========================================
+ Hits 141062 141173 +111
- Misses 57969 58077 +108
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 4 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
It seems this PR now does at least 2 things:
Can we spilt it into 2 parts focusing on each item? |
Sure, i'll do it |
82e2714
to
bbfe860
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still reading some parts ... but posting existing comments first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly done, except for type conversions and arithmetic...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The auto-generated PR description is meaningless and even misleading. To summarize:
- introduce
rw_int256
(DataType::Int256
) - support casting int256 from and into string
- support implicit casting from smallint / int / bigint to rw_int256
- support comparison
- support binary
+
/-
/*
//
/%
and unary-
- fix memcomparable encoding
Limitation:
HashKeySerDe
cannot be implemented, soHashKeySize::Variable
is used.
In addition, let's add e2e tests to demonstrate the basic usage (interoperate with int, no interoperate with decimal / float, quoted for numbers larger than bigint), as well as the panic / wrong queries we fixed. A new type should also be working automatically for is null
, case when
, coalesce
, nullif
, in
.
FYI there also also other polymorphic arithmetic operations for integral types:
- unary
+
handled in frontend binder abs
- bitwise (maybe until necessary)
…, removed unnecessary usage.
…t for null value, drop table.
impl Signed for Int256 { | ||
fn abs(&self) -> Self { | ||
self.0.abs().into() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately num-traits
does not have CheckedAbs
. We can expose checked_abs
from ethnum
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we can use the same neg
method that's used for general_abs
to implement the abs
method directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes. I just want to avoid introducing too many useless methods that panics when misused, for example abs
could panic for MIN. For the same reason I do not like num-traits
requires CheckedAdd: Add
.
But to reuse general_abs
, let's keep this impl Signed
@@ -165,6 +166,7 @@ fn calculate_encoded_size_inner( | |||
DataType::Jsonb => deserializer.skip_bytes()?, | |||
DataType::Varchar => deserializer.skip_bytes()?, | |||
DataType::Bytea => deserializer.skip_bytes()?, | |||
DataType::Int256 => Int256::MEMCMP_ENCODED_SIZE, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still incorrect. Although deserializer.skip_bytes()
returns Int256::MEMCMP_ENCODED_SIZE
here, it also has a side effect of advancing the offset. For fixed size types, the offset advancing is done on line 175 below.
Since we encoded int256 as bytes, it has extra marks and advancing 32 bytes is not enough.. But I am not familiar with how this code is used and how to construct a query to trigger this error or panic.
Now talking about the fix:
- Easiest is just to use
skip_bytes
, because the encoding is bytes. - But actually we could avoid the extra marks in bytes encoding, and use exactly 32 bytes. There is
i256::into_words
. It returns(i128, i128)
but logically it should be(i128, u128)
. The memcomparable ser/de is not implemented for i128/u128 yet, but we can play the same trick again to split i128 to(i64, u64)
and u128 to(u64, u64)
. Let me enhance memcomparable for i128/u128 at the same time, which I should have done weeks earlier ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not quite sure about code here, so let's change it to skip_bytes
for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Add a distinct / group-by test to prevent someone "fix" HashKeySize
accidentally.
select distinct v::int256 from generate_series(1, 1, 1) as t(v);
@lmatz What is the recommended way of documenting such experimental features? |
I hereby agree to the terms of the RisingWave Labs, Inc. Contributor License Agreement.
What's changed and what's your intention?
rw_int256
(DataType::Int256
)+
/-
/*
//
/%
and unary-
,abs
A new type should also be working automatically for
is null
,case when
,coalesce
,nullif
,in
.Limitation:
HashKeySerDe
cannot be implemented, soHashKeySize::Variable
is used.Not implemented until necessary:
+
(useless)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 #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
Documentation
Click here for Documentation
Types of user-facing changes
Please keep the types that apply to your changes, and remove the others.
Release note