Skip to content

Instantly share code, notes, and snippets.

@souenzzo
Last active July 22, 2018 02:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save souenzzo/c7b5a5434d4c04efcc58802c81b46023 to your computer and use it in GitHub Desktop.
Save souenzzo/c7b5a5434d4c04efcc58802c81b46023 to your computer and use it in GitHub Desktop.
datomic-issue

The problem

Some queries behave differently depending on whether the transactor is remote or not.

The "alternative query" (QUERY2 on code) not show this bug. But QUERY1 do.

Steps do reproduce

Start a "free" transactor

$ ./bin/transactor config/samples/free-transactor-template.properties 
# Launching with Java options -server -Xms1g -Xmx1g -XX:+UseG1GC -XX:MaxGCPauseMillis=50
# Starting datomic:free://localhost:4334/<DB-NAME>, storing data in: data ...
# System started datomic:free://localhost:4334/<DB-NAME>, storing data in: data

Run this project

  • with a memory db (no bugs)
$ clj -Sdeps '{:deps {datomic-issue {:git/url "https://gist.github.com/souenzzo/c7b5a5434d4c04efcc58802c81b46023" :sha "55e2ed827416487dc2ba302de2756c270a1d8753"}}}' -m datomic-issue 'datomic:mem://bug'
# start test using ["datomic:mem://bug" [:find ?e :in $ ?ignore :where [?e :db/ident ?ident] (not [(contains? ?ignore ?ident)])]]
# end test using ["datomic:mem://bug" [:find ?e :in $ ?ignore :where [?e :db/ident ?ident] (not [(contains? ?ignore ?ident)])]]
  • with free db (bugs!!!!)
$ clj -Sdeps '{:deps {datomic-issue {:git/url "https://gist.github.com/souenzzo/c7b5a5434d4c04efcc58802c81b46023" :sha "55e2ed827416487dc2ba302de2756c270a1d8753"}}}' -m datomic-issue 'datomic:free://localhost:4334/bug'
# start test using ["datomic:free://localhost:4334/bug" [:find ?e :in $ ?ignore :where [?e :db/ident ?ident] (not [(contains? ?ignore ?ident)])]]
# 
# FAIL in (check-for-bugs) (datomic_issue.clj:51)
# # as at conn, db = db-after, the transaction should fail
# expected: (thrown? ExecutionException (clojure.core/deref (d/transact conn tx-data)))
#   actual: nil
# end test using ["datomic:free://localhost:4334/bug" [:find ?e :in $ ?ignore :where [?e :db/ident ?ident] (not [(contains? ?ignore ?ident)])]]
  • with a memory db + alternative query (no bugs)
$ clj -Sdeps '{:deps {datomic-issue {:git/url "https://gist.github.com/souenzzo/c7b5a5434d4c04efcc58802c81b46023" :sha "55e2ed827416487dc2ba302de2756c270a1d8753"}}}' -m datomic-issue 'datomic:mem://bug' true
# start test using ["datomic:mem://bug" [:find ?e :in $ ?ignore :where [?e :db/ident ?ident] [(contains? ?ignore ?ident) ?q] [(ground false) ?q]]]
# end test using ["datomic:mem://bug" [:find ?e :in $ ?ignore :where [?e :db/ident ?ident] [(contains? ?ignore ?ident) ?q] [(ground false) ?q]]]
  • with a free db + alternative query (no bugs)
$ clj -Sdeps '{:deps {datomic-issue {:git/url "https://gist.github.com/souenzzo/c7b5a5434d4c04efcc58802c81b46023" :sha "55e2ed827416487dc2ba302de2756c270a1d8753"}}}' -m datomic-issue 'datomic:free://localhost:4334/bug' true
# start test using ["datomic:free://localhost:4334/bug" [:find ?e :in $ ?ignore :where [?e :db/ident ?ident] [(contains? ?ignore ?ident) ?q] [(ground false) ?q]]]
# end test using ["datomic:free://localhost:4334/bug" [:find ?e :in $ ?ignore :where [?e :db/ident ?ident] [(contains? ?ignore ?ident) ?q] [(ground false) ?q]]]
(ns datomic-issue
(:require [datomic.api :as d]
[clojure.test :refer :all])
(:import (clojure.lang ExceptionInfo)
(java.util.concurrent ExecutionException)))
(def empty-query?
(d/function '{:lang :clojure
:requires [[datomic.api :as d]]
:params [db query & args]
:code (when-not (->> (into [db] args)
(hash-map :query query :args)
(d/query)
(empty?))
(throw (ex-info "ERROR" {})))}))
(def QUERY1
"Bug occurs with this query"
'[:find ?e
:in $ ?ignore
:where
[?e :db/ident ?ident]
(not [(contains? ?ignore ?ident)])])
(def QUERY2
"Bug DO NOT occurs with this query"
'[:find ?e
:in $ ?ignore
:where
[?e :db/ident ?ident]
[(contains? ?ignore ?ident) ?q]
[(ground false) ?q]])
(def ^:dynamic conn)
(def ^:dynamic QUERY)
(deftest check-for-bugs
(let [{db :db-after} @(d/transact conn [{:db/fn empty-query? :db/ident ::empty-query?}])
idents (set (d/q '[:find [?ident ...] :where [?e :db/ident ?ident]] db))
new-ident (keyword "my-ident" (format "ident-" (count idents)))
tx-data [{:db/ident new-ident} [::empty-query? QUERY idents]]
{:keys [db-after]} @(d/transact conn [{:db/ident ::new-one!}])]
(testing
"at db, the transaction should success"
(is (map? (d/with db tx-data))))
(testing
"at db-after, the transaction should fail"
(is (thrown? ExceptionInfo (d/with db-after tx-data))))
(testing
"as at conn, db = db-after, the transaction should fail"
(is (thrown? ExecutionException @(d/transact conn tx-data))))))
(defn -main
[db-uri & [alternative-query?]]
(if (d/create-database db-uri)
(try
(let [connection (d/connect db-uri)]
(binding [QUERY (if alternative-query? QUERY2 QUERY1)
conn connection]
(printf "start test using %s\n" [db-uri QUERY])
(check-for-bugs)
(printf "end test using %s\n" [db-uri QUERY]))
(d/release connection))
(finally
(d/delete-database db-uri)))
(printf "this db already exists %s\n" db-uri))
(flush)
(System/exit 0))
{:paths ["."]
:deps {org.clojure/clojure {:mvn/version "1.9.0"}
com.datomic/datomic-free {:mvn/version "0.9.5697"}
org.clojure/test.check {:mvn/version "0.10.0-alpha3"}}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment