-
Notifications
You must be signed in to change notification settings - Fork 142
feat: add allow_missing for fields in DeserializeRow #1416
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
base: main
Are you sure you want to change the base?
Conversation
67e73b9 to
820386a
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.
Pull Request Overview
This PR adds an allow_missing attribute to struct fields for both row and value deserialization, allowing fields to be initialized with Default::default() when missing from the database instead of failing. This feature provides compatibility with sqlx's #[sqlx(default)] attribute for smoother migration to scylla-rust-driver.
- Implements
#[scylla(allow_missing)]attribute for both struct-level and field-level usage - Adds support for the attribute in both row and value deserialization contexts
- Includes comprehensive test coverage for the new functionality
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| scylla-macros/src/lib.rs | Adds documentation for the new allow_missing attribute |
| scylla-macros/src/serialize/value.rs | Adds ignored allow_missing attribute parsing for value serialization |
| scylla-macros/src/serialize/row.rs | Adds ignored allow_missing attribute parsing for row serialization |
| scylla-macros/src/deserialize/value.rs | Implements allow_missing logic for value deserialization |
| scylla-macros/src/deserialize/row.rs | Implements allow_missing logic for row deserialization |
| scylla/tests/integration/macros/hygiene.rs | Adds hygiene tests for the new attribute |
| scylla-cql/src/deserialize/row_tests.rs | Adds comprehensive tests for allow_missing functionality |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
820386a to
7091295
Compare
7091295 to
74184aa
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.
Sorry for the delay! Please rebase on main to make semver checks work again.
| #[test] | ||
| fn test_struct_deserialization_loose_ordering_allow_missing() { | ||
| #[derive(DeserializeRow, PartialEq, Eq, Debug)] | ||
| #[scylla(crate = "crate")] | ||
| #[scylla(allow_missing)] |
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.
Please let's do one thing in this PR. Other field attributes can't be used on a struct, so let's remove this ability from this one as well, at least for now. It will also simplify this PR a lot.
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.
sorry, i don't understand what your intention is, is it start with scylla[allow_missing] field attributes in this PR, and put scylla[allow_missing] in struct attributes in another (next) PR?
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 how understand this. Also, if we choose to allow this attribute to be put on a struct, then we want to allow others as well. Therefore, such another PR would necessarily by larger.
For now, not to impede the per-field attribute, let's strip this PR and get it merged.
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.
sorry, i don't understand what your intention is, is it start with scylla[allow_missing] field attributes in this PR, and put scylla[allow_missing] in struct attributes in another (next) PR?
In another PR, or maybe not at all - we will have to decide if we want to include such functionality in the driver.
I see "using field attributes on a struct" as a totally separate matter from "using allow_missing in DeserializeRow", so I think it should not be put in a single commit or PR.
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.
Hi! sorry for the delay, removing struct attribute and add enforce_order functionalities based on DeserializeValue code is done in my latest commit
74184aa to
27a4fa3
Compare
27a4fa3 to
4c8defe
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.
Pull Request Overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
scylla-macros/src/lib.rs
Outdated
| /// | ||
| /// #[scylla(allow_missing)] | ||
| /// | ||
| /// if set, implementation will not fail if some columns are missing. |
Copilot
AI
Oct 31, 2025
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.
Inconsistent capitalization: sentence should start with a capital letter. Change 'if set' to 'If set'.
| /// if set, implementation will not fail if some columns are missing. | |
| /// If set, implementation will not fail if some columns are missing. |
| /// | ||
| /// #[scylla(allow_missing)] | ||
| /// | ||
| /// if set, implementation will not fail if some columns are missing. |
Copilot
AI
Oct 31, 2025
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.
Inconsistent capitalization: sentence should start with a capital letter. Change 'if set' to 'If set'.
| /// if set, implementation will not fail if some columns are missing. | |
| /// If set, implementation will not fail if some columns are missing. |
scylla-macros/src/lib.rs
Outdated
| /// If the value of the field received from DB is null, the field will be | ||
| /// initialized with `Default::default()`. |
Copilot
AI
Oct 31, 2025
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 documentation is incorrect. For DeserializeValue, the allow_missing attribute should handle missing fields in the UDT definition, not null values. The description should say 'If the UDT definition does not contain this field' similar to the field-level documentation at line 528.
| /// If the value of the field received from DB is null, the field will be | |
| /// initialized with `Default::default()`. | |
| /// If the UDT definition does not contain this field, it will be initialized | |
| /// with `Default::default()`. |
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.
🌱 Hmm, perhaps Copilot is right? Perhaps a better name would be allow_null? cc @Lorak-mmk
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 allow_missing struct attributes docs that i forgot to delete, mb!
add allow_missing field attribute with macro DeserializeRow to handle partial deserialization
4c8defe to
fd9db3f
Compare
| // If true, then - if this field is missing from the UDT fields metadata | ||
| // - it will be initialized to Default::default(). | ||
| #[darling(default)] | ||
| #[darling(rename = "allow_missing")] | ||
| default_when_missing: bool, | ||
|
|
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 DeserializeRow, not DeserializeValue, so UDTs are not applicable here. It should be changed to "if this field is missing from the query result metadata"
| let cql_name_literal = field.cql_name_literal(); | ||
| let decrement_if_required: Option<syn::Stmt> = field | ||
| .is_required() | ||
| let decrement_if_required: Option<syn::Stmt> = field.is_required() |
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.
nitpick: changes in this file are only formatting (and btw its surprising that rustfmt accepts both formattings). Those changes are not necessary here.
|
|
||
| // Used for deserialization only. Ignored in serialization. | ||
| #[darling(default)] | ||
| #[darling(rename = "allow_missing")] | ||
| _default_when_missing: bool, |
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 don't see why this is necessary. The PR adds support for allow_missing in DeserializeRow, it should not need to touch SerializeValue. Even before this PR we had the following struct in tests:
// Test attributes for value struct with name flavor
#[derive(
_scylla::DeserializeValue, _scylla::SerializeValue, PartialEq, Debug,
)]
#[scylla(crate = _scylla)]
#[allow(dead_code)] // TODO: Change to expect after bumping MSRV to 1.89
struct TestStructByName {
a: ::core::primitive::i32,
#[scylla(allow_missing)]
b: ::core::primitive::i32,
#[scylla(default_when_null)]
c: ::core::primitive::i32,
#[scylla(skip)]
d: ::core::primitive::i32,
#[scylla(rename = "f")]
e: ::core::primitive::i32,
g: ::core::primitive::i32,
}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.
Ah, those are struct attributes, not fields attributes. It makes this change even more unnecessary.
|
|
||
| // Used for deserialization only. Ignored in serialization. | ||
| #[darling(default)] | ||
| #[darling(rename = "allow_missing")] | ||
| _default_when_missing: bool, |
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 struct with struct-level attributes, this should not be required 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.
I tried to understand changes in this file but I'm not able to. It looks like apart from adding support for new attribute, you also performed a bunch of refactors. This is fine in general, but such refactors should be split into commits. Each of those commits should be working, and should be easy to understand for reviewers.
We have limited review throughput, so we always try to make sure that review is reasonably easy, even if it means more work for the contributor.
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 code structure on deserializeRow on enforce order is similiar like deserializeValue on enforce order flavor, but i think i rush it too much, i will convert it into draft, apply the suggestion and split the commit,
thank you for your time to checking my PR.
Fixes: #1146
Add #[allow_missing] in the field attribute for DeserializeRow macro both on enforce_order flavor and match_by_name flavor
Pre-review checklist
./docs/source/.Fixes:annotations to PR description.