diff --git a/modules/drivers/bigquery/src/metabase/driver/bigquery.clj b/modules/drivers/bigquery/src/metabase/driver/bigquery.clj
index ab8a7e9574de716918ca149b71e65da9f13357b2..745286e2dea5baade6fb83205a2f7b46a13dfc2d 100644
--- a/modules/drivers/bigquery/src/metabase/driver/bigquery.clj
+++ b/modules/drivers/bigquery/src/metabase/driver/bigquery.clj
@@ -102,7 +102,7 @@
     "STRING"    :type/Text
     "DATE"      :type/Date
     "DATETIME"  :type/DateTime
-    "TIMESTAMP" :type/DateTime
+    "TIMESTAMP" :type/DateTimeWithLocalTZ
     "TIME"      :type/Time
     "NUMERIC"   :type/Decimal
     :type/*))
diff --git a/modules/drivers/bigquery/src/metabase/driver/bigquery/query_processor.clj b/modules/drivers/bigquery/src/metabase/driver/bigquery/query_processor.clj
index 7faa1f61c425acab5381633e19e9f392ad77681a..78f0ca0730ec58a80609825d926f379a46c9fe4a 100644
--- a/modules/drivers/bigquery/src/metabase/driver/bigquery/query_processor.clj
+++ b/modules/drivers/bigquery/src/metabase/driver/bigquery/query_processor.clj
@@ -15,7 +15,9 @@
             [metabase.models
              [field :refer [Field]]
              [table :as table]]
-            [metabase.query-processor.store :as qp.store]
+            [metabase.query-processor
+             [error-type :as error-type]
+             [store :as qp.store]]
             [metabase.util
              [date-2 :as u.date]
              [honeysql-extensions :as hx]
@@ -102,92 +104,157 @@
 ;;; |                                               SQL Driver Methods                                               |
 ;;; +----------------------------------------------------------------------------------------------------------------+
 
-;; EXPERIMENTAL
+(def ^:private temporal-type-hierarchy
+  (-> (make-hierarchy)
+      (derive :date :temporal-type)
+      (derive :time :temporal-type)
+      (derive :datetime :temporal-type)
+      ;; timestamp = datetime with a timezone
+      (derive :timestamp :temporal-type)))
 
 (defmulti ^:private temporal-type
   {:arglists '([x])}
-  mbql.u/dispatch-by-clause-name-or-class)
+  mbql.u/dispatch-by-clause-name-or-class
+  :hierarchy #'temporal-type-hierarchy)
 
 (defmethod temporal-type LocalDate      [_] :date)
 (defmethod temporal-type LocalTime      [_] :time)
 (defmethod temporal-type OffsetTime     [_] :time)
 (defmethod temporal-type LocalDateTime  [_] :datetime)
-(defmethod temporal-type OffsetDateTime [_] :datetime)
-(defmethod temporal-type ZonedDateTime  [_] :datetime)
+(defmethod temporal-type OffsetDateTime [_] :timestamp)
+(defmethod temporal-type ZonedDateTime  [_] :timestamp)
 
 (defn- base-type->temporal-type [base-type]
   (condp #(isa? %2 %1) base-type
-    :type/Date     :date
-    :type/Time     :time
-    :type/DateTime :datetime
+    :type/Date           :date
+    :type/Time           :time
+    :type/DateTimeWithTZ :timestamp
+    :type/DateTime       :datetime
     nil))
 
 (defmethod temporal-type (class Field)
-  [{base-type :base_type}]
-  (base-type->temporal-type base-type))
+  [{base-type :base_type, database-type :database_type}]
+  (case database-type
+    "TIMESTAMP" :timestamp
+    "DATETIME"  :datetime
+    "DATE"      :date
+    "TIME"      :time
+    (base-type->temporal-type base-type)))
 
 (defmethod temporal-type :absolute-datetime
-  [[_ t unit]]
+  [[_ t _]]
   (temporal-type t))
 
 (defmethod temporal-type :time
   [_]
   :time)
 
+(defmethod temporal-type :datetime-field
+  [[_ field unit]]
+  ;; date extraction operations result in integers, so the type of the expression shouldn't be a temporal type
+  (if (u.date/extract-units unit)
+    nil
+    (temporal-type field)))
+
 (defmethod temporal-type :default
   [x]
-  (or (mbql.u/match-one x
-        [:field-id id]               (temporal-type (qp.store/field id))
-        [:field-literal _ base-type] (base-type->temporal-type base-type))
-      (:mbql/temporal-type (meta x))))
+  (if (contains? (meta x) :bigquery/temporal-type)
+    (:bigquery/temporal-type (meta x))
+    (mbql.u/match-one x
+      [:field-id id]               (temporal-type (qp.store/field id))
+      [:field-literal _ base-type] (base-type->temporal-type base-type))))
 
 (defmulti ^:private ->temporal-type
   {:arglists '([target-type x])}
-  (fn [t-type x]
-    [t-type (mbql.u/dispatch-by-clause-name-or-class x)]))
-
-(defmethod ->temporal-type [:date LocalDate]          [_ t] t)
-(defmethod ->temporal-type [:time LocalDate]          [_ t] (throw (UnsupportedOperationException. (tru "Cannot convert date to time"))))
-(defmethod ->temporal-type [:datetime LocalDate]      [_ t] (t/local-date-time t (t/local-time 0)))
-(defmethod ->temporal-type [:date LocalTime]          [_ t] (throw (UnsupportedOperationException. (tru "Cannot convert time to a date"))))
-(defmethod ->temporal-type [:time LocalTime]          [_ t] t)
-(defmethod ->temporal-type [:datetime LocalTime]      [_ t] (throw (UnsupportedOperationException. (tru "Cannot convert time to a datetime"))))
-(defmethod ->temporal-type [:date OffsetTime]         [_ t] (t/local-date t))
-(defmethod ->temporal-type [:time OffsetTime]         [_ t] (t/local-time t))
-(defmethod ->temporal-type [:datetime OffsetTime]     [_ t] t)
-(defmethod ->temporal-type [:date LocalDateTime]      [_ t] (t/local-date t))
-(defmethod ->temporal-type [:time LocalDateTime]      [_ t] (t/local-time t))
-(defmethod ->temporal-type [:datetime LocalDateTime]  [_ t] t)
-(defmethod ->temporal-type [:date OffsetDateTime]     [_ t] (t/local-date t))
-(defmethod ->temporal-type [:time OffsetDateTime]     [_ t] (t/local-time t))
-(defmethod ->temporal-type [:datetime OffsetDateTime] [_ t] t)
-(defmethod ->temporal-type [:date ZonedDateTime]      [_ t] (t/local-date t))
-(defmethod ->temporal-type [:time ZonedDateTime]      [_ t] (t/local-time t))
-(defmethod ->temporal-type [:datetime ZonedDateTime]  [_ t] t)
+  (fn [target-type x]
+    [target-type (mbql.u/dispatch-by-clause-name-or-class x)])
+  :hierarchy #'temporal-type-hierarchy)
+
+(defn- throw-unsupported-conversion [from to]
+  (throw (ex-info (tru "Cannot convert a {0} to a {1}" from to)
+           {:type error-type/invalid-query})))
+
+(defmethod ->temporal-type [:date LocalTime]           [_ t] (throw-unsupported-conversion "time" "date"))
+(defmethod ->temporal-type [:date OffsetTime]          [_ t] (throw-unsupported-conversion "time" "date"))
+(defmethod ->temporal-type [:date LocalDate]           [_ t] t)
+(defmethod ->temporal-type [:date LocalDateTime]       [_ t] (t/local-date t))
+(defmethod ->temporal-type [:date OffsetDateTime]      [_ t] (t/local-date t))
+(defmethod ->temporal-type [:date ZonedDateTime]       [_ t] (t/local-date t))
+
+(defmethod ->temporal-type [:time LocalTime]           [_ t] t)
+(defmethod ->temporal-type [:time OffsetTime]          [_ t] (t/local-time t))
+(defmethod ->temporal-type [:time LocalDate]           [_ t] (throw-unsupported-conversion "date" "time"))
+(defmethod ->temporal-type [:time LocalDateTime]       [_ t] (t/local-time t))
+(defmethod ->temporal-type [:time OffsetDateTime]      [_ t] (t/local-time t))
+(defmethod ->temporal-type [:time ZonedDateTime]       [_ t] (t/local-time t))
+
+(defmethod ->temporal-type [:datetime LocalTime]       [_ t] (throw-unsupported-conversion "time" "datetime"))
+(defmethod ->temporal-type [:datetime OffsetTime]      [_ t] (throw-unsupported-conversion "time" "datetime"))
+(defmethod ->temporal-type [:datetime LocalDate]       [_ t] (t/local-date-time t (t/local-time 0)))
+(defmethod ->temporal-type [:datetime LocalDateTime]   [_ t] t)
+(defmethod ->temporal-type [:datetime OffsetDateTime]  [_ t] (t/local-date-time t))
+(defmethod ->temporal-type [:datetime ZonedDateTime]   [_ t] (t/local-date-time t))
+
+;; Not sure whether we should be converting local dates/datetimes to ones with UTC timezone or with the report timezone?
+(defmethod ->temporal-type [:timestamp LocalTime]      [_ t] (throw-unsupported-conversion "time" "timestamp"))
+(defmethod ->temporal-type [:timestamp OffsetTime]     [_ t] (throw-unsupported-conversion "time" "timestamp"))
+(defmethod ->temporal-type [:timestamp LocalDate]      [_ t] (t/zoned-date-time t (t/local-time 0) (t/zone-id "UTC")))
+(defmethod ->temporal-type [:timestamp LocalDateTime]  [_ t] (t/zoned-date-time t (t/zone-id "UTC")))
+(defmethod ->temporal-type [:timestamp OffsetDateTime] [_ t] t)
+(defmethod ->temporal-type [:timestamp ZonedDateTime]  [_ t] t)
 
 (defmethod ->temporal-type :default
-  [t-type x]
-  (if (= (temporal-type x) t-type)
-    x
-    (case t-type
-      nil       x
-      :date     (vary-meta (hx/cast :date      (sql.qp/->honeysql :bigquery x)) assoc :mbql/temporal-type :date)
-      :time     (vary-meta (hx/cast :time      (sql.qp/->honeysql :bigquery x)) assoc :mbql/temporal-type :time)
-      :datetime (vary-meta (hx/cast :timestamp (sql.qp/->honeysql :bigquery x)) assoc :mbql/temporal-type :timestamp))))
+  [target-type x]
+  (cond
+    (nil? x)
+    nil
+
+    (= (temporal-type x) target-type)
+    (vary-meta x assoc :bigquery/temporal-type target-type)
+
+    :else
+    (let [hsql-form     (sql.qp/->honeysql :bigquery x)
+          bigquery-type (case target-type
+                          :date      :date
+                          :time      :time
+                          :datetime  :datetime
+                          :timestamp :timestamp
+                          nil)]
+      (cond
+        (nil? hsql-form)
+        nil
+
+        (= (temporal-type hsql-form) target-type)
+        (vary-meta hsql-form assoc :bigquery/temporal-type target-type)
+
+        bigquery-type
+        (do
+          (log/tracef "Casting %s (temporal type = %s) to %s" (binding [*print-meta* true] (pr-str x)) (temporal-type x) bigquery-type)
+          (with-meta (hx/cast bigquery-type (sql.qp/->honeysql :bigquery x))
+            {:bigquery/temporal-type target-type}))
+
+        :else
+        x))))
+
+(defmethod ->temporal-type [:temporal-type :absolute-datetime]
+  [target-type [_ t unit]]
+  [:absolute-datetime (->temporal-type target-type t) unit])
 
 (defn- trunc
-  "Generate a SQL call to `timestamp_truc`, `date_trunc`, or `time_trunc` (depending on the `temporal-type` of `expr`)."
+  "Generate a SQL call an appropriate truncation function, depending on the temporal type of `expr`."
   [unit expr]
   (let [expr-type (or (temporal-type expr) :datetime)
         f         (case expr-type
-                    :date     :date_trunc
-                    :time     :time_trunc
-                    :datetime :timestamp_trunc)]
-    (hsql/call f (->temporal-type expr-type expr) (hsql/raw (name unit)))))
+                    :date      :date_trunc
+                    :time      :time_trunc
+                    :datetime  :datetime_trunc
+                    :timestamp :timestamp_trunc)]
+    (with-meta (hsql/call f (->temporal-type expr-type expr) (hsql/raw (name unit)))
+      {:bigquery/temporal-type expr-type})))
 
 (defn- extract [unit expr]
-  ;; implemenation of extract() in `metabase.util.honeysql-extensions` handles actual conversion to raw SQL (!)
-  (hsql/call :extract unit (hx/->timestamp expr)))
+  (with-meta (hsql/call :extract unit (->temporal-type :timestamp expr))
+    {:bigquery/temporal-type nil}))
 
 (defmethod sql.qp/date [:bigquery :minute]          [_ _ expr] (trunc   :minute    expr))
 (defmethod sql.qp/date [:bigquery :minute-of-hour]  [_ _ expr] (extract :minute    expr))
@@ -206,13 +273,11 @@
 (defmethod sql.qp/date [:bigquery :quarter-of-year] [_ _ expr] (extract :quarter   expr))
 (defmethod sql.qp/date [:bigquery :year]            [_ _ expr] (trunc   :year      expr))
 
-(defmethod sql.qp/unix-timestamp->timestamp [:bigquery :seconds]
-  [_ _ expr]
-  (hsql/call :timestamp_seconds expr))
-
-(defmethod sql.qp/unix-timestamp->timestamp [:bigquery :milliseconds]
-  [_ _ expr]
-  (hsql/call :timestamp_millis expr))
+(doseq [[unix-timestamp-type bigquery-fn] {:seconds      :timestamp_seconds
+                                           :milliseconds :timestamp_millis}]
+  (defmethod sql.qp/unix-timestamp->timestamp [:bigquery unix-timestamp-type]
+    [_ _ expr]
+    (vary-meta (hsql/call bigquery-fn expr) assoc :bigquery/temporal-type :timestamp)))
 
 
 ;;; +----------------------------------------------------------------------------------------------------------------+
@@ -245,6 +310,12 @@
          (>= (count components) 2))
     true))
 
+(defmethod sql.qp/->honeysql [:bigquery (class Field)]
+  [driver field]
+  (let [parent-method (get-method sql.qp/->honeysql [:sql (class Field)])
+        identifier    (parent-method driver field)]
+    (vary-meta identifier assoc :bigquery/temporal-type (temporal-type field))))
+
 (defmethod sql.qp/->honeysql [:bigquery Identifier]
   [_ identifier]
   (if-not (should-qualify-identifier? identifier)
@@ -255,6 +326,12 @@
                                     more)))
         (vary-meta assoc ::already-qualified? true))))
 
+(doseq [clause-type [:datetime-field :field-literal :field-id]]
+  (defmethod sql.qp/->honeysql [:bigquery clause-type]
+    [driver clause]
+    (let [hsql-form ((get-method sql.qp/->honeysql [:sql clause-type]) driver clause)]
+      (vary-meta hsql-form assoc :bigquery/temporal-type (temporal-type clause)))))
+
 (s/defn ^:private honeysql-form->sql :- s/Str
   [driver, honeysql-form :- su/Map]
   (let [[sql & args :as sql+args] (sql.qp/format-honeysql driver honeysql-form)]
@@ -325,8 +402,7 @@
   ;; TODO - we should make sure these are in the QP store somewhere and then could at least batch the calls
   (let [table-name (db/select-one-field :name table/Table :id (u/get-id table-id))]
     (with-meta (hx/identifier :field table-name field-name)
-      ;; EXPERIMENTAL
-      {:mbql/temporal-type (temporal-type field)})))
+      {:bigquery/temporal-type (temporal-type field)})))
 
 (defmethod sql.qp/apply-top-level-clause [:bigquery :breakout]
   [driver _ honeysql-form {breakouts :breakout, fields :fields}]
@@ -353,16 +429,23 @@
 (defmethod sql.qp/->honeysql [:bigquery :asc]  [driver clause] (alias-order-by-field driver clause))
 (defmethod sql.qp/->honeysql [:bigquery :desc] [driver clause] (alias-order-by-field driver clause))
 
-;; because between clauses are generated for SQL params we need to be careful that the temporal types line up
-(defmethod sql.qp/->honeysql [:bigquery :between]
-  [driver [_ f x y :as clause]]
-  ((get-method sql.qp/->honeysql [:sql :between])
-   driver
-   (if-let [f-type (or (temporal-type f) (temporal-type x))]
-     (do
-       (log/tracef "Coercing args in %s to temporal type %s" (binding [*print-meta* true] (pr-str clause)) f-type)
-       [:between (->temporal-type f-type f) (->temporal-type f-type x) (->temporal-type f-type y)])
-     clause)))
+(defn- reconcile-temporal-types
+  "Make sure the temporal types of fields and values in filter clauses line up."
+  [[clause-type f & args :as clause]]
+  (if-let [target-type (or (temporal-type f) (some temporal-type args))]
+    (do
+      (log/tracef "Coercing args in %s to temporal type %s" (binding [*print-meta* true] (pr-str clause)) target-type)
+      (u/prog1 (into [clause-type] (map (partial ->temporal-type target-type) (cons f args)))
+        (when-not (= clause <>)
+          (log/tracef "Coerced -> %s" (binding [*print-meta* true] (pr-str <>))))))
+    clause))
+
+(doseq [filter-type [:between := :!= :> :>= :< :<=]]
+  (defmethod sql.qp/->honeysql [:bigquery filter-type]
+    [driver clause]
+    ((get-method sql.qp/->honeysql [:sql filter-type])
+     driver
+     (reconcile-temporal-types clause))))
 
 
 ;;; +----------------------------------------------------------------------------------------------------------------+
@@ -370,8 +453,17 @@
 ;;; +----------------------------------------------------------------------------------------------------------------+
 
 (defmethod driver/date-add :bigquery
-  [_ dt amount unit]
-  (hsql/call :datetime_add (hx/->datetime dt) (hsql/raw (format "INTERVAL %d %s" (int amount) (name unit)))))
+  [driver expr amount unit]
+  (let [add-fn (case (temporal-type expr)
+                 :timestamp :timestamp_add
+                 :datetime  :datetime_add
+                 :date      :date_add
+                 :time      :time_add
+                 nil)]
+    (if-not add-fn
+      (driver/date-add driver (->temporal-type :datetime expr) amount unit)
+      (with-meta (hsql/call add-fn expr (hsql/raw (format "INTERVAL %d %s" (int amount) (name unit))))
+        {:bigquery/temporal-type (temporal-type expr)}))))
 
 (defmethod driver/mbql->native :bigquery
   [driver
@@ -392,7 +484,7 @@
 
 (defmethod sql.qp/current-datetime-fn :bigquery
   [_]
-  :%current_timestamp)
+  (with-meta (hsql/call :current_timestamp) {:bigquery/temporal-type :timestamp}))
 
 (defmethod sql.qp/quote-style :bigquery
   [_]
diff --git a/modules/drivers/bigquery/test/metabase/driver/bigquery/query_processor_test.clj b/modules/drivers/bigquery/test/metabase/driver/bigquery/query_processor_test.clj
index ddb87a3d056e30ae741de9445ab77112cc4a09dd..caeb7bf28197dfae66e1a15a0822cef4a08ee0c8 100644
--- a/modules/drivers/bigquery/test/metabase/driver/bigquery/query_processor_test.clj
+++ b/modules/drivers/bigquery/test/metabase/driver/bigquery/query_processor_test.clj
@@ -4,27 +4,21 @@
             [java-time :as t]
             [metabase
              [driver :as driver]
+             [models :refer [Database Field]]
              [query-processor :as qp]
              [query-processor-test :as qp.test]
+             [test :as mt]
              [util :as u]]
             [metabase.driver.bigquery :as bigquery]
+            [metabase.driver.bigquery.query-processor :as bigquery.qp]
             [metabase.driver.sql.query-processor :as sql.qp]
-            [metabase.models
-             [database :refer [Database]]
-             [field :refer [Field]]]
-            [metabase.query-processor
-             [store :as qp.store]
-             [test-util :as qp.test-util]]
-            [metabase.test
-             [data :as data]
-             [util :as tu]]
-            [metabase.test.data.datasets :as datasets]
+            [metabase.query-processor.store :as qp.store]
             [metabase.test.util.timezone :as tu.tz]
             [metabase.util.honeysql-extensions :as hx]
             [toucan.util.test :as tt]))
 
 (deftest native-query-test
-  (datasets/test-driver :bigquery
+  (mt/test-driver :bigquery
     (is (= [[100]
             [99]]
            (get-in
@@ -34,7 +28,7 @@
                                       "ORDER BY `test_data.venues`.`id` DESC "
                                       "LIMIT 2;")}
                :type     :native
-               :database (data/id)})
+               :database (mt/id)})
             [:data :rows])))
 
     (is (= [{:name         "venue_id"
@@ -60,24 +54,24 @@
                                        "FROM `test_data.checkins` "
                                        "LIMIT 2")}
                 :type     :native
-                :database (data/id)})))
+                :database (mt/id)})))
         (str "make sure that BigQuery native queries maintain the column ordering specified in the SQL -- "
              "post-processing ordering shouldn't apply (Issue #2821)"))))
 
 (deftest aggregations-test
-  (datasets/test-driver :bigquery
+  (mt/test-driver :bigquery
     (testing (str "make sure queries with two or more of the same aggregation type still work. Aggregations used to be "
                   "deduplicated here in the BigQuery driver; now they are deduplicated as part of the main QP "
                   "middleware, but no reason not to keep a few of these tests just to be safe")
       (let [{:keys [rows columns]} (qp.test/rows+column-names
-                                     (data/run-mbql-query checkins
+                                     (mt/run-mbql-query checkins
                                        {:aggregation [[:sum $user_id] [:sum $user_id]]}))]
         (is (= ["sum" "sum_2"]
                columns))
         (is (= [[7929 7929]]
                rows)))
       (let [{:keys [rows columns]} (qp.test/rows+column-names
-                                     (data/run-mbql-query checkins
+                                     (mt/run-mbql-query checkins
                                        {:aggregation [[:sum $user_id] [:sum $user_id] [:sum $user_id]]}))]
         (is (= ["sum" "sum_2" "sum_3"]
                columns))
@@ -92,10 +86,10 @@
               :from     [(hx/identifier :table "test_data.venues")]
               :group-by [(hx/identifier :field-alias "price")]
               :order-by [[(hx/identifier :field-alias "avg") :asc]]}
-             (qp.test-util/with-everything-store
+             (mt/with-everything-store
                (#'sql.qp/mbql->honeysql
                 :bigquery
-                (data/mbql-query venues
+                (mt/mbql-query venues
                   {:aggregation [[:avg $category_id]]
                    :breakout    [$price]
                    :order-by    [[:asc [:aggregation 0]]]})))))
@@ -108,11 +102,11 @@
               :table-name "venues"
               :mbql?      true}
              (qp/query->native
-               (data/mbql-query venues
+               (mt/mbql-query venues
                  {:aggregation [[:avg $category_id]], :breakout [$price], :order-by [[:asc [:aggregation 0]]]})))))))
 
 (deftest join-alias-test
-  (datasets/test-driver :bigquery
+  (mt/test-driver :bigquery
     (is (= (str "SELECT `categories__via__category_id`.`name` AS `name`,"
                 " count(*) AS `count` "
                 "FROM `test_data.venues` "
@@ -123,9 +117,9 @@
            ;; normally for test purposes BigQuery doesn't support foreign keys so override the function that checks
            ;; that and make it return `true` so this test proceeds as expected
            (with-redefs [driver/supports? (constantly true)]
-             (tu/with-temp-vals-in-db Field (data/id :venues :category_id) {:fk_target_field_id (data/id :categories :id)
+             (mt/with-temp-vals-in-db Field (mt/id :venues :category_id) {:fk_target_field_id (mt/id :categories :id)
                                                                             :special_type       "type/FK"}
-               (let [results (data/run-mbql-query venues
+               (let [results (mt/run-mbql-query venues
                                {:aggregation [:count]
                                 :breakout    [$category_id->categories.name]})]
                  (get-in results [:data :native_form :query] results)))))
@@ -143,15 +137,15 @@
       ffirst))
 
 (deftest parsed-date-timezone-handling-test
-  (datasets/test-driver :bigquery
+  (mt/test-driver :bigquery
     (is (= "2018-08-31T00:00:00Z"
-           (native-timestamp-query (data/id) "2018-08-31 00:00:00" "UTC"))
+           (native-timestamp-query (mt/id) "2018-08-31 00:00:00" "UTC"))
         "A UTC date is returned, we should read/return it as UTC")
 
     (is (= "2018-08-31T00:00:00-05:00"
            (tu.tz/with-system-timezone-id "America/Chicago"
              (tt/with-temp* [Database [db {:engine  :bigquery
-                                           :details (assoc (:details (data/db))
+                                           :details (assoc (:details (mt/db))
                                                            :use-jvm-timezone true)}]]
                (native-timestamp-query db "2018-08-31 00:00:00-05" "America/Chicago"))))
         (str "This test includes a `use-jvm-timezone` flag of true that will assume that the date coming from BigQuery "
@@ -161,7 +155,7 @@
     (is (= "2018-08-31T00:00:00+07:00"
            (tu.tz/with-system-timezone-id "Asia/Jakarta"
              (tt/with-temp* [Database [db {:engine  :bigquery
-                                           :details (assoc (:details (data/db))
+                                           :details (assoc (:details (mt/db))
                                                            :use-jvm-timezone true)}]]
                (native-timestamp-query db "2018-08-31 00:00:00+07" "Asia/Jakarta"))))
         "Similar to the above test, but covers a positive offset")))
@@ -173,16 +167,16 @@
     (with-redefs [bigquery/process-native* (fn [_ sql]
                                              (reset! native-query sql)
                                              (throw (Exception. "Done.")))]
-      (qp/process-query {:database (data/id)
+      (qp/process-query {:database (mt/id)
                          :type     :query
-                         :query    {:source-table (data/id :venues)
+                         :query    {:source-table (mt/id :venues)
                                     :limit        1}
                          :info     {:executed-by 1000
                                     :query-hash  (byte-array [1 2 3 4])}})
       @native-query)))
 
 (deftest remark-test
-  (datasets/test-driver :bigquery
+  (mt/test-driver :bigquery
     (is (= (str
             "-- Metabase:: userID: 1000 queryType: MBQL queryHash: 01020304\n"
             "SELECT `test_data.venues`.`id` AS `id`,"
@@ -194,20 +188,20 @@
             "FROM `test_data.venues` "
             "LIMIT 1")
            (query->native
-            {:database (data/id)
+            {:database (mt/id)
              :type     :query
-             :query    {:source-table (data/id :venues)
+             :query    {:source-table (mt/id :venues)
                         :limit        1}
              :info     {:executed-by 1000
                         :query-hash  (byte-array [1 2 3 4])}}))
         "if I run a BigQuery query, does it get a remark added to it?")))
 
 (deftest unprepare-params-test
-  (datasets/test-driver :bigquery
+  (mt/test-driver :bigquery
     (is (= [["Red Medicine"]]
            (qp.test/rows
              (qp/process-query
-               {:database (data/id)
+               {:database (mt/id)
                 :type     :native
                 :native   {:query  (str "SELECT `test_data.venues`.`name` AS `name` "
                                         "FROM `test_data.venues` "
@@ -216,17 +210,110 @@
         (str "Do we properly unprepare, and can we execute, queries that still have parameters for one reason or "
              "another? (EE #277)"))))
 
+(def ^:private reconcile-test-values
+  [{:value (t/local-date "2019-12-10")
+    :type  :date
+    :as    {:datetime  (t/local-date-time "2019-12-10T00:00:00")
+            :timestamp (t/zoned-date-time "2019-12-10T00:00:00Z[UTC]")}}
+   {:value (t/local-date-time "2019-12-10T14:47:00")
+    :type  :datetime
+    :as    {:date      (t/local-date "2019-12-10")
+            :timestamp (t/zoned-date-time "2019-12-10T14:47:00Z[UTC]")}}
+   {:value (t/zoned-date-time "2019-12-10T14:47:00Z[UTC]")
+    :type  :timestamp
+    :as    {:date     (t/local-date "2019-12-10")
+            :datetime (t/local-date-time "2019-12-10T14:47:00")}}
+   {:value (t/offset-date-time "2019-12-10T14:47:00Z")
+    :type  :timestamp
+    :as    {:date     (t/local-date "2019-12-10")
+            :datetime (t/local-date-time "2019-12-10T14:47:00")}}
+   (let [unix-ts (sql.qp/unix-timestamp->timestamp :bigquery :seconds :some_field)]
+     {:value unix-ts
+      :type  :timestamp
+      :as    {:date     (hx/cast :date unix-ts)
+              :datetime (hx/cast :datetime unix-ts)}})
+   (let [unix-ts (sql.qp/unix-timestamp->timestamp :bigquery :milliseconds :some_field)]
+     {:value unix-ts
+      :type  :timestamp
+      :as    {:date     (hx/cast :date unix-ts)
+              :datetime (hx/cast :datetime unix-ts)}})])
+
+(deftest temporal-type-test
+  (testing "Make sure we can detect temporal types correctly"
+    (doseq [[expr expected-type] {[:field-literal "x" :type/DateTime]                                :datetime
+                                  [:datetime-field [:field-literal "x" :type/DateTime] :day-of-week] nil}]
+      (testing (format "\n(temporal-type %s)" (binding [*print-meta* true] (pr-str expr)))
+        (is (= expected-type
+               (#'bigquery.qp/temporal-type expr)))))))
+
+(deftest reconcile-temporal-types-test
+  (mt/with-everything-store
+    (tt/with-temp* [Field [date-field      {:name "date", :base_type :type/Date}]
+                    Field [datetime-field  {:name "datetime", :base_type :type/DateTime}]
+                    Field [timestamp-field {:name "timestamp", :base_type :type/DateTimeWithLocalTZ}]]
+      ;; bind `*table-alias*` so the BigQuery QP doesn't try to look up the current dataset name when converting
+      ;; `hx/identifier`s to SQL
+      (binding [sql.qp/*table-alias* "ABC"
+                *print-meta*         true]
+        (let [fields {:date      date-field
+                      :datetime  datetime-field
+                      :timestamp timestamp-field}]
+          (doseq [clause [{:args 2, :mbql :=, :honeysql :=}
+                          {:args 2, :mbql :!=, :honeysql :not=}
+                          {:args 2, :mbql :>, :honeysql :>}
+                          {:args 2, :mbql :>=, :honeysql :>=}
+                          {:args 2, :mbql :<, :honeysql :<}
+                          {:args 2, :mbql :<=, :honeysql :<=}
+                          {:args 3, :mbql :between, :honeysql :between}]]
+            (testing (format "\n%s filter clause" (:mbql clause))
+              (doseq [[temporal-type field] fields
+                      field                 [field
+                                             [:field-id (:id field)]
+                                             [:datetime-field [:field-id (:id field)] :default]
+                                             [:field-literal (:name field) (:base_type field)]
+                                             [:datetime-field [:field-literal (:name field) (:base_type field)] :default]]]
+                (testing (format "\nField = %s %s"
+                                 temporal-type
+                                 (if (map? field) (format "<Field %s>" (pr-str (:name field))) field))
+                  (doseq [{filter-value :value, :as value} reconcile-test-values
+                          filter-value                     (cons filter-value
+                                                                 (when (instance? java.time.temporal.Temporal filter-value)
+                                                                   [[:absolute-datetime filter-value :default]]))]
+                    (testing (format "\nValue = %s %s" (:type value) (pr-str filter-value))
+                      (let [filter-clause       (into [(:mbql clause) field]
+                                                      (repeat (dec (:args clause)) filter-value))
+                            expected-identifier (hx/identifier :field "ABC" (name temporal-type))
+                            expected-value      (get-in value [:as temporal-type] (:value value))
+                            expected-clause     (into [(:honeysql clause) expected-identifier]
+                                                      (repeat (dec (:args clause)) expected-value))]
+                        (testing (format "\nreconcile %s -> %s"
+                                         (into [(:mbql clause) temporal-type] (repeat (dec (:args clause)) (:type value)))
+                                         (into [(:mbql clause) temporal-type] (repeat (dec (:args clause)) temporal-type)))
+                          (testing (format "\ninferred field type = %s, inferred value type = %s"
+                                           (#'bigquery.qp/temporal-type field)
+                                           (#'bigquery.qp/temporal-type filter-value))
+                            (is (= expected-clause
+                                   (sql.qp/->honeysql :bigquery filter-clause))))))))))))
+          (testing "\ndate extraction filters"
+            (doseq [[temporal-type field] fields
+                    :let                  [identifier          (hx/identifier :field "ABC" (name temporal-type))
+                                           expected-identifier (if (= temporal-type :timestamp)
+                                                                 identifier
+                                                                 (hx/cast :timestamp identifier))]]
+              (is (= [:= (hsql/call :extract :dayofweek expected-identifier) 1]
+                     (sql.qp/->honeysql :bigquery [:= [:datetime-field [:field-id (:id field)] :day-of-week] 1]))))))))))
+
 (deftest between-test
   (testing "Make sure :between clauses reconcile the temporal types of their args"
     (letfn [(between->sql [clause]
               (sql.qp/format-honeysql :bigquery
                 {:where (sql.qp/->honeysql :bigquery clause)}))]
-      (testing "Should look for `:mbql/temporal-type` metadata"
+      (testing "Should look for `:bigquery/temporal-type` metadata"
         (is (= ["WHERE field BETWEEN ? AND ?"
                 (t/local-date-time "2019-11-11T00:00")
                 (t/local-date-time "2019-11-12T00:00")]
                (between->sql [:between
-                              (with-meta (hsql/raw "field") {:mbql/temporal-type :datetime})
+                              (with-meta (hsql/raw "field") {:bigquery/temporal-type :datetime})
                               (t/local-date "2019-11-11")
                               (t/local-date "2019-11-12")]))))
       (testing "If first arg has no temporal-type info, should look at next arg"
@@ -242,31 +329,31 @@
                 (t/local-date "2019-11-11")
                 (t/local-date "2019-11-12")]
                (between->sql [:between
-                              (with-meta (hsql/raw "field") {:mbql/temporal-type :date})
+                              (with-meta (hsql/raw "field") {:bigquery/temporal-type :date})
                               (t/local-date "2019-11-11")
                               (t/local-date "2019-11-12")]))))
-      (datasets/test-driver :bigquery
-        (qp.test-util/with-everything-store
+      (mt/test-driver :bigquery
+        (mt/with-everything-store
           (let [expected ["WHERE `test_data.checkins`.`date` BETWEEN ? AND ?"
-                          (t/local-date-time "2019-11-11T00:00")
-                          (t/local-date-time "2019-11-12T00:00")]]
+                          (t/zoned-date-time "2019-11-11T00:00Z[UTC]")
+                          (t/zoned-date-time "2019-11-12T00:00Z[UTC]")]]
             (testing "Should be able to get temporal type from a FieldInstance"
               (is (= expected
                      (between->sql [:between
-                                    (qp.store/field (data/id :checkins :date))
+                                    (qp.store/field (mt/id :checkins :date))
                                     (t/local-date "2019-11-11")
                                     (t/local-date "2019-11-12")]))))
             (testing "Should be able to get temporal type from a :field-id"
               (is (= expected
                      (between->sql [:between
-                                    [:field-id (data/id :checkins :date)]
+                                    [:field-id (mt/id :checkins :date)]
                                     (t/local-date "2019-11-11")
                                     (t/local-date "2019-11-12")]))))
             (testing "Should be able to get temporal type from a wrapped field-id"
-              (is (= (cons "WHERE timestamp_trunc(CAST(`test_data.checkins`.`date` AS timestamp), day) BETWEEN ? AND ?"
+              (is (= (cons "WHERE timestamp_trunc(`test_data.checkins`.`date`, day) BETWEEN ? AND ?"
                            (rest expected))
                      (between->sql [:between
-                                    [:datetime-field [:field-id (data/id :checkins :date)] :day]
+                                    [:datetime-field [:field-id (mt/id :checkins :date)] :day]
                                     (t/local-date "2019-11-11")
                                     (t/local-date "2019-11-12")]))))
             (testing "Should work with a field literal"
diff --git a/modules/drivers/bigquery/test/metabase/driver/bigquery_test.clj b/modules/drivers/bigquery/test/metabase/driver/bigquery_test.clj
index 67f3f85a5a4e2cbc603521cf9f6b1fef5eddb5f7..6eb1fdc1d7d8e02ea62692d3197a2101a7d752d9 100644
--- a/modules/drivers/bigquery/test/metabase/driver/bigquery_test.clj
+++ b/modules/drivers/bigquery/test/metabase/driver/bigquery_test.clj
@@ -2,13 +2,11 @@
   (:require [clojure.test :refer :all]
             [metabase
              [driver :as driver]
+             [models :refer [Field Table]]
              [query-processor :as qp]
              [query-processor-test :as qp.test]
              [sync :as sync]]
             [metabase.db.metadata-queries :as metadata-queries]
-            [metabase.models
-             [field :refer [Field]]
-             [table :refer [Table]]]
             [metabase.test
              [data :as data]
              [util :as tu]]
@@ -61,13 +59,8 @@
 (deftest sync-views-test
   (datasets/test-driver :bigquery
     (with-view [view-name]
-      (is (= {:tables
-              #{{:schema nil, :name "categories"}
-                {:schema nil, :name "checkins"}
-                {:schema nil, :name "users"}
-                {:schema nil, :name "venues"}
-                {:schema nil, :name view-name}}}
-             (driver/describe-database :bigquery (data/db)))
+      (is (contains? (:tables (driver/describe-database :bigquery (data/db)))
+                     {:schema nil, :name view-name})
           "`describe-database` should see the view")
       (is (= {:schema nil
               :name   view-name
@@ -99,3 +92,38 @@
                      {:fields   [$id $date]
                       :filter   [:= $date "2015-11-19"]
                       :order-by [[:asc $id]]})))))))))
+
+(defn- do-with-datetime-timestamp-table [f]
+  (driver/with-driver :bigquery
+    (let [table-name (name (munge (gensym "table_")))]
+      (data/with-temp-copy-of-db
+        (try
+          (bigquery.tx/execute!
+           (format "CREATE TABLE `test_data.%s` ( ts TIMESTAMP, dt DATETIME )" table-name))
+          (bigquery.tx/execute!
+           (format "INSERT INTO `test_data.%s` (ts, dt) VALUES (TIMESTAMP \"2020-01-01 00:00:00 UTC\", DATETIME \"2020-01-01 00:00:00\")"
+                   table-name))
+          (sync/sync-database! (data/db))
+          (f table-name)
+          (finally
+            (bigquery.tx/execute! "DROP TABLE IF EXISTS `test_data.%s`" table-name)))))))
+
+(deftest filter-by-datetime-timestamp-test
+  (datasets/test-driver :bigquery
+    ;; there are more tests in the `bigquery.query-processor-test` namespace
+    (testing "Make sure we can filter against different types of BigQuery temporal columns (#11222)"
+      (do-with-datetime-timestamp-table
+       (fn [table-name]
+         (doseq [column [:ts :dt]]
+           (testing (format "Filtering against %s column" column)
+             (doseq [s    ["2020-01-01" "2020-01-01T00:00:00"]
+                     field [[:field-id (data/id table-name column)]
+                            [:datetime-field [:field-id (data/id table-name column)] :default]
+                            [:datetime-field [:field-id (data/id table-name column)] :day]]
+                     :let [filter-clause [:= field s]]]
+               (testing (format "\nMBQL filter clause = %s" (pr-str filter-clause))
+                 (is (= [["2020-01-01T00:00:00Z" "2020-01-01T00:00:00Z"]]
+                        (qp.test/rows
+                          (data/run-mbql-query nil
+                            {:source-table (data/id table-name)
+                             :filter       filter-clause})))))))))))))
diff --git a/src/metabase/driver/sql/query_processor.clj b/src/metabase/driver/sql/query_processor.clj
index f07ef47d69b8cf1d6b162eff677a4c8ffcb4b959..4d320f4805cda314d5b57601ae0db6f17131853f 100644
--- a/src/metabase/driver/sql/query_processor.clj
+++ b/src/metabase/driver/sql/query_processor.clj
@@ -444,45 +444,56 @@
   [value :- (s/constrained mbql.s/value #(string? (second %)) "string value"), f]
   (update value 1 f))
 
-(defmethod ->honeysql [:sql :starts-with] [driver [_ field value options]]
+(defmethod ->honeysql [:sql :starts-with]
+  [driver [_ field value options]]
   (like-clause driver (->honeysql driver field) (update-string-value value #(str % \%)) options))
 
-(defmethod ->honeysql [:sql :contains] [driver [_ field value options]]
+(defmethod ->honeysql [:sql :contains]
+  [driver [_ field value options]]
   (like-clause driver (->honeysql driver field) (update-string-value value #(str \% % \%)) options))
 
-(defmethod ->honeysql [:sql :ends-with] [driver [_ field value options]]
+(defmethod ->honeysql [:sql :ends-with]
+  [driver [_ field value options]]
   (like-clause driver (->honeysql driver field) (update-string-value value #(str \% %)) options))
 
-(defmethod ->honeysql [:sql :between] [driver [_ field min-val max-val]]
+(defmethod ->honeysql [:sql :between]
+  [driver [_ field min-val max-val]]
   [:between (->honeysql driver field) (->honeysql driver min-val) (->honeysql driver max-val)])
 
-
-(defmethod ->honeysql [:sql :>] [driver [_ field value]]
+(defmethod ->honeysql [:sql :>]
+  [driver [_ field value]]
   [:> (->honeysql driver field) (->honeysql driver value)])
 
-(defmethod ->honeysql [:sql :<] [driver [_ field value]]
+(defmethod ->honeysql [:sql :<]
+  [driver [_ field value]]
   [:< (->honeysql driver field) (->honeysql driver value)])
 
-(defmethod ->honeysql [:sql :>=] [driver [_ field value]]
+(defmethod ->honeysql [:sql :>=]
+  [driver [_ field value]]
   [:>= (->honeysql driver field) (->honeysql driver value)])
 
-(defmethod ->honeysql [:sql :<=] [driver [_ field value]]
+(defmethod ->honeysql [:sql :<=]
+  [driver [_ field value]]
   [:<= (->honeysql driver field) (->honeysql driver value)])
 
-(defmethod ->honeysql [:sql :=] [driver [_ field value]]
+(defmethod ->honeysql [:sql :=]
+  [driver [_ field value]]
   [:= (->honeysql driver field) (->honeysql driver value)])
 
-(defmethod ->honeysql [:sql :!=] [driver [_ field value]]
+(defmethod ->honeysql [:sql :!=]
+  [driver [_ field value]]
   [:not= (->honeysql driver field) (->honeysql driver value)])
 
-
-(defmethod ->honeysql [:sql :and] [driver [_ & subclauses]]
+(defmethod ->honeysql [:sql :and]
+  [driver [_ & subclauses]]
   (apply vector :and (map (partial ->honeysql driver) subclauses)))
 
-(defmethod ->honeysql [:sql :or] [driver [_ & subclauses]]
+(defmethod ->honeysql [:sql :or]
+  [driver [_ & subclauses]]
   (apply vector :or (map (partial ->honeysql driver) subclauses)))
 
-(defmethod ->honeysql [:sql :not] [driver [_ subclause]]
+(defmethod ->honeysql [:sql :not]
+  [driver [_ subclause]]
   [:not (->honeysql driver subclause)])
 
 (defmethod apply-top-level-clause [:sql :filter]
diff --git a/src/metabase/plugins/classloader.clj b/src/metabase/plugins/classloader.clj
index 9e73640008c5aa29dd83934d9bf335ed11b46662..d63538927ca1d2468ca4d025718fe2beb69f87d8 100644
--- a/src/metabase/plugins/classloader.clj
+++ b/src/metabase/plugins/classloader.clj
@@ -81,7 +81,7 @@
        current-thread-context-classloader))
    ;; otherwise set the current thread's context classloader to the shared context classloader
    (let [shared-classloader @shared-context-classloader]
-     (log/debug
+     (log/trace
       (deferred-trs "Setting current thread context classloader to shared classloader {0}..." shared-classloader))
      (.setContextClassLoader (Thread/currentThread) shared-classloader)
      shared-classloader)))
diff --git a/src/metabase/util/honeysql_extensions.clj b/src/metabase/util/honeysql_extensions.clj
index a85fa3d167852f6efbf79db1409b6c0079eaef9b..61ede48659ef7d2887cae307d4965be4f1232436 100644
--- a/src/metabase/util/honeysql_extensions.clj
+++ b/src/metabase/util/honeysql_extensions.clj
@@ -186,8 +186,9 @@
 (require 'honeysql.types)
 (extend-protocol PrettyPrintable
   honeysql.types.SqlCall
-  (pretty [{fn-name :name, args :args}]
-    (apply list 'hsql/call fn-name args)))
+  (pretty [{fn-name :name, args :args, :as this}]
+    (with-meta (apply list 'hsql/call fn-name args)
+      (meta this))))
 
 (defmethod print-method honeysql.types.SqlCall
   [call writer]
diff --git a/test/metabase/query_processor_test/date_bucketing_test.clj b/test/metabase/query_processor_test/date_bucketing_test.clj
index 2e9dd86faa981a96fd2d8efdcaea804ea65e79af..c2a97e5249320d3a1f7e9142ffc4c0008fef10b2 100644
--- a/test/metabase/query_processor_test/date_bucketing_test.clj
+++ b/test/metabase/query_processor_test/date_bucketing_test.clj
@@ -1057,7 +1057,7 @@
   (testing "Additional tests for filtering against various datetime bucketing units that aren't tested above"
     (mt/test-drivers (mt/normal-drivers)
       (doseq [[expected-count unit filter-value] addition-unit-filtering-vals]
-        (testing unit
+        (testing (format "\nunit = %s" unit)
           (let [result (count-of-checkins unit filter-value)]
             (if (integer? expected-count)
               (is (= expected-count result)
diff --git a/test/metabase/query_processor_test/filter_test.clj b/test/metabase/query_processor_test/filter_test.clj
index 78a7e36905b8524f6183ce63a1e23aff118465c4..621d8f39e336c81188b1c09a119193852d55df62 100644
--- a/test/metabase/query_processor_test/filter_test.clj
+++ b/test/metabase/query_processor_test/filter_test.clj
@@ -3,7 +3,8 @@
   (:require [clojure.test :refer :all]
             [metabase
              [driver :as driver]
-             [query-processor-test :as qp.test]]
+             [query-processor-test :as qp.test]
+             [test :as mt]]
             [metabase.test.data :as data]
             [metabase.test.data.datasets :as datasets]))
 
@@ -119,34 +120,30 @@
     (data/run-mbql-query venues
       {:filter [:inside $latitude $longitude 10.0649 -165.379 10.0641 -165.371]})))
 
-;;; FILTER - `is-null` & `not-null` on datetime columns
-(qp.test/expect-with-non-timeseries-dbs
-  [1000]
-  (qp.test/first-row
-    (qp.test/format-rows-by [int]
-      (data/run-mbql-query checkins
-        {:aggregation [[:count]]
-         :filter      [:not-null $date]}))))
-
-;; Creates a query that uses a field-literal. Normally our test queries will use a field placeholder, but
-;; https://github.com/metabase/metabase/issues/7381 is only triggered by a field literal
-(qp.test/expect-with-non-timeseries-dbs
-  [1000]
-  (qp.test/first-row
-    (qp.test/format-rows-by [int]
-      (data/run-mbql-query checkins
-        {:aggregation [[:count]]
-         :filter      ["NOT_NULL"
-                       ["field-id"
-                        ["field-literal" (data/format-name "date") "type/DateTime"]]]}))))
-
-(qp.test/expect-with-non-timeseries-dbs
-  true
-  (let [result (qp.test/first-row (data/run-mbql-query checkins
-                            {:aggregation [[:count]]
-                             :filter      [:is-null $date]}))]
-    ;; Some DBs like Mongo don't return any results at all in this case, and there's no easy workaround
-    (contains? #{[0] [0M] [nil] nil} result)))
+(deftest is-null-test
+  (mt/test-drivers (mt/normal-drivers)
+    (let [result (qp.test/first-row (data/run-mbql-query checkins
+                                      {:aggregation [[:count]]
+                                       :filter      [:is-null $date]}))]
+      ;; Some DBs like Mongo don't return any results at all in this case, and there's no easy workaround
+      (is (= true
+             (contains? #{[0] [0M] [nil] nil} result))))))
+
+(deftest not-null-test
+  (mt/test-drivers (mt/normal-drivers)
+    (is (= [1000]
+           (qp.test/first-row
+             (qp.test/format-rows-by [int]
+               (data/run-mbql-query checkins
+                 {:aggregation [[:count]]
+                  :filter      [:not-null $date]})))))
+    (testing "Make sure :not-null filters work correctly with field literals (#7381)"
+      (is (= [1000]
+             (qp.test/first-row
+               (qp.test/format-rows-by [int]
+                 (data/run-mbql-query checkins
+                   {:aggregation [[:count]]
+                    :filter      [:not-null *date]}))))))))
 
 
 ;;; +----------------------------------------------------------------------------------------------------------------+
diff --git a/test/metabase/query_processor_test/parameters_test.clj b/test/metabase/query_processor_test/parameters_test.clj
index 103dda8d51c37a4670d48db6c54d7b3e44d6cf09..27e256dfbf0c1869e9db04dd1cf6594d5abae138 100644
--- a/test/metabase/query_processor_test/parameters_test.clj
+++ b/test/metabase/query_processor_test/parameters_test.clj
@@ -39,13 +39,14 @@
                              :aggregation  [[:count]]
                              :filter       (into [:and]
                                                  (for [[i [field]] (map-indexed vector field->type+value)]
-                                                   [:= (mt/id table field) i]))})
+                                                   [:= [:field-id (mt/id table field)] i]))})
           {:keys [query]} (qp/query->native mbql-query)
           query           (reduce
-                           (fn [query [i [field]]]
-                             (str/replace query (re-pattern (format "= %d" i)) (format "= {{%s}}" (name field))))
+                           (fn [query [field]]
+                             ;; TODO — currently only supports one field
+                             (str/replace query (re-pattern #"= .*") (format "= {{%s}}" (name field))))
                            query
-                           (map-indexed vector field->type+value))]
+                           field->type+value)]
       (log/tracef "%s\n->\n%s\n->\n%s"
                   (pr-str (list 'native-count-query driver table field->type+value))
                   (pr-str mbql-query)