diff --git a/server/src/instant/db/datalog.clj b/server/src/instant/db/datalog.clj index 8d2f1a9720..849fdd9d9e 100644 --- a/server/src/instant/db/datalog.clj +++ b/server/src/instant/db/datalog.clj @@ -1963,10 +1963,11 @@ (contains? (flags/flag :always-materialize-attr-ids) (first (uspec/tagged-unwrap (:a named-p)))))) -(defn enable-row-hints? [query-hash] +(defn enable-row-hints? [app-id query-hash] (and (or (flags/toggled? :enable-row-hints-globally true) (coll/exists? (fn [h] (= query-hash h)) (flags/flag :enable-row-hints-query-hashes))) + (not (contains? (flags/flag :disable-row-hints-apps) app-id)) (not (coll/exists? (fn [h] (= query-hash h)) (flags/flag :disable-row-hints-query-hashes))))) @@ -2875,7 +2876,7 @@ :pg-hints (if (flags/toggled? :disable-pg-hints) [] - (if (enable-row-hints? (:query-hash ctx)) + (if (enable-row-hints? app-id (:query-hash ctx)) pg-hints (filterv (fn [hint] (not= :'Rows (first hint))) diff --git a/server/src/instant/flags.clj b/server/src/instant/flags.clj index 3bf84b26d6..afa6b00a71 100644 --- a/server/src/instant/flags.clj +++ b/server/src/instant/flags.clj @@ -237,6 +237,7 @@ (update :use-reactive-cache-for-verify-token-apps parse-uuids-flag) (update :backup-skip-app-ids parse-uuids-flag) (update :pkey-null-padding-apps parse-uuids-flag) + (update :disable-row-hints-apps parse-uuids-flag) (update :query-circuit-breaker parse-query-circuit-breaker-flag)) handle-receive-timeout (reduce (fn [acc {:strs [appId timeoutMs]}] (assoc acc (parse-uuid appId) timeoutMs)) diff --git a/server/test/instant/db/row_hints_flag_test.clj b/server/test/instant/db/row_hints_flag_test.clj new file mode 100644 index 0000000000..47605b7cc5 --- /dev/null +++ b/server/test/instant/db/row_hints_flag_test.clj @@ -0,0 +1,49 @@ +(ns instant.db.row-hints-flag-test + (:require [clojure.test :refer [deftest is testing]] + [instant.db.attr-sketch :as cms] + [instant.db.datalog :as d] + [instant.db.instaql :as iq] + [instant.db.model.attr :as attr-model] + [instant.flags :as flags] + [instant.util.instaql :as instaql-util])) + +(def app-id #uuid "5a0c1d2e-7b3f-4c6a-9e8d-1f2a3b4c5d6e") + +(def attrs + (attr-model/wrap-attrs + (mapv (fn [n field] + (cond-> {:id (java.util.UUID. 0 n) + :forward-identity [(java.util.UUID. 1 n) "prices" field] + :value-type :blob :cardinality :one + :index? (= field "modified") :unique? (= field "id")} + (= field "modified") (assoc :checked-data-type :number))) + [1 2 3] ["id" "modified" "value"]))) + +(def query + {:prices {:$ {:where {:and [{:modified {:$gt 100}} {:modified {:$lte 200}}]} + :order {:modified "asc"} :first 50}}}) + +(defn row-hints [app-id] + (let [normalized (instaql-util/normalized-forms query) + ctx {:app-id app-id :attrs attrs + :query-normalized normalized + :query-hash (hash normalized) + :sketches (into {} (map (fn [a] + [{:app-id app-id :attr-id (:id a)} + {:sketch (assoc (cms/make-sketch) :total 240000)}]) + attrs))} + patterns (:patterns (iq/instaql-query->patterns ctx query)) + named (d/annotate-with-hints-impl ctx {} (d/nested->named-patterns patterns))] + (binding [d/*enable-pg-hints* true] + (->> (d/nested-match-query ctx :m- app-id named) + :query + :pg-hints + (filter #(= :'Rows (first %))))))) + +(deftest row-hints-can-be-disabled-per-app + (is (seq (row-hints app-id))) + (binding [flags/*flag-overrides* {:disable-row-hints-apps #{app-id}}] + (testing "the listed app loses only its row hints" + (is (empty? (row-hints app-id)))) + (testing "other apps keep theirs" + (is (seq (row-hints (random-uuid)))))))