Naming
The SQL surface was reviewed as a whole before the first release, 0.1.0
(until a version is released, renames need no aliases or upgrade script;
after it, every change needs a version and an upgrade script, see
Versioning and upgrades). Principles:
objects that cannot collide because they take an automerge argument may
use generic names where that reads better (merge, merge_agg, ||);
everything else carries the automerge_ prefix; parameter names are the
same for the same role, so named-argument calls read consistently (doc
for the document, changes for bytes, since_heads/heads, hash).
Renamed:
merge_agg_trans/merge_agg_final→automerge_merge_agg_trans/automerge_merge_agg_final.merge_agg_final(internal)has no extension type in its signature, so another extension (or a user function) of that name in the same schema would makeCREATE EXTENSIONfail, or ours block theirs; both support functions also show up in\df. The prefix removes the clash; the aggregate keeps its name.- The first parameter of
merge(automerge, bytea)andautomerge_contains(automerge, bytea):a→doc, as in every other function whose first argument is the document the bytes apply to (merge(doc => d, changes => c)).merge(a, b)andautomerge_contains(a, b)keepa,b: a pair of documents.
Considered and kept:
merge,||: required, and keyed on theautomergetype (mergeis an unreserved keyword; unqualified calls work, tested).merge_aggrather thanautomerge_merge_agg: Postgres identifies an aggregate by name and argument types, so another extension'smerge_agg(hll)ormerge_agg(anyelement)coexists with ours in the same schema, and a call on anautomergeargument resolves to ours (an exact match beats a polymorphic or cast candidate). It pairs withmergethe waystring_agg,json_object_aggpair with their scalar forms.automerge_changes/automerge_changes_meta/automerge_changes_bytes: one family with the samesince_headsparameter.automerge_save_after(Automerge's name) for the last was rejected: it would split the family, and "save" suggests a document, while the result is change chunks.automerge_get_changerather thanautomerge_change(doc, hash): a function named like the composite typeautomerge_changewould read as the function-call form of a cast to that type.automerge_change_count,automerge_heads,automerge_contains,automerge_notify(trigger functions are named for what they do, likepg_notify),automerge_from_bytea(the cast function),automerge_merge_support.automerge_to_jsonb(doc, heads)as an overload of the cast function rather thanautomerge_to_jsonb_at: same result, "the jsonb ofdoc", as ofheads; the cast is bound by OID, so the overload cannot change what the cast calls, andheads => '{}'reads well in named form.- The composite types' columns (
hash,actor,seq,start_op,op_count,time,message,deps,change): Automerge's own field names in snake case.timeis a non-reserved keyword and works unquoted as a column (SELECT seq, time FROM ..., in the regress examples);change(the change's bytes, fordecodeChange/applyChanges) was kept overbytes, which names a representation, not what it is. - The setting
pg_automerge.verify_writes: custom settings are prefixed with the extension name.