Limit update() to only work on primary keys#1862
Conversation
|
Please also update the API proposal |
|
Should we change the API? If updates are only by PK, and a table has at most one PK, then they don't really belong on unique indices, do they? Should it be EDIT: Or do we want to leave it on the PK index to make it clear how the old row is found during the update? |
4d5a078 to
64a2b2b
Compare
I think that's beneficial - I just added a section in the doc comment for |
64a2b2b to
43d33e0
Compare
43d33e0 to
91d3aa6
Compare
|
I'm going to try to get this to merge, but I don't want to make the |
91d3aa6 to
947f95a
Compare
|
That should be working for the rust module bindings. |
Restrict `update()` in both Rust and C# module bindings to only work on primary key columns, not all unique columns. Calling `update()` on a non-PK unique column is semantically a delete+insert — clients won't see it as a row update unless the primary key stays the same. Rust changes: - Add `PrimaryKey` marker trait in `crates/bindings/src/table.rs` - Add `where Col: PrimaryKey` bound on `UniqueColumn::update()` - Generate `impl PrimaryKey` in the bindings macro for PK columns C# changes: - Only emit `Update()` on `UniqueIndex` when the column is a PK - Update `unique_*` test reducers to use `Delete()`+`Insert()` instead Closes #1862
|
Closing in favor of #4279, which re-implements this on top of current master and extends the change to C# and TypeScript module bindings as well. |
## Summary - Restricts `update()` across all three server-side SDKs (Rust, C#, TypeScript) to only work on primary key columns, not all unique columns - Calling `update()` on a non-PK unique column is semantically a delete+insert — clients won't see it as a row update unless the primary key stays the same - Fresh re-implementation of #1862, extended to cover C# and TypeScript bindings ### Design principle Primary key is a constraint on columns, not a property of indexes. An index is unique or not unique — whether `update()` is available is derived from the column's attributes at the point of use, not stored on the index. This differs from #1862 which introduced a `Uniqueness` enum (`No | Unique | PrimaryKey`) on the index itself. Instead, we keep `is_unique: bool` and check the column metadata where needed. ### Rust changes - Add `PrimaryKey` marker trait and `where Col: PrimaryKey` bound on `UniqueColumn::update()` - `marker_type()` receives `primary_key_column` and checks the column directly — no `is_pk` field on the index - `sdk-test` unique tables use `update_non_pk_by` (delete+insert) instead of `update_by` - Benchmarks that used `update()` on `#[unique]` columns changed to either `#[primary_key]` or delete+insert ### C# changes - Only emit `Update()` on `UniqueIndex` when the column has `PrimaryKey` attrs - Update `unique_*` test reducers in `sdk-test-cs` to use `Delete()`+`Insert()` instead ### TypeScript changes - `UniqueIndex` now has only `find` + `delete` (no `update`) - `AllColumnsPrimaryKey` type-level helper checks column metadata from the `TableDef` - `Index` routing conditionally intersects `{ update() }` when columns are PK - Runtime only attaches `update` method for PK unique indexes - `sdk-test-ts` unique tables use delete+insert instead of update - Type-level test in `schema.test-d.ts` verifies `id.update()` compiles (PK) and `name2.update` errors (non-PK unique) ## Test plan - [x] C# codegen tests pass (`dotnet test crates/bindings-csharp/Codegen.Tests`) - [x] Rust SDK test module compiles - [x] Benchmarks compile - [x] TypeScript type checks pass (`npx tsc --noEmit`) - [ ] CI passes Closes #1862
Description of Changes
@cloutiertyler and I were talking about this. Makes the semantic mapping for people easier, a row update on the client is an update() on the server. Doesn't make sense for non-pk to have
.update()but it doesn't trigger an update.Expected complexity level and risk
1