Datalevin查询变量重绑定问题:该行为是预期还是Bug?
Datalevin查询中变量重绑定的行为分析
问题场景
使用Datalevin 0.8.16作为数据库,先执行数据插入操作:
(datalevin.core/transact! conn [{:hello "some value" :data {:k "other value"}}])
随后运行查询:
(datalevin.core/q '[:find ?e ?v :where [?e :hello ?v] [?e :data ?d] [(get ?d :k) ?v]] my-db)
查询返回结果#{[21 "other value"]},但预期结果应为空集——按照常规Datomic查询语义,同一个变量?v不能同时绑定到两个不同的值,这里?v先绑定到"some value",后续不应被重绑定为"other value"。
行为分析
Datomic的查询语义中,:where子句里的变量是统一绑定的:一旦变量被绑定到某个值,后续所有引用该变量的地方都必须匹配这个值,不能被重新赋值。函数表达式[(get ?d :k) ?v]的语义应该是取出?d的:k字段值,检查它是否等于已绑定的?v值,而非将?v重新绑定为这个新值。
当前Datalevin的处理方式违背了这一语义,不符合Datomic的规范逻辑。
结论
这种变量被重绑定的行为并非预期,更可能是Datalevin在函数表达式变量绑定逻辑上的Bug。根据Datomic官方文档,函数表达式的第二个参数作为变量绑定,应遵循常规的变量绑定一致性规则,而非覆盖已有绑定。
内容的提问来源于stack exchange,提问作者erdos
相关产品推荐
相关产品推荐

