From 52582c5ca497995ae9f7a622296402efd9cb454d Mon Sep 17 00:00:00 2001 From: Brian Platz Date: Sat, 5 Nov 2022 10:15:41 -0400 Subject: [PATCH] #240 Allows @context @reverse declarations in queries to return proper results --- deps.edn | 2 +- src/fluree/db/index.cljc | 2 +- src/fluree/db/query/analytical_parse.cljc | 2 +- src/fluree/db/query/json_ld/response.cljc | 49 +++++++++++------ src/fluree/db/query/json_ld/select.cljc | 23 +++++--- src/fluree/db/query/subject_crawl/core.cljc | 4 +- .../db/query/subject_crawl/subject.cljc | 4 +- test/fluree/db/query/reverse_query_test.clj | 55 +++++++++++++++++++ 8 files changed, 109 insertions(+), 32 deletions(-) create mode 100644 test/fluree/db/query/reverse_query_test.clj diff --git a/deps.edn b/deps.edn index 1c030c157..71ead6c8b 100644 --- a/deps.edn +++ b/deps.edn @@ -9,7 +9,7 @@ cheshire/cheshire {:mvn/version "5.11.0"} instaparse/instaparse {:mvn/version "1.4.12"} com.fluree/json-ld {:git/url "https://github.com/fluree/json-ld.git" - :sha "c22e943a9c4618379759eb9e2ca0cd384e1a1882"} + :sha "0614a222e0197ca654449ac3b1a1125608d3ec7b"} ;; logging diff --git a/src/fluree/db/index.cljc b/src/fluree/db/index.cljc index 7d60f6dfd..353e869b2 100644 --- a/src/fluree/db/index.cljc +++ b/src/fluree/db/index.cljc @@ -214,7 +214,7 @@ (defn novelty-subrange [{:keys [rhs leftmost?], first-flake :first, :as node} through-t novelty] - (log/debug "novelty-subrange: first-flake:" first-flake "\nrhs:" rhs "\nleftmost?" leftmost?) + (log/trace "novelty-subrange: first-flake:" first-flake "\nrhs:" rhs "\nleftmost?" leftmost?) (let [subrange (cond ;; standard case: both left and right boundaries (and rhs (not leftmost?)) diff --git a/src/fluree/db/query/analytical_parse.cljc b/src/fluree/db/query/analytical_parse.cljc index abda6552c..b19617c2a 100644 --- a/src/fluree/db/query/analytical_parse.cljc +++ b/src/fluree/db/query/analytical_parse.cljc @@ -1172,7 +1172,7 @@ (defn parse* [db {:keys [opts prettyPrint filter context depth orderBy order-by groupBy group-by] :as query-map} supplied-vars] - (log/debug "parse* query-map:" query-map) + (log/trace "parse* query-map:" query-map) (let [op-type (cond (some #{:select :selectOne :selectReduced :selectDistince} (keys query-map)) :select diff --git a/src/fluree/db/query/json_ld/response.cljc b/src/fluree/db/query/json_ld/response.cljc index 1c3f86ee1..7c625b9db 100644 --- a/src/fluree/db/query/json_ld/response.cljc +++ b/src/fluree/db/query/json_ld/response.cljc @@ -75,23 +75,36 @@ acc)))))) (defn crawl-ref-item - [db compact-fn ref-flake sub-select cache fuel-vol max-fuel depth-i] + [db compact-fn flake-sid sub-select cache fuel-vol max-fuel depth-i] (go-try - (let [sub-flakes (res db cache compact-fn fuel-vol max-fuel sub-select depth-i sub-flakes))))) -(defn crawl-ref - "A sub-selection (graph crawl) exists, generate results." - [db compact-fn p-flakes sub-select cache fuel-vol max-fuel depth-i] + +(defn add-reverse-specs + "When @reverse variables are present, crawl for the reverse specs." + [db cache compact-fn fuel-vol max-fuel {:keys [reverse] :as select-spec} depth-i flakes] (go-try - (loop [[next-flake & r] p-flakes - acc []] - (if next-flake - (let [sub-flakes (res db cache compact-fn fuel-vol max-fuel sub-select depth-i sub-flakes))] - (recur r (conj acc res))) - (if (= 1 (count acc)) - (first acc) + (let [sid (flake/s (first flakes))] + (loop [[reverse-item & r] (vals reverse) + acc {}] + (if reverse-item + (let [{:keys [id as spec]} reverse-item + sub-flakes (iri db cache compact-fn ref-sid))))] + (recur r (conj acc-item result))) + (if (= 1 (count acc-item)) + (first acc-item) + acc-item)))] + (recur r (assoc acc as result))) acc))))) @@ -99,7 +112,7 @@ (defn flakes->res "depth-i param is the depth of the graph crawl. Each successive 'ref' increases the graph depth, up to the requested depth within the select-spec" - [db cache compact-fn fuel-vol max-fuel {:keys [wildcard? depth] :as select-spec} depth-i flakes] + [db cache compact-fn fuel-vol max-fuel {:keys [wildcard? depth reverse] :as select-spec} depth-i flakes] (go-try (when (not-empty flakes) (loop [[p-flakes & r] (partition-by flake/p flakes) @@ -139,11 +152,11 @@ (cond ;; have a specified sub-selection (graph crawl) (:spec spec) - (} for each ref iri :else @@ -159,4 +172,6 @@ (if v (recur r (assoc acc (:as spec) v)) (recur r acc))) - acc))))) + (if reverse + (merge acc ( spec - (assoc :spec (expand-selection db context depth* v) - :as k)))) + (dec depth)) + reverse? (boolean (get-in context [k :reverse])) + spec* (-> spec + (assoc :spec (expand-selection db context depth* v) + :as k))] + (if reverse? + (assoc-in acc [:reverse pid] spec*) + (assoc acc pid spec*))) (#{"*" :* '*} select-item) (assoc acc :wildcard? true) :else - (let [iri (json-ld/expand-iri select-item context) - spec (get-in schema [:pred iri]) - pid (:id spec)] - (assoc acc pid (assoc spec :as select-item))))) + (let [iri (json-ld/expand-iri select-item context) + spec (get-in schema [:pred iri]) + pid (:id spec) + reverse? (boolean (get-in context [select-item :reverse]))] + (if reverse? + (assoc-in acc [:reverse pid] (assoc spec :as select-item)) + (assoc acc pid (assoc spec :as select-item)))))) {:depth depth} selection)) diff --git a/src/fluree/db/query/subject_crawl/core.cljc b/src/fluree/db/query/subject_crawl/core.cljc index 5d7a688f9..3dfa75cd3 100644 --- a/src/fluree/db/query/subject_crawl/core.cljc +++ b/src/fluree/db/query/subject_crawl/core.cljc @@ -66,7 +66,7 @@ (e) send result into :select graph crawl" [db {:keys [vars ident-vars where limit offset fuel rel-binding? order-by compact-fn opts] :as parsed-query}] - (log/debug "Running simple subject crawl query:" parsed-query) + (log/trace "Running simple subject crawl query:" parsed-query) (let [error-ch (async/chan) f-where (first where) rdf-type? (= :rdf/type (:type f-where)) @@ -97,7 +97,7 @@ :query parsed-query :result-fn result-fn :finish-fn finish-fn}] - (log/debug "simple-subject-crawl opts:" opts) + (log/trace "simple-subject-crawl opts:" opts) (if rel-binding? (relationship-binding opts) (if collection? diff --git a/src/fluree/db/query/subject_crawl/subject.cljc b/src/fluree/db/query/subject_crawl/subject.cljc index 1954b6085..c21669659 100644 --- a/src/fluree/db/query/subject_crawl/subject.cljc +++ b/src/fluree/db/query/subject_crawl/subject.cljc @@ -94,7 +94,7 @@ "For queries that specify _id as the predicate, we will have a single subject as a value." [db error-ch vars {:keys [o] :as f-where}] - (log/debug "subjects-id-chan f-where:" f-where) + (log/trace "subjects-id-chan f-where:" f-where) (let [return-ch (async/chan) _id-val (or (:value o) (get vars (:variable o)))] @@ -141,7 +141,7 @@ [{:keys [db error-ch f-where limit offset parallelism vars ident-vars finish-fn] :as opts}] (go-try - (log/debug "subj-crawl opts:" opts) + (log/trace "subj-crawl opts:" opts) (let [{:keys [o p-ref?]} f-where vars* (if ident-vars (