diff --git a/project.clj b/project.clj
index a8e81fdd03b8c780125e85a696ebfc2a157e1fbd..94e1048316d66fde5047c13aafbe35255f35fd66 100644
--- a/project.clj
+++ b/project.clj
@@ -64,13 +64,13 @@
                  [org.yaml/snakeyaml "1.17"]                          ; YAML parser (required by liquibase)
                  [org.xerial/sqlite-jdbc "3.8.11.2"]                  ; SQLite driver
                  [postgresql "9.3-1102.jdbc41"]                       ; Postgres driver
+                 [io.crate/crate-jdbc "1.11.0"]                       ; Crate JDBC driver
+                 [io.crate/crate-client "0.54.7"]                     ; Crate Java client (used by Crate JDBC)
                  [prismatic/schema "1.1.1"]                           ; Data schema declaration and validation library
                  [ring/ring-jetty-adapter "1.4.0"]                    ; Ring adapter using Jetty webserver (used to run a Ring server for unit tests)
                  [ring/ring-json "0.4.0"]                             ; Ring middleware for reading/writing JSON automatically
                  [stencil "0.5.0"]                                    ; Mustache templates for Clojure
-                 [swiss-arrows "1.0.0"]                               ; 'Magic wand' macro -<>, etc.
-                 [io.crate/crate-jdbc "1.11.0"]
-                 [io.crate/crate-client "0.54.7"]]
+                 [swiss-arrows "1.0.0"]]                              ; 'Magic wand' macro -<>, etc.
   :repositories [["bintray" "https://dl.bintray.com/crate/crate"]]
   :plugins [[lein-environ "1.0.2"]                                    ; easy access to environment variables
             [lein-ring "0.9.7"                                        ; start the HTTP server with 'lein ring server'
diff --git a/src/metabase/driver/crate.clj b/src/metabase/driver/crate.clj
index 7a48b03bc74e316399327e77a26da1324da5af59..a0bc3d81790b231538615b8b7c71ceb75ee9c19a 100644
--- a/src/metabase/driver/crate.clj
+++ b/src/metabase/driver/crate.clj
@@ -59,7 +59,7 @@
          (dissoc opts :hosts)))
 
 (defn- connection-details->spec [_ details]
-  (-> details crate-spec))
+  (crate-spec details))
 
 (defn- can-connect [driver details]
   (let [connection (connection-details->spec driver details)]
diff --git a/src/metabase/driver/crate/native.clj b/src/metabase/driver/crate/native.clj
index 3b00feb46169ec0e33d2d59e08b0caed3213e1bf..f06f5a7da42a0487e269cb883b0ceb36089bea8d 100644
--- a/src/metabase/driver/crate/native.clj
+++ b/src/metabase/driver/crate/native.clj
@@ -13,16 +13,16 @@
   (try (let [database (sel :one :fields [Database :engine :details] :id database-id)
              db-conn  (sql/db->jdbc-connection-spec database)]
          (jdbc/with-db-connection [t-conn db-conn]
-                                  (let [^java.sql.Connection jdbc-connection (:connection t-conn)]
-                                    (try
-                                      ;; Now run the query itself
-                                      (log/debug (u/format-color 'green "%s" sql))
-                                      (let [[columns & [first-row :as rows]] (jdbc/query t-conn sql, :as-arrays? true)]
-                                        {:rows    rows
-                                         :columns columns
-                                         :cols    (for [[column first-value] (partition 2 (interleave columns first-row))]
-                                                    {:name      column
-                                                     :base_type (n/value->base-type first-value)})})))))
+           (let [^java.sql.Connection jdbc-connection (:connection t-conn)]
+             (try
+               ;; Now run the query itself
+               (log/debug (u/format-color 'green "%s" sql))
+               (let [[columns & [first-row :as rows]] (jdbc/query t-conn sql, :as-arrays? true)]
+                 {:rows    rows
+                  :columns columns
+                  :cols    (for [[column first-value] (partition 2 (interleave columns first-row))]
+                             {:name      column
+                              :base_type (n/value->base-type first-value)})})))))
        (catch java.sql.SQLException e
          (let [^String message (or (->> (.getMessage e)     ; error message comes back like 'Column "ZID" not found; SQL statement: ... [error-code]' sometimes
                                         (re-find #"^(.*);") ; the user already knows the SQL, and error code is meaningless
diff --git a/src/metabase/driver/crate/query_processor.clj b/src/metabase/driver/crate/query_processor.clj
index df88e8adb706f6bb90e46e290a39432c3aa04577..a818c5800773de6d89fa096353afb57a93ab3457 100644
--- a/src/metabase/driver/crate/query_processor.clj
+++ b/src/metabase/driver/crate/query_processor.clj
@@ -2,14 +2,15 @@
   (:require [korma.core :as k]
             [metabase.driver.generic-sql.query-processor :as qp]
             [korma.sql.fns :as kfns]
-            [korma.sql.engine :as kengine])
+            [korma.sql.engine :as kengine]
+            [metabase.query-processor.interface :as i])
   (:import (metabase.query_processor.interface ComparisonFilter CompoundFilter)))
 
 (defn- rewrite-between
   "Rewrite [:between <field> <min> <max>] -> [:and [:>= <field> <min>] [:<= <field> <max>]]"
   [clause]
-  (CompoundFilter. :and [(ComparisonFilter. :>= (:field clause) (:min-val clause))
-                         (ComparisonFilter. :<= (:field clause) (:max-val clause))]))
+  (i/strict-map->CompoundFilter {:compound-type :and :subclauses [(ComparisonFilter. :>= (:field clause) (:min-val clause))
+                                       (ComparisonFilter. :<= (:field clause) (:max-val clause))]}))
 
 (defn resolve-subclauses
   "resolve filters recursively"
diff --git a/src/metabase/driver/crate/util.clj b/src/metabase/driver/crate/util.clj
index 5bd2bcbb5fa2d9c7f8b04de962d6aadeea87928c..dd73dd8d9036f4cd50d35a3a0754f3243e734b65 100644
--- a/src/metabase/driver/crate/util.clj
+++ b/src/metabase/driver/crate/util.clj
@@ -3,7 +3,7 @@
             [korma.sql.utils :as kutils]
             [korma.core :as k]
             [metabase.util :as u]
-            [metabase.driver :as driver])
+            [metabase.driver.generic-sql.query-processor :as qp])
   (:import (java.sql Timestamp)))
 
 (defn unix-timestamp->timestamp [_ expr seconds-or-milliseconds]
@@ -14,30 +14,35 @@
 
 (defn- date-trunc [unit expr]
   "date_trunc('interval', timezone, timestamp): truncates a timestamp to a given interval"
-  (if (or (nil? (driver/report-timezone)) (= (count (driver/report-timezone)) 0))
-    (k/sqlfn :DATE_TRUNC (kx/literal unit) expr)
-    (k/sqlfn :DATE_TRUNC (kx/literal unit) (driver/report-timezone) expr)))
+  (let [timezone    (get-in qp/*query* [:settings :report-timezone])]
+    (if (= (nil? timezone) true)
+      (k/sqlfn :DATE_TRUNC (kx/literal unit) expr)
+      (k/sqlfn :DATE_TRUNC (kx/literal unit) timezone expr))))
 
 (defn- date-format [format expr]
   "date_format('format_string', timezone, timestamp): formats the timestamp as string"
-  (if (or (nil? (driver/report-timezone)) (= (count (driver/report-timezone)) 0))
-    (k/sqlfn :DATE_FORMAT format expr)
-    (k/sqlfn :DATE_FORMAT format (driver/report-timezone) expr)))
+  (let [timezone    (get-in qp/*query* [:settings :report-timezone])]
+    (if (nil? timezone)
+      (k/sqlfn :DATE_FORMAT format expr)
+      (k/sqlfn :DATE_FORMAT format timezone expr))))
 
 (defn- extract    [unit expr]
   "extract(field from expr): extracts subfields of a timestamp"
-  (kutils/func (format "EXTRACT(%s FROM %%s)" (name unit)) [expr]))
+  (case unit
+    ;; Crate DOW starts with Monday (1) to Sunday (7)
+    :day_of_week (kx/+ (kx/mod (kutils/func (format "EXTRACT(%s FROM %%s)" (name unit)) [expr]) 7) 1)
+    (kutils/func (format "EXTRACT(%s FROM %%s)" (name unit)) [expr])))
 
 (def ^:private extract-integer
   (comp kx/->integer extract))
 
-(def ^:private YEAR   (constantly 31536000000))
-(def ^:private MONTH  (constantly 2628000000))
-(def ^:private WEEK   (constantly 604800000))
-(def ^:private DAY    (constantly 86400000))
-(def ^:private HOUR   (constantly 3600000))
-(def ^:private MINUTE (constantly 60000))
-(def ^:private SECOND (constantly 1000))
+(def ^:private ^:const second 1000)
+(def ^:private ^:const minute (* 60 second))
+(def ^:private ^:const hour   (* 60 minute))
+(def ^:private ^:const day    (* 24 hour))
+(def ^:private ^:const week   (* 7 day))
+(def ^:private ^:const year   (* 365 day))
+(def ^:private ^:const month  (Math/round (float (/ year 12))))
 
 (defn date [_ unit expr]
   (let [v (if (instance? Timestamp expr)
@@ -54,7 +59,8 @@
       :day-of-week     (extract-integer :day_of_week v)
       :day-of-month    (extract-integer :day_of_month v)
       :day-of-year     (extract-integer :day_of_year v)
-      :week            (date-format (str "%Y-%m-%d") (date-trunc :week v))
+      ;; Crate weeks start on Monday, so shift this date into the proper bucket and then decrement the resulting day
+      :week            (date-format (str "%Y-%m-%d") (kx/- (date-trunc :week (kx/+ v day)) day))
       :week-of-year    (extract-integer :week v)
       :month           (date-format (str "%Y-%m-%d") (date-trunc :month v))
       :month-of-year   (extract-integer :month v)
@@ -63,17 +69,16 @@
       :year            (extract-integer :year v))))
 
 (defn- sql-interval [unit amount]
-  (format "CURRENT_TIMESTAMP + %d" (* (unit) amount)))
+  (format "CURRENT_TIMESTAMP + %d" (* unit amount)))
 
 (defn date-interval [_ unit amount]
   "defines the sql command required for date-interval calculation"
   (case unit
     :quarter (recur nil :month (kx/* amount 3))
-    :year (k/raw (sql-interval YEAR amount))
-    :month (k/raw (sql-interval MONTH amount))
-    :week (k/raw (sql-interval WEEK amount))
-    :day (k/raw (sql-interval DAY amount))
-    :hour (k/raw (sql-interval HOUR amount))
-    :minute (k/raw (sql-interval MINUTE amount))
-    :second (k/raw (sql-interval SECOND amount))
-    ))
+    :year (k/raw (sql-interval year amount))
+    :month (k/raw (sql-interval month amount))
+    :week (k/raw (sql-interval week amount))
+    :day (k/raw (sql-interval day amount))
+    :hour (k/raw (sql-interval hour amount))
+    :minute (k/raw (sql-interval minute amount))
+    :second (k/raw (sql-interval second amount))))
diff --git a/src/metabase/driver/generic_sql.clj b/src/metabase/driver/generic_sql.clj
index 9148c11a9a29ff5352846e03d286198b9c46c313..dec9ea23feac358d70779c3d96f2618a0db783d8 100644
--- a/src/metabase/driver/generic_sql.clj
+++ b/src/metabase/driver/generic_sql.clj
@@ -88,7 +88,7 @@
 
 (extend-protocol jdbc/IResultSetReadColumn
   (class (object-array []))
-  (result-set-read-column [x _2 _3] (PersistentVector/adopt x)))
+  (result-set-read-column [x _ _] (PersistentVector/adopt x)))
 
 (def ^:dynamic ^:private connection-pools
   "A map of our currently open connection pools, keyed by DATABASE `:id`."
diff --git a/test/metabase/query_processor_test.clj b/test/metabase/query_processor_test.clj
index ba7619b5252729988dd8b2d17b113af592bbbeea..6a01a53094414771ec5b2cddfa4b7f0c620b9d3a 100644
--- a/test/metabase/query_processor_test.clj
+++ b/test/metabase/query_processor_test.clj
@@ -842,10 +842,10 @@
 (datasets/expect-with-engines (engines-that-support :standard-deviation-aggregations)
   {:columns [(format-name "price")
              "stddev"]
-   :rows    [[3 (if (or (= *engine* :mysql) (= *engine* :crate)) 25 26)]
+   :rows    [[3 (if (contains? #{:mysql :crate} *engine*) 25 26)]
              [1 24]
              [2 21]
-             [4 (if (or (= *engine* :mysql) (= *engine* :crate)) 14 15)]]
+             [4 (if (contains? #{:mysql :crate} *engine*) 14 15)]]
    :cols    [(venues-col :price)
              (aggregate-col :stddev (venues-col :category_id))]}
   (->> (run-query venues
diff --git a/test/metabase/test/data/crate.clj b/test/metabase/test/data/crate.clj
index ef6da3c4222e7b699b9ef705161bbb278e9cd473..661a9c7b07eb4d9138029e46dbd783ac19f9ec3e 100644
--- a/test/metabase/test/data/crate.clj
+++ b/test/metabase/test/data/crate.clj
@@ -1,13 +1,13 @@
 (ns metabase.test.data.crate
   "Code for creating / destroying a Crate database from a `DatabaseDefinition`."
-  (:require [environ.core :refer [env]]
-            metabase.driver.crate
-            (metabase.test.data [generic-sql :as generic]
-                                [interface :as i])
+  (:require [clojure.java.jdbc :as jdbc]
+            [clojure.string :as s]
             [metabase.driver.generic-sql :as sql]
-            [clojure.java.jdbc :as jdbc]
             [metabase.util :as u]
-            [clojure.string :as s])
+            (metabase.test.data [generic-sql :as generic]
+                                [interface :as i])
+            [clojure.tools.logging :as log]
+            [korma.core :as k])
   (:import metabase.driver.crate.CrateDriver))
 
 (def ^:private ^:const field-base-type->sql-type
@@ -25,9 +25,9 @@
 
 (defn- timestamp->CrateDateTime
   [value]
-  (if (= (instance? java.sql.Timestamp value) true)
+  (if (instance? java.sql.Timestamp value)
     (.getTime (u/->Timestamp value))
-    (if (= (and (= (instance? clojure.lang.PersistentArrayMap value) true) (contains? value :korma.sql.utils/generated)) true)
+    (if (and (instance? clojure.lang.PersistentArrayMap value) (contains? value :korma.sql.utils/generated))
       (+ (read-string (s/replace (:korma.sql.utils/generated value) #"CURRENT_TIMESTAMP \+" "")) (.getTime (u/new-sql-timestamp)))
       value)))
 
@@ -47,15 +47,15 @@
     (let [insert!   ((apply comp wrap-insert-fns) (fn [row-or-rows]
                                                     (apply jdbc/insert!
                                                            (generic/database->spec driver :db dbdef)
-                                                           (keyword (get tabledef :table-name))
+                                                           (keyword (:table-name tabledef))
                                                            :transaction? false
                                                            (escape-field-names row-or-rows))))
           rows      (apply list (generic/load-data-get-rows driver dbdef tabledef))]
       (insert! rows))))
 
-(defn- database->connection-details [_ _ {:keys [_ _]}]
-  (merge {:host         "localhost"
-          :port         4300}))
+(def ^:private database->connection-details
+  (constantly {:host "localhost"
+               :port 4300}))
 
 (extend CrateDriver
   generic/IGenericSQLDatasetLoader