Fork me on GitHub
#datomic
<
2023-05-24
>
steveb8n00:05:40

Q: I’m trying to use clojure.core/compare in a query rule for Cloud. I get a strange exception. Deets in thread….

steveb8n00:05:58

clojure.lang.ExceptionInfo: Unable to resolve symbol: tx-data in this context
         cognitect.anomalies/category: :cognitect.anomalies/fault
          cognitect.anomalies/message: "Unable to resolve symbol: tx-data in this context"
         datomic.client-spi/exception: com.google.common.util.concurrent.UncheckedExecutionException
        datomic.client-spi/request-id: "38a341e3-784a-440e-a698-b22a985cc2a5"
    datomic.client-spi/root-exception: java.lang.RuntimeException
                                  dbs: [{:database-id "bc6549ca-5e23-47d0-bb13-b185f5c8d9f5",
                                         :t 9034,
                                         :next-t 9035,
                                         :history false}]

steveb8n00:05:36

I’ve added clojure.core/compare to the :allow list in ion-config

steveb8n00:05:38

Is this a known problem?

steveb8n00:05:07

I’ll try to workaround using some other fn for now

steveb8n00:05:39

false alarm. it was not the compare fn. it was another invalid rule

steveb8n00:05:01

odd error message for a bad rule but at least I’m not blocked

Joe R. Smith01:05:20

Can I see the query?

steveb8n06:05:20

Thanks but no need. It was an invalid rule that I needed to delete. The only mystery is why it didn't fail in tests but did on cloud

2
Henrique Prange12:05:20

Are you using dev-local in your tests?

Joe R. Smith01:05:38

Any updates on a solution for Datomic Cloud users to get some of that sweet, sweet free Datomic goodness? 🙂

🙏 4
jaret11:05:36

Its still coming! We had to clear some hurdles with account limits and AWS Marketplace. Hope to have more news this week.

catjam 10
jaret11:05:36

Its still coming! We had to clear some hurdles with account limits and AWS Marketplace. Hope to have more news this week.

catjam 10
Karol Wójcik11:05:40

I'm on the newest version of transactor 1.0.6733 with following settings in transactor.properties

ping-host=localhost
ping-port=8080
When I'm trying to curl localhost:8080/health I'm receiving connection refused. Logs on transactor side seems okay, though.
2023-05-24 13:31:44.343 INFO  default    datomic.transactor - {:event :transactor/start, :args {:log-dir "log", :sql-driver-class "org.postgresql.Driver", :ping-host "localhost", :protocol :sql, :rest-alias "sql", :memory-index-max "256m", :port 4334, :memory-index-threshold "32m", :data-dir "./data", :object-cache-max "128m", :host "localhost", :ping-port "8080", :sql-validation-query "select 1", :version "1.0.6733", :encrypt-channel true}, :pid 13268, :tid 13}

lassemaatta11:05:37

I think this is the same issue: https://clojurians.slack.com/archives/C03RZMDSH/p1683025237165599, fix should be in the works

Karol Wójcik11:05:22

Wow. That was quick and very helpful. Thanks!

jaret17:05:56

Yep! We'll have this fixed in the next release. Discovered too late to get it into 6733.

Matt DeAngelis13:05:24

I'm really struggling with database functions in Datomic. I am specifically looking for a function that will compare datetime stamps of certain entries in the database to today's date. However, in order to debug the error: "Wrong number of args passed to keyword", I have generated the following simple example.

(def three-args
  (d/function '{:lang :clojure
                :params [x y z]
                :code (+ x y z)}))


@(d/transact conn  [{:db/doc "Example three-argument function."
                     :db/ident :three-args
                     :db/fn three-args}])
From this, I feel that I should be able to then run:
(d/q '[:find ?result
       :where
       [[:three-args 1 2 3] ?result]] (d/db conn))
And see the result. But I can't. I get that same error above: "Wrong number of args passed to keyword". I take that to mean that the function isn't being recognized. However, when I run: (d/entity (d/db conn) :three-args) I get the entity id, and: (d/invoke (d/db conn) <entity id> 1 2 3) returns 6, as expected. Can anyone help?

favila13:05:09

> [[:three-args 1 2 3] ?result]]

favila13:05:13

this is not an invocation

favila13:05:37

of your db fn

favila13:05:52

it’s invoking the keyword (clojure keywords are functions)

favila13:05:33

you need to get that :db/fn object, or you can use the peer api d/invoke

favila13:05:58

e.g. [(datomic.api/invoke $ :three-args 1 2 3) ?result]

favila13:05:23

I think this might work too, but I’m not sure if the datalog parser is ok with it

favila13:05:47

[:three-args :db/fn ?three-args-fn][(?three-args-fn 1 2 3) ?result]

favila13:05:52

are you using database functions as a deployment method? otherwise you can just call arbitrary functions from within the query in on-prem

favila14:05:16

[(my-ns/three-args 1 2 3) ?result]

Matt DeAngelis14:05:38

Thank you favila! Your first code sample worked, so I have proof of concept, at least. It sounds like calling namespaced functions directly within the query would work for me. I'll be filtering results based on the truthiness of my date checking function, that will work?

favila14:05:24

yes, you can call anything, even java interop, even type hints

favila14:05:45

predicate forms you can omit the return binding, and truthiness will determine if it unifies

favila14:05:55

[(my-pred ?x)] for e.g.

Matt DeAngelis14:05:25

Wow, that's neat. I will try that. Looks like I started out by overengineering 😁 Thank you for your help.

favila14:05:39

the only caveat I have is that only the first level of the form is inspected for datalog variables

favila14:05:55

[(f (vector ?x))] won’t work for e.g.

Matt DeAngelis14:05:49

Okay, got it I think. I don't think that will be an issue, but I will see.

favila14:05:24

the workaround is to adjust the signature of f to what you need, or to use multiple clauses binding an intermediate

favila14:05:37

the query runs in the same process and clojure environment as the rest of the peer, so def-ing a new thing and using it from a query requires no ceremony

Matt DeAngelis14:05:25

Yes that works! Thank you so much, this is much, much easier to manage.

Lennart Buit15:05:11

Just for completeness sake, comparing dates of entities with today is something you could already do pretty easily. If my memory serves me well; comparison is even implemented more efficiently than using clojure.core/> :

(d/q '{:find  [?e]
       :in    [$ ?now]
       :where [[?e :my-entity/date ?date]]
               [(> ?date ?now)]}
     db
     (Date.))

Lennart Buit15:05:49

(although visually, it looks like you are invoking the > function)

favila15:05:22

Good call out, I read over that part of the OP

favila15:05:34

datomic datalog comparison operators work on any datomic attribute type except bytes. They’re not clojure.core/>, which don’t support those (e.g. (< (Date.) (Date.)) throws)

Matt DeAngelis17:05:48

That's a neat idea, too. I will experiment with the simple built-in comparison operators. Thanks Lennart 🙂

Lennart Buit17:05:27

Be sure to also check out ‘rules’, which is a way to reuse multiple clauses across queries.

Lennart Buit17:05:02

Imo, using the built in stuff, together with rules, should already be powerful enough for the majority of queries you write ^^. Database functions are just a way for you to unlock even more superpowers ;)

Matt DeAngelis17:05:24

Oh rules are cool! I was just thinking, man, wouldn't it be nice if I could build the :where up programatically...

Lennart Buit17:05:53

You can! But I would strongly advice to try to get used to writing datomic queries statically (with rules to reuse!).

Lennart Buit17:05:32

There are cases to think of to build queries programmatically, to use datomic functions, to do all sorts of magic stuff. But there is nothing as clear as a literal map with datalog clauses and the occasional rule.

Lennart Buit18:05:04

(I don’t know how contentious this point is, haha)

Matt DeAngelis18:05:05

Good point. I'm not getting too fancy just yet.