You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Edge Validation and Constraint Validation of the @uniqueForTarget directive have very similar roles. Theoretically the only difference between them is that the edge validation checks that the source has one one such edge (when not a list), while the constraint makes sure the target only has one such edge. But they are implemented very differently:
The Edge validation is enforced during the transaction, while the constraint is not enforced until finishing the transaction.
This behavior might need to be standardized to avoid some confusion.
But it also leads to the question of how to standardized it. Do we want to enforce them both during or just before finishing the transaction? If not done carefully both alternatives might actually lead to some very strange results while mixing queries with transactions.
Take the following example schema:
We also assume we have some (custom)query that takes an id of a Source object and returns the total number of edges originating from the Source with that id: NumberOfEdgesFromSource(ID!): Int.
As I am not really sure how the exact syntax for reusing results during transactions will look like, I will just use the following to represent this:
createObject(data: SomeData)
{
idbindX
}
Where X is now a variabel we can reuse in further steps of the transaction.
Now take the following two, similar but different, transactions which demonstrates the differences between the two methods of enforcement following how they are current implemented:
1.
Transaction 1 will fail early as the edge validation will throw an error as we are trying to put two edges into a field that takes only one edge. Even if the results of the complete transaction would actually be correct according to the schema.
Transaction 2 will not fail as the end results is correct according to the schema. But the value returned from the intermediate query would be two, which does not fit with what one might expect, as there is only one edge after the transaction has finished.
This is of course quite an harmless example. There might be worse cases where the results from the intermediate query is then reused in further mutations and where these non-correct states basically leads to data loss or data corruption. Depending in how schemas are built, this might even turn out to be a security flaw.
A solution would be to implement intermediate sub-transactions where correct state is enforced before each intermediate query in an transaction.
But the question is: do we really care? Will this actually be doable in practice, or will we not allow queries during transactions?
Edge Validation and Constraint Validation of the
@uniqueForTarget
directive have very similar roles. Theoretically the only difference between them is that the edge validation checks that the source has one one such edge (when not a list), while the constraint makes sure the target only has one such edge. But they are implemented very differently:The Edge validation is enforced during the transaction, while the constraint is not enforced until finishing the transaction.
This behavior might need to be standardized to avoid some confusion.
But it also leads to the question of how to standardized it. Do we want to enforce them both during or just before finishing the transaction? If not done carefully both alternatives might actually lead to some very strange results while mixing queries with transactions.
Take the following example schema:
Notice the differences between the edges here.
We also assume we have some (custom)query that takes an id of a
Source
object and returns the total number of edges originating from theSource
with that id:NumberOfEdgesFromSource(ID!): Int
.As I am not really sure how the exact syntax for reusing results during transactions will look like, I will just use the following to represent this:
Where X is now a variabel we can reuse in further steps of the transaction.
Now take the following two, similar but different, transactions which demonstrates the differences between the two methods of enforcement following how they are current implemented:
1.
Transaction 1 will fail early as the edge validation will throw an error as we are trying to put two edges into a field that takes only one edge. Even if the results of the complete transaction would actually be correct according to the schema.
Transaction 2 will not fail as the end results is correct according to the schema. But the value returned from the intermediate query would be two, which does not fit with what one might expect, as there is only one edge after the transaction has finished.
This is of course quite an harmless example. There might be worse cases where the results from the intermediate query is then reused in further mutations and where these non-correct states basically leads to data loss or data corruption. Depending in how schemas are built, this might even turn out to be a security flaw.
A solution would be to implement intermediate sub-transactions where correct state is enforced before each intermediate query in an transaction.
But the question is: do we really care? Will this actually be doable in practice, or will we not allow queries during transactions?
@hartig @keski @rcapshaw
The text was updated successfully, but these errors were encountered: