Expand description
Cell-level row editing for the explorer.
Sprint 14 model: editing is enabled only on tabs opened from the
schema browser (“double-click a relation”), where the explorer
knows the (schema, table) and the auto-generated SELECT carries
ctid AS __pg_rowid__. The UI extracts that hidden column to use
as the row identifier for UPDATEs.
§Why ctid
ctid is Postgres’s internal per-row identifier on heap tables.
It is:
- Always unique within a relation (so the WHERE matches at most one row).
- Always present (no PK assumption needed).
- Mutated on every UPDATE — which gives us free optimistic locking. If two clients race to edit the same row, the second UPDATE matches zero rows and we surface “row no longer there” instead of clobbering.
Limitation: views, materialized views, and foreign tables don’t have a meaningful ctid. We don’t try to edit them; the UI gates editing on the relation kind already.
§Type binding
Values cross the FFI as String. We bind $1 as text and cast
it to the column’s declared type server-side: SET "col" = $1::int4.
Postgres’s text-input parser handles the heavy lifting (timestamps,
arrays, ranges, JSON). Setting NULL skips the parameter entirely
since ''::int4 would fail.
Identifiers are quoted defensively (PG allows mixed-case and
reserved-word identifiers; an unquoted Order would target a
lowercase order). Type names from pg_type.typname are also
quoted to be safe — most don’t need it but the cost is zero.
Structs§
- Insert
Column Input - One column’s worth of input for an INSERT. Caller emits a list
of these for the columns it wants to set explicitly; columns not
in the list are left to the server’s
DEFAULT(which honorspg_attrdef-defined defaults, sequences, generated values, etc). - Inserted
Row - Update
Outcome
Functions§
- delete_
rows - Delete one or more rows identified by their ctids. Returns the number of rows actually deleted (callers compare against the requested count to surface “some rows were already gone” — the same optimistic-locking semantic as cell UPDATEs).
- insert_
row - Insert one row, returning the requested columns for the new row.
- update_
cell - Issue a single-cell UPDATE.
new_value: Nonemeans SET NULL.column_typeis the column’spg_type.typname(e.g.int4,timestamptz); used for the server-side text→typed cast.