Indexes on vectors return surprising results

Abierto
#470 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
35/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
clojure
Área
databases

Línea de trabajo

Empieza ejecutando los dos fragmentos de reproducción y siguiendo la búsqueda d/datoms :avet para el atributo :path indexado. Compara entradas de tipo vector, lista y secuencia con y sin el datom :children adicional; se considera terminado cuando la búsqueda se comporta de forma coherente y solo coincide con los valores indexados previstos.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

I'm seeing some odd behavior with indexed vectors. I thought this might have been introduced in 1.6.4, but it was also happening in 1.6.3. Given

(let [db (-> (d/empty-db {:path {:db/index true}})
             (d/db-with [{:path [1 2]}
                         {:path [1 2 3]}]))]
  (for [v [;; variations on 1, 2
           [1 2]
           (list 1 2)
           (butlast [1 2 3])

           ;; variations on 1, 2, 3
           [1 2 3]
           (list 1 2 3)
           (butlast [1 2 3 4])]]
    [v
     (->> (d/datoms db :avet :path v)
          (mapv :e))]))

I'd expect this to only find entity ids for the first and fourth values of v, i.e. for the vectors, not the lists or sequences. However, this is what is returned.

;; => ([[1 2] [1]]
;;     [(1 2) [1]]
;;     [(1 2) []]
;;     [[1 2 3] [2]]
;;     [(1 2 3) []]
;;     [(1 2 3) [2]])

It's particularly odd that first list, (list 1 2) returns an entity id but (list 1 2 3) doesn't. And contrarily that the first sequence (butlast [1 2 3]) doesn't return an entity id but (butlast [1 2 3 4]) does.

As I was playing with this I also ran across another odd variation. The presence of other datoms seems to affect the result.

(let [db (-> (d/empty-db {:path {:db/index true}
                          ;; this attribute is new
                          :children {:db/valueType :db.type/ref
                                     :db/cardinality :db.cardinality/many}})
             (d/db-with [{:db/id "a"
                          :path [1 2]}
                         {:db/id "b"
                          :path [1 2 3]}
                         ;; this datom is new
                         [:db/add "a" :children "b"]]))]
  (for [v [;; variations on 1, 2
           [1 2]
           (list 1 2)
           (butlast [1 2 3])

           ;; variations on 1, 2, 3
           [1 2 3]
           (list 1 2 3)
           (butlast [1 2 3 4])]]
    [v
     (->> (d/datoms db :avet :path v)
          (mapv :e))]))

;; => ([[1 2] [1]]
;;     [(1 2) [1]]
;;     this result has changed
;;     [(1 2) [1 2]]
;;     [[1 2 3] [2]]
;;     [(1 2 3) []]
;;     [(1 2 3) [2]])

Here the result is almost the same, except that whereas before when v was (list 1 2), d/datoms returned nothing. Now, with the other datom, it returns both entity ids. Very odd!

The easiest fix is, on the calling side, to be careful to pass vectors not sequences. That's what we'll do in our project, but I wanted to report the issue anyway.

Lenguaje dominante
Clojure
Estrellas
5.8k
Forks
318
Métricas de merge de PR
Sin PR fusionados en 30 d

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de tonsky/datascript

Todos los issues de tonsky/datascript

Issues similares

Más issues de Clojure

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.