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
Referential actions in the Prisma Schema Language #1947
Conversation
9c92ac3
to
8d46dca
Compare
8d46dca
to
9fccafd
Compare
Supported actions: `Cascade`, `Restrict`, `NoAction`, `SetNull` and `SetDefault`. Per-database validation, e.g. `Restrict` doesn't validate on SQL Server. Defaults to: - `onUpdate`: `SetNull` on optional and `Cascade` on required relations. - `onDelete`: `SetNull` on optional and `Restrict` on required relations. Currently ALWAYS renders the actions on introspection, due to the database always has some action set.
7483bc3
to
2def366
Compare
2def366
to
18ac766
Compare
Mark some places that require work.
introspection-engine/introspection-engine-tests/tests/commenting_out/mod.rs
Outdated
Show resolved
Hide resolved
Call it with starting prisma-fmt with subcommand referential actions. STDIN takes the data model and stdout lists all allowed actions.
20f0881
to
a4032c5
Compare
We haven't been doing this for some weeks already. Updated the original comment to reflect the reality. |
If even one underlying scalar field is required, the default referential action should not be `SetNull`.
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.
Leaving a first small batch of comments. Still lots I haven't read, it's going to take some time.
introspection-engine/introspection-engine-tests/src/test_api.rs
Outdated
Show resolved
Hide resolved
@@ -117,7 +117,7 @@ impl Datamodel { | |||
let mut fields = vec![]; | |||
for model in self.models() { | |||
for field in model.scalar_fields() { | |||
if FieldType::Enum(enum_name.to_owned()) == field.field_type { | |||
if field.field_type.is_enum(enum_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.
👍
} | ||
|
||
/// Describes what happens when related nodes are deleted. | ||
#[repr(u8)] | ||
#[bitflags] |
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 find this weird — a given relation has a single referential action, so it should be a regular enum, right?
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.
Or is that impl used to denote the set of available referential actions for a connector? I'll continue reading.
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.
Your guess was right. We can set multiple of them in the connector.
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 wondering if the extra dependency is pulling its weight, but it's fine for now.
libs/datamodel/connectors/sql-datamodel-connector/src/mysql_datamodel_connector.rs
Outdated
Show resolved
Hide resolved
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.
A few more comments. I'll continue reading.
matches && same_on_delete_action && same_on_update_action | ||
} else { | ||
matches | ||
} |
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.
👍
@@ -600,7 +597,7 @@ | |||
"relationName": "AToB", | |||
"relationFromFields": [], | |||
"relationToFields": [], | |||
"relationOnDelete": "NONE", |
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 interesting, so we are not returning this anymore in case of None
? Could it break something typescript-side?
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.
Asked from the ts team.
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.
ping @millsp @williamluke4 @Jolg42 will we break some of your code?
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'll need to remove it from our typings and update some snapshots. All good on TS side.
@steebchen will also need to remove it from Go Client.
and @madebysid from Studio
Also, I see some projects also have it defined and will need to remove it, like Amplication.
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 use this atm so no problem for me
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 use it either, all good.
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.
Actually, nothing to change in TS since the field is not removed but not always passed
https://github.com/prisma/prisma/blob/7ac84453f9e096fbe6652bc0a68e2a47e15ba344/src/packages/generator-helper/src/dmmf.ts#L84
Because it's an optional field typed to string.
} | ||
} | ||
|
||
return Ok(()); |
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.
💯
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.
One last batch of comments/questions, but I'm done reading. I think maybe @do4gr should look at the introspection tests if possible, but in general ✔️
@@ -193,7 +205,7 @@ pub enum ConnectorCapability { | |||
/// Contains all capabilities that the connector is able to serve. | |||
#[derive(Debug)] | |||
pub struct ConnectorCapabilities { | |||
capabilities: Vec<ConnectorCapability>, | |||
pub capabilities: Vec<ConnectorCapability>, |
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.
Does this need to be public? Didn't check but I think there is an accessor.
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.
no it should not be public
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, @dpetrick needs it, so will leave it as-is
} | ||
|
||
/// Describes what happens when related nodes are deleted. | ||
#[repr(u8)] | ||
#[bitflags] |
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 wondering if the extra dependency is pulling its weight, but it's fine for now.
.assert_referential_action_on_update(ForeignKeyAction::Cascade) | ||
}) | ||
}); | ||
} |
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.
👍
); | ||
|
||
let message = format!( | ||
"Invalid referential action: `{}`. Allowed values: (`Restrict`, `SetNull`)", |
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 to align with current QE behaviour? I don't really understand what the PlanetScale situation after this PR is going to be.
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 planetscale should emulate the referential actions. If the mode is enabled. @dpetrick can decide which modes are enabled, but currently the emulation is WIP and not part of this PR.
Supported actions:
Cascade
,Restrict
,NoAction
,SetNull
andSetDefault
.Per-database validation, e.g.
Restrict
doesn't validate on SQL Server.Defaults to:
onUpdate
:Cascade
on optional andCascade
on required relations.onDelete
:SetNull
on optional andRestrict
on required relations.Required work
Closes: prisma/prisma#2810
Closes: prisma/prisma#5782
Closes: prisma/prisma#4711