pg_mentat implements the core Datomic data model and query language as a PostgreSQL extension. This document reflects the actual implementation status of the current codebase.
pg_mentat provides Datomic-compatible schema, transactions, and Datalog queries via SQL functions. The companion mentatd server exposes an HTTP API compatible with Datomic client libraries.
Feature Datomic pg_mentat Status
:db/addYes Yes Complete
:db/retractYes Yes Complete
:db/retractEntityYes Yes Complete -- cascade via :db/isComponent
:db.fn/casYes Yes Complete -- compare-and-swap
with (speculative)Yes Yes Complete -- mentat_with()
Map notation Yes Yes Complete
Tempids Yes Yes Complete
Lookup refs Yes Yes Complete
Upsert (unique/identity) Yes Yes Complete
Tx metadata (:db/txInstant) Yes Yes Complete
Negative tempids Yes No N/A -- use string tempids
:db/fn (database functions)Yes No Not Planned -- security risk
Feature Datomic pg_mentat Status
Relation [:find ?x ?y] Yes Yes Complete
Collection [:find [?x ...]] Yes Yes Complete
Tuple [:find [?x ?y]] Yes Yes Complete
Scalar [:find ?x .] Yes Yes Complete
Feature Datomic pg_mentat Status
Basic patterns Yes Yes Complete
NOT clauses Yes Yes Complete -- NOT EXISTS subquery
NOT-JOIN Yes Yes Complete
OR clauses Yes Yes Complete -- UNION
OR-JOIN Yes Yes Complete
Feature Datomic pg_mentat Status
Scalar :in ?x Yes Yes Complete
Collection :in [?x ...] Yes Yes Complete
Tuple :in [?x ?y] Yes Yes Complete
Relation :in [[?x ?y]] Yes Yes Complete
Function Datomic pg_mentat Status
get-elseYes Yes Complete -- LEFT JOIN + COALESCE
missing?Yes Yes Complete -- NOT EXISTS subquery
groundYes Yes Complete -- constant binding
get-someYes No Not implemented
tupleYes No Not implemented
untupleYes No Not implemented
Feature Datomic pg_mentat Status
=, !=Yes Yes Complete
<, >, <=, >=Yes Yes Complete
Arithmetic (+, -, *, /) Yes Yes Complete
like / ilikeN/A Yes Extension -- PostgreSQL LIKE/ILIKE
Type-safety guard Yes Yes Complete -- mismatched types produce empty set
Aggregate Datomic pg_mentat Status
countYes Yes Complete
count-distinctYes Yes Complete
sumYes Yes Complete
minYes Yes Complete
maxYes Yes Complete
avgYes Yes Complete
sampleYes Yes Complete
medianYes No Not implemented
varianceYes No Not implemented
stddevYes No Not implemented
Feature Datomic pg_mentat Status
Named rules Yes Yes Complete
Recursive rules Yes Yes Complete -- WITH RECURSIVE CTE
Rule sets (multiple heads) Yes Yes Complete
Rules with predicates Yes Yes Complete
Feature Datomic pg_mentat Status
Attribute selection Yes Yes Complete
Wildcard [*] Yes Yes Complete
Reverse lookup [:_attr] Yes Yes Complete
Nested/map specs Yes Yes Complete
Recursion {:attr ...} Yes Yes Complete -- cycle detection
Bounded recursion {:attr N} Yes Yes Complete
Default values Yes Yes Complete
Rename (:as) Yes Yes Complete
Limit (:limit N) Yes Yes Complete
Component auto-expand Yes Yes Complete
pull-manyYes Yes Complete
Namespace wildcard Yes No Not implemented
Feature Datomic pg_mentat Status
:db/identYes Yes Complete
:db/valueTypeYes Yes Complete (9 types)
:db/cardinalityYes Yes Complete (one/many)
:db/unique (value)Yes Yes Complete
:db/unique (identity)Yes Yes Complete + upsert
:db/indexYes Yes Complete
:db/fulltextYes Yes Complete -- BM25 scoring
:db/isComponentYes Yes Complete -- cascade retraction
:db/noHistoryYes Yes Complete
:db/docYes Yes Complete
Schema alteration Yes Yes Complete
Type Datomic pg_mentat Storage
:db.type/booleanYes Yes BOOLEAN in datoms_boolean_new
:db.type/longYes Yes BIGINT in datoms_long_new
:db.type/doubleYes Yes DOUBLE PRECISION in datoms_double_new
:db.type/stringYes Yes TEXT in datoms_text_new
:db.type/keywordYes Yes TEXT in datoms_keyword_new
:db.type/refYes Yes BIGINT in datoms_ref_new
:db.type/instantYes Yes TIMESTAMPTZ in datoms_instant_new
:db.type/uuidYes Yes UUID in datoms_uuid_new
:db.type/bytesYes Yes BYTEA in datoms_bytes_new
:db.type/bigintYes No Not implemented
:db.type/bigdecYes No Not implemented
:db.type/uriYes No Not Planned -- use string
:db.type/tupleYes No Not Planned -- Datomic Cloud only
Feature Datomic pg_mentat Status
as-ofYes Yes Complete -- mentat_as_of()
sinceYes Yes Complete -- mentat_since()
historyYes Yes Complete -- mentat_history()
tx-rangeYes Yes Complete -- mentat_tx_range()
Basis-t Yes Yes Complete -- MAX(tx) query
Feature Datomic pg_mentat Status
Entity excision Yes Yes Complete -- mentat_excise()
Partition gating Yes Yes Complete -- allow_excision flag
Schema protection Yes Yes Complete -- entid < 10000 blocked
Dangling ref check Yes Yes Complete
Excision log N/A Yes Extension -- audit trail
Feature Datomic pg_mentat Status
tx-report-queue Yes Yes Complete -- LISTEN/NOTIFY triggers
Subscribe by query No Yes Extension -- mentat_subscribe()
Unsubscribe Yes Yes Complete -- mentat_unsubscribe()
Feature Datomic Client mentatd Status
list-databases Yes Yes Complete
create-database Yes Yes Complete
delete-database Yes Yes Complete
connect Yes Yes Complete
transact Yes Yes Complete
query Yes Yes Complete
pull Yes Yes Complete
entity Yes Yes Complete
EDN serialization Yes Yes Complete
Transit+JSON Yes Yes Complete
CORS N/A Yes Complete
HTTP/2 Yes No Not implemented
Streaming responses Yes No Not implemented
Feature Reason Workaround
:db/fnSecurity risk -- arbitrary code execution Application logic
Peer mode Architecture incompatible (embedded JVM) Use mentatd HTTP API
Datomic Analytics Proprietary PostgreSQL analytics tools
Negative tempids Not supported Use string tempids
Peer cache No equivalent Application-layer caching
Schema definitions transfer directly. Remove #db/id partition references:
;; Datomic
[{:db/id #db/id[:db.part/db]
:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}]
;; pg_mentat (same minus partition boilerplate)
[{:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}]
Queries work unchanged. Transactions work unchanged. Pull patterns work unchanged.