Browse Source

fix(query): cache special value as resolved value (#8263)

* fix(query): cache inputs as resolved values
Co-authored-by: Ben Yorke <[email protected]>
Yichen Yan 2 năm trước cách đây
mục cha
commit
a3c7308dc0

+ 12 - 2
e2e-tests/fixtures.ts

@@ -25,12 +25,22 @@ const consoleLogWatcher = (msg: ConsoleMessage) => {
   // console.log(msg.text())
   // console.log(msg.text())
   const text = msg.text()
   const text = msg.text()
   logs += text + '\n'
   logs += text + '\n'
-  expect(text, logs).not.toMatch(/^(Failed to|Uncaught)/)
+
+  // expect() will remember all arguments in memory,
+  // and the memory usage will grow *exponentially* in the number of output line.
+  // So we call expect() iff interesting pattern has already be found to avoid OOM.
+  const expectNotMatchWithCheck = (pattern: RegExp) => {
+    if (text.match(pattern)) {
+      expect(text, logs).not.toMatch(pattern)
+    }
+  }
+
+  expectNotMatchWithCheck(/^(Failed to|Uncaught)/)
 
 
   // youtube video
   // youtube video
   // Error with Permissions-Policy header: Origin trial controlled feature not enabled: 'ch-ua-reduced'.
   // Error with Permissions-Policy header: Origin trial controlled feature not enabled: 'ch-ua-reduced'.
   if (!text.match(/^Error with Permissions-Policy header:/)) {
   if (!text.match(/^Error with Permissions-Policy header:/)) {
-    expect(text, logs).not.toMatch(/^Error/)
+    expectNotMatchWithCheck(/^Error/)
   }
   }
 
 
   // NOTE: React warnings will be logged as error.
   // NOTE: React warnings will be logged as error.

+ 3 - 4
src/main/frontend/db/query_react.cljs

@@ -97,15 +97,14 @@
     (pprint "Use the following to debug your datalog queries:")
     (pprint "Use the following to debug your datalog queries:")
     (pprint query')
     (pprint query')
     (let [query (resolve-query query)
     (let [query (resolve-query query)
-          current-block-uuid (:current-block-uuid query-opts)
           repo (or repo (state/get-current-repo))
           repo (or repo (state/get-current-repo))
           db (conn/get-db repo)
           db (conn/get-db repo)
-          resolved-inputs (mapv #(resolve-input db % {:current-block-uuid current-block-uuid})
-                                inputs)
+          resolve-with (select-keys query-opts [:current-page-fn :current-block-uuid])
+          resolved-inputs (mapv #(resolve-input db % resolve-with) inputs)
           inputs (cond-> resolved-inputs
           inputs (cond-> resolved-inputs
                          rules
                          rules
                          (conj rules))
                          (conj rules))
-          k [:custom (or (:query-string query') query')]]
+          k [:custom (or (:query-string query') query') inputs]]
       (pprint "inputs (post-resolution):" resolved-inputs)
       (pprint "inputs (post-resolution):" resolved-inputs)
       (pprint "query-opts:" query-opts)
       (pprint "query-opts:" query-opts)
       (pprint (str "time elapsed: " (.toFixed (- (.now js/performance) start-time) 2) "ms"))
       (pprint (str "time elapsed: " (.toFixed (- (.now js/performance) start-time) 2) "ms"))

+ 31 - 14
src/test/frontend/db/query_react_test.cljs

@@ -1,7 +1,6 @@
 (ns frontend.db.query-react-test
 (ns frontend.db.query-react-test
   (:require [cljs.test :refer [deftest is use-fixtures]]
   (:require [cljs.test :refer [deftest is use-fixtures]]
             [cljs-time.core :as t]
             [cljs-time.core :as t]
-            [clojure.pprint]
             [clojure.string :as string]
             [clojure.string :as string]
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.date :as date]
             [frontend.date :as date]
@@ -9,7 +8,6 @@
             [frontend.test.helper :as test-helper :refer [load-test-files]]
             [frontend.test.helper :as test-helper :refer [load-test-files]]
             [frontend.db.query-custom :as query-custom]
             [frontend.db.query-custom :as query-custom]
             [frontend.db.utils :as db-utils]
             [frontend.db.utils :as db-utils]
-            [frontend.db.react :as react]
             [goog.string :as gstring]))
             [goog.string :as gstring]))
 
 
 (use-fixtures :each {:before test-helper/start-test-db!
 (use-fixtures :each {:before test-helper/start-test-db!
@@ -19,21 +17,20 @@
   "Use custom-query over react-query for testing since it tests react-query and
   "Use custom-query over react-query for testing since it tests react-query and
 adds rules that users often use"
 adds rules that users often use"
   [query & [opts]]
   [query & [opts]]
-  (react/clear-query-state!)
   (when-let [result (query-custom/custom-query test-helper/test-db query opts)]
   (when-let [result (query-custom/custom-query test-helper/test-db query opts)]
     (map first (deref result))))
     (map first (deref result))))
 
 
 (defn- blocks-created-between-inputs [a b]
 (defn- blocks-created-between-inputs [a b]
-   (sort
-     (map #(-> % :block/content string/split-lines first)
-          (custom-query {:inputs [a b]
-                         :query '[:find (pull ?b [*])
-                                  :in $ ?start ?end
-                                  :where
-                                  [?b :block/content]
-                                  [?b :block/created-at ?timestamp]
-                                  [(>= ?timestamp ?start)]
-                                  [(<= ?timestamp ?end)]]}))))
+  (sort
+   (map #(-> % :block/content string/split-lines first)
+        (custom-query {:inputs [a b]
+                       :query '[:find (pull ?b [*])
+                                :in $ ?start ?end
+                                :where
+                                [?b :block/content]
+                                [?b :block/created-at ?timestamp]
+                                [(>= ?timestamp ?start)]
+                                [(<= ?timestamp ?end)]]}))))
 
 
 (defn- blocks-journaled-between-inputs [a b]
 (defn- blocks-journaled-between-inputs [a b]
   (map :block/content (custom-query {:inputs [a b]
   (map :block/content (custom-query {:inputs [a b]
@@ -56,6 +53,17 @@ adds rules that users often use"
                                                      [?e :block/name ?page]]}
                                                      [?e :block/name ?page]]}
                                     {:current-block-uuid (get (block-with-content block-content) :block/uuid)})))
                                     {:current-block-uuid (get (block-with-content block-content) :block/uuid)})))
 
 
+(defn- blocks-with-tag-on-specified-current-page [& {:keys [current-page tag]}]
+  (map :block/content (custom-query {:title "Query title"
+                                     :inputs [:current-page tag] 
+                                     :query '[:find (pull ?b [*]) 
+                                              :in $ ?current-page ?tag-name
+                                              :where [?b :block/page ?bp] 
+                                                     [?bp :block/name ?current-page] 
+                                                     [?b :block/ref-pages ?t] 
+                                                     [?t :block/name ?tag-name]]}
+                                    {:current-page-fn (constantly current-page)})))
+
 (deftest resolve-input-for-page-and-block-inputs
 (deftest resolve-input-for-page-and-block-inputs
   (load-test-files [{:file/path "pages/page1.md"
   (load-test-files [{:file/path "pages/page1.md"
                      :file/content
                      :file/content
@@ -70,7 +78,7 @@ adds rules that users often use"
                                :query '[:find (pull ?b [*])
                                :query '[:find (pull ?b [*])
                                         :in $ ?current-page
                                         :in $ ?current-page
                                         :where [?b :block/page ?bp]
                                         :where [?b :block/page ?bp]
-                                        [?bp :block/name ?current-page]]}))))
+                                               [?bp :block/name ?current-page]]}))))
       ":current-page input resolves to current page name")
       ":current-page input resolves to current page name")
 
 
   (is (= []
   (is (= []
@@ -303,3 +311,12 @@ created-at:: %s"
 
 
     (is (= ["+1d"] (blocks-on-journal-page-from-block-with-content :query-page "+1d"))
     (is (= ["+1d"] (blocks-on-journal-page-from-block-with-content :query-page "+1d"))
         ":query-page resolves to the parent page when called from another page")))
         ":query-page resolves to the parent page when called from another page")))
+
+(deftest cache-input-for-page-inputs
+  (load-test-files [{:file/path "pages/a.md" :file/content "- a #shared-tag"}
+                    {:file/path "pages/b.md" :file/content "- b #shared-tag"}])
+
+  (is (not= (blocks-with-tag-on-specified-current-page :current-page "a" :tag "shared-tag")
+            (blocks-with-tag-on-specified-current-page :current-page "b" :tag "shared-tag")
+            [])
+      "Querying for blocks with tag on current page from page returns not-empty but differing results"))