Last active
October 20, 2025 02:06
-
-
Save mk/e1e2955dc4c892ca7214185072047bda to your computer and use it in GitHub Desktop.
Datomic Query Inst Reader Issue
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
| (require '[datomic.api]) | |
| ;; this is demonstrating an issue we ran into where overwriting the | |
| ;; `#inst` reader broke `datomic.api/q` in surprising ways. | |
| (def schema | |
| [{:db/ident :exit/datetime | |
| :db/valueType :db.type/instant | |
| :db/cardinality :db.cardinality/one}]) | |
| (def conn | |
| (datomic.api/connect (doto "datomic:mem://inst-java-time-readers" datomic.api/create-database))) | |
| @(datomic.api/transact conn schema) | |
| (def db+data | |
| (:db-after | |
| @(datomic.api/transact conn [{:exit/datetime #inst "2024"} | |
| {:exit/datetime #inst "2025"} | |
| {:exit/datetime #inst "2026"}]))) | |
| ;; this works | |
| (count (datomic.api/q [:find '?f | |
| :where | |
| '[?f :exit/datetime ?exit] | |
| [(list '< '?exit (java.util.Date.))]] | |
| db+data)) | |
| ;; fails silently (returns incorrect number of results) | |
| (binding [*data-readers* (assoc *data-readers* 'inst (fn [cs] (java.util.Date/.toInstant (clojure.instant/read-instant-date cs))))] | |
| (count (datomic.api/q [:find '?f | |
| :where | |
| '[?f :exit/datetime ?exit] | |
| [(list '< '?exit (java.util.Date.))]] | |
| db+data))) | |
| ;; fails loudly with processing rule: (q__124130 ?f), message: | |
| ;; processing clause: [?f :exit/datetime ?exit], message: | |
| ;; java.lang.ClassCastException: class java.time.Instant cannot be | |
| ;; cast to class java.util.Date (java.time.Instant and java.util.Date | |
| ;; are in module java.base of loader 'bootstrap') | |
| (binding [*data-readers* (assoc *data-readers* 'inst (fn [cs] (java.util.Date/.toInstant (clojure.instant/read-instant-date cs))))] | |
| (count (datomic.api/q [:find '?f | |
| :where | |
| '[?f :exit/datetime ?exit] | |
| [(list java.util.Date/.before '?exit (java.util.Date.))]] | |
| db+data))) | |
| ;; My guess is that this is related to datomic's [query | |
| ;; caching](https://docs.datomic.com/query/query-executing.html#query-caching) | |
| ;; because once a query has been cached, a sucessive call with the | |
| ;; same query value and a bound #inst reader succeeds: | |
| (let [query [:find '?f | |
| :where | |
| '[?f :exit/datetime ?exit] | |
| [(list java.util.Date/.before '?exit (java.util.Date.))]]] | |
| (= (count (datomic.api/q query db+data)) | |
| (binding [*data-readers* (assoc *data-readers* 'inst (fn [cs] (java.util.Date/.toInstant (clojure.instant/read-instant-date cs))))] | |
| (count (datomic.api/q query db+data))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment