-
Notifications
You must be signed in to change notification settings - Fork 598
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(types): add Fields trait and derive macro #13862
Conversation
Signed-off-by: TennyZhuang <[email protected]>
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.
license-eye has totally checked 4559 files.
Valid | Invalid | Ignored | Fixed |
---|---|---|---|
2006 | 1 | 2552 | 0 |
Click to see the invalid file list
- src/common/src/types/with_data_type.rs
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: TennyZhuang <[email protected]>
Signed-off-by: TennyZhuang <[email protected]>
src/common/fields-derive/src/lib.rs
Outdated
use syn::Data; | ||
use syn::DeriveInput; | ||
use syn::Field; | ||
use syn::Result; |
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 unsure why cargo fmt
can't help me to merge them here, but I don't like to fix it manually. I guess there are many similar fmt issues in the whole codebase. Let's investigate why cargo fmt
doesn't work and fix them all later.
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.
cargo fmt
works on my machine 🤡
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.
Maybe you are not in the root dir?
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.
brew uninstall rustfmt
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.
Others LGTM
@@ -7,6 +7,7 @@ members = [ | |||
"src/cmd_all", | |||
"src/common", | |||
"src/common/common_service", | |||
"src/common/fields-derive", |
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.
prefer underscore, to be consistent with others
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’s already inconsistent now, although most of them are underscores, there are still several crates using dash.
} | ||
|
||
assert_eq!( | ||
Data::fields(), |
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.
Just a hint. You can use expect_test::Expect::assert_debug_eq so you don’t have to manually write the RHS 🤪
Timestamp, Timestamptz, F32, F64, | ||
}; | ||
|
||
pub trait WithDataType { |
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 a little hard to understand why it’s needed. Add some comments?
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.
Do we have something similar before? Or can we use this trait to simplify some existing manual match
es?
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 can’t find similar thing that can be used, but I guess we may use it in somewhere. I’ll review it later.
Currently it’s just a macro helper.
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.
Rest LGTM
impl_with_data_type!(Timestamp, DataType::Timestamp); | ||
impl_with_data_type!(Timestamptz, DataType::Timestamptz); | ||
impl_with_data_type!(Interval, DataType::Interval); | ||
impl_with_data_type!(Vec<u8>, DataType::Bytea); |
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.
Is this okay?
impl_with_data_type!(Vec<u8>, DataType::Bytea); | |
impl_with_data_type!([u8], DataType::Bytea); |
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.
We may need both lines?
Timestamp, Timestamptz, F32, F64, | ||
}; | ||
|
||
pub trait WithDataType { |
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.
Do we have something similar before? Or can we use this trait to simplify some existing manual match
es?
/// A struct can implements `Fields` when if can be represented as a relational Row. | ||
pub trait Fields { | ||
/// When the struct being converted to an [`Row`](crate::row::Row) or a [`DataChunk`](crate::array::DataChunk), it schema must be consistent with the `fields` call. | ||
fn fields() -> Vec<(&'static str, DataType)>; |
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.
Should we return Cow
here?
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.
+1 for making the return value static. Maybe use lazy-static?
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.
Got it, but it increases the complexity. We can do it when it’s really used in critical path.
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.
We can use an attribute static
to control whether make it lazy static.
Please note that static
doesn't mean always more efficient.
If user only called once, and need the ownership, then we need to allocate once, return a static reference, and then allocate (clone) again.
And we can modify the signature to this:
fn fields() -> impl ToOwned<Owned = Vec<(&'static str, DataType)>> + AsRef<[(&'static str, DataType)]>;
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.
Rest LGTM!
ty, | ||
.. | ||
} = field_rs; | ||
let name = name.map_or("".to_string(), |name| name.to_string()); |
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.
Why a struct field may have no name? 🤔
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.
tuple
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.
In PostgreSQL the names would implicitly become f1
, f2
, ...
test=# select row(9, 18);
row
--------
(9,18)
(1 row)
test=# select (row(9, 18)).f1;
f1
----
9
(1 row)
test=# select to_jsonb(row(9, 18));
to_jsonb
---------------------
{"f1": 9, "f2": 18}
(1 row)
But in RisingWave this has not been supported consistently yet. Some places are empty while some places have these implicit names. Have not thought about the impact on backward compatibility if it was fixed to be pg-compatible.
No opinion on what the behavior of this place should be.
/// A struct can implements `Fields` when if can be represented as a relational Row. | ||
pub trait Fields { | ||
/// When the struct being converted to an [`Row`](crate::row::Row) or a [`DataChunk`](crate::array::DataChunk), it schema must be consistent with the `fields` call. | ||
fn fields() -> Vec<(&'static str, DataType)>; |
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.
+1 for making the return value static. Maybe use lazy-static?
Signed-off-by: TennyZhuang <[email protected]>
Signed-off-by: TennyZhuang <[email protected]>
Signed-off-by: TennyZhuang <[email protected]>
Signed-off-by: TennyZhuang <[email protected]>
Signed-off-by: TennyZhuang <[email protected]>
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #13862 +/- ##
==========================================
- Coverage 68.30% 68.25% -0.06%
==========================================
Files 1528 1531 +3
Lines 262603 262735 +132
==========================================
- Hits 179375 179320 -55
- Misses 83228 83415 +187
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
I hereby agree to the terms of the RisingWave Labs, Inc. Contributor License Agreement.
What's changed and what's your intention?
Resolve #13851
risingwave/src/common/src/types/fields.rs
Lines 38 to 76 in 585f637
Checklist
./risedev check
(or alias,./risedev c
)Documentation
Release note
If this PR includes changes that directly affect users or other significant modifications relevant to the community, kindly draft a release note to provide a concise summary of these changes. Please prioritize highlighting the impact these changes will have on users.