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
{{ message }}
Repository navigation
UpdateColumns can reuse cached update plans across column filters #15
DbMap.UpdateColumns can reuse an update plan generated by an earlier Update
or UpdateColumns call with a different ColumnFilter. The filter is part of
the caller's intended write set, so a filtered update can still generate SQL and
bind values for columns rejected by the current filter.
Affected area
Tested on main at c0288adf3b533244dd2bf2fca08ca4418b25d281.
Affected paths:
DbMap.Update
DbMap.UpdateColumns
TableMap.bindUpdate
Reproduction
A focused regression uses a database/sql capture driver. First call Update
for a row with PublicNote, Admin, and Balance. Then call UpdateColumns
with a filter that only accepts PublicNote.
Expected second query:
update "security_rows" set "PublicNote"=? where "ID"=?;
Actual second query:
update "security_rows" set "PublicNote"=?, "Admin"=?, "Balance"=? where "ID"=?;
The second call also binds values for Admin and Balance.
Impact
Consumer code that treats UpdateColumns as an allowed-column boundary can
unintentionally write protected fields after another path has primed the
table's cached update plan.
Root cause
TableMap.bindUpdate caches one updatePlan per table through plan.once.Do.
The cached plan is keyed by the table, not by the supplied ColumnFilter, so
the first call's filter controls later calls.
Suggested fix
Keep cached update plans for unfiltered updates, but build filtered update plans
per call, or key filtered plans by an explicit stable filter identity.
Add regression coverage for full-to-filtered and filtered-to-filtered update
sequences.
Thanks for the report. Since Boulder doesn't use UpdateColumns, and borp is maintained for Boulder's use, I'd like to delete UpdateColumns and the concept of a column filter.
That makes sense. I checked Boulder usage and only found UpdateColumns / ColumnFilter in the vendored borp copy, not in Boulder application code.
I will stop pursuing the cached-plan preservation patch and switch to a smaller removal PR that deletes DbMap.UpdateColumns, Transaction.UpdateColumns, ColumnFilter, and the filter plumbing/tests. I will keep the removal PR linked here.
Activity
jsha commentedon Jun 11, 2026
Thanks for the report. Since Boulder doesn't use UpdateColumns, and borp is maintained for Boulder's use, I'd like to delete UpdateColumns and the concept of a column filter.
akshithg commentedon Jun 11, 2026
That makes sense. I checked Boulder usage and only found
UpdateColumns/ColumnFilterin the vendored borp copy, not in Boulder application code.I will stop pursuing the cached-plan preservation patch and switch to a smaller removal PR that deletes
DbMap.UpdateColumns,Transaction.UpdateColumns,ColumnFilter, and the filter plumbing/tests. I will keep the removal PR linked here.akshithg commentedon Jun 11, 2026
@jsha #19 removes UpdateColumns and the concept of a column filter
Remove UpdateColumns (letsencrypt#19)