feat(postgres): support editing hstore columns - #427
Merged
NewtTheWolf merged 5 commits intoAug 2, 2026
Conversation
Reading hstore columns already worked (tokio-postgres decodes them natively as HashMap<String, Option<String>>), but writing back failed with 'Cannot bind a JSON object to a non-JSON column' because hstore has no fixed OID and information_schema reports it generically as 'USER-DEFINED'. - Resolve the real hstore OID per column via pg_type before binding, since it varies per installation/schema. - Bind JSON objects (and, for now, JSON-encoded strings, the plain text cell editor doesn't yet distinguish hstore from other types) as HashMap<String, Option<String>>, which tokio-postgres encodes natively as hstore. - Expose udt_name on TableColumn so the frontend can identify hstore precisely; data_type alone can't, since it's shared with every other extension/custom type. - Route hstore columns through the existing JSON editor in the row editor sidebar, and fix the inline cell editor to show valid JSON instead of '[object Object]' for any object-valued cell. Closes TabularisDB#395
NewtTheWolf
requested changes
Jul 13, 2026
NewtTheWolf
left a comment
Collaborator
There was a problem hiding this comment.
Thanks for tackling this — resolving the per-install OID via pg_type and leaning on tokio-postgres's native HashMap encoding is the right approach, and the binding-layer test coverage is solid. 🙏
One blocking correctness issue inline: the USER-DEFINED fallback in the bind routing regresses editing of other user-defined types (enums, citext, PostGIS…). Fix + a note on the affected test are inline.
Non-blocking, your call:
bind_pg_hstoreduplicates the oid-resolve →hstore_map_from_json_object→Type::new→BoundValueblock across theObjectandStringarms — could fold into a small local closure.get_hstore_oid_for_columnfires one catalog query perUSER-DEFINEDcolumn per row in theinsert_recordloop — fine for single-row edits, worth caching if bulk insert ever routes through here.Type::new(..., "public")hardcodes the schema; harmless sinceprepare_typedpins on the OID, just noting hstore can live in another schema.
Also: the branch currently has a merge conflict against main (mergeStateStatus: DIRTY) — could you rebase/resolve that when you get a chance? 🙏
…folding from TabularisDB#450 data_type now reports the real udt_name for user-defined types, so: - gate hstore OID resolution on data_type == "hstore" instead of "USER-DEFINED" - route bind_pg_value by column_type == "hstore" so the unresolved-OID error stays reachable - drop the now-redundant udt_name field from TableColumn and the frontend types - port the row editor change to the type-based isHstoreColumn check (RowEditorSidebar was replaced by RowEditorPanel in TabularisDB#510)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reading hstore columns already worked (tokio-postgres decodes them natively as HashMap<String, Option>), but writing back failed with 'Cannot bind a JSON object to a non-JSON column' because hstore has no fixed OID and information_schema reports it generically as 'USER-DEFINED'.
Closes #395