|
1 | 1 | (ns metabase.driver.databricks-sql |
2 | 2 | (:require [clojure.java.jdbc :as jdbc] |
3 | 3 | [clojure.string :as str] |
| 4 | + [honeysql.core :as hsql] |
| 5 | + [honeysql.format :as hformat] |
| 6 | + [metabase.util.honeysql-extensions :as hx] |
4 | 7 | [medley.core :as m] |
5 | 8 | [metabase.driver :as driver] |
6 | 9 | [metabase.driver.sql-jdbc.connection :as sql-jdbc.conn] |
|
169 | 172 | (defmethod driver/supports? [:databricks-sql :foreign-keys] [_ _] true)) |
170 | 173 |
|
171 | 174 | (defmethod sql.qp/quote-style :databricks-sql [_] :mysql) |
| 175 | + |
| 176 | +(defn- date-format [format-str expr] |
| 177 | + (hsql/call :date_format expr (hx/literal format-str))) |
| 178 | + |
| 179 | +(defn- str-to-date [format-str expr] |
| 180 | + (hx/->timestamp |
| 181 | + (hsql/call :from_unixtime |
| 182 | + (hsql/call :unix_timestamp |
| 183 | + expr (hx/literal format-str))))) |
| 184 | + |
| 185 | +(defn- trunc-with-format [format-str expr] |
| 186 | + (str-to-date format-str (date-format format-str expr))) |
| 187 | + |
| 188 | +(defmethod sql.qp/date [:databricks-sql :default] [_ _ expr] (hx/->timestamp expr)) |
| 189 | +(defmethod sql.qp/date [:databricks-sql :minute] [_ _ expr] (trunc-with-format "yyyy-MM-dd HH:mm" (hx/->timestamp expr))) |
| 190 | +(defmethod sql.qp/date [:databricks-sql :minute-of-hour] [_ _ expr] (hsql/call :minute (hx/->timestamp expr))) |
| 191 | +(defmethod sql.qp/date [:databricks-sql :hour] [_ _ expr] (trunc-with-format "yyyy-MM-dd HH" (hx/->timestamp expr))) |
| 192 | +(defmethod sql.qp/date [:databricks-sql :hour-of-day] [_ _ expr] (hsql/call :hour (hx/->timestamp expr))) |
| 193 | +(defmethod sql.qp/date [:databricks-sql :day] [_ _ expr] (trunc-with-format "yyyy-MM-dd" (hx/->timestamp expr))) |
| 194 | +(defmethod sql.qp/date [:databricks-sql :day-of-month] [_ _ expr] (hsql/call :dayofmonth (hx/->timestamp expr))) |
| 195 | +(defmethod sql.qp/date [:databricks-sql :day-of-year] [_ _ expr] (hx/->integer (date-format "D" (hx/->timestamp expr)))) |
| 196 | +(defmethod sql.qp/date [:databricks-sql :month] [_ _ expr] (hsql/call :trunc (hx/->timestamp expr) (hx/literal :MM))) |
| 197 | +(defmethod sql.qp/date [:databricks-sql :month-of-year] [_ _ expr] (hsql/call :month (hx/->timestamp expr))) |
| 198 | +(defmethod sql.qp/date [:databricks-sql :quarter-of-year] [_ _ expr] (hsql/call :quarter (hx/->timestamp expr))) |
| 199 | +(defmethod sql.qp/date [:databricks-sql :year] [_ _ expr] (hsql/call :trunc (hx/->timestamp expr) (hx/literal :year))) |
| 200 | + |
| 201 | +(defmethod driver/db-start-of-week :databricks-sql |
| 202 | + [_] |
| 203 | + :sunday) |
| 204 | + |
| 205 | +(defrecord DateExtract [unit expr] |
| 206 | + hformat/ToSql |
| 207 | + (to-sql [_this] |
| 208 | + (format "extract(%s FROM %s)" (name unit) (hformat/to-sql expr)))) |
| 209 | + |
| 210 | +(defmethod sql.qp/date [:databricks-sql :day-of-week] |
| 211 | + [driver _unit expr] |
| 212 | + (sql.qp/adjust-day-of-week driver (-> (->DateExtract :dow (hx/->timestamp expr)) |
| 213 | + (hx/with-database-type-info "integer")))) |
| 214 | + |
| 215 | +(defmethod sql.qp/date [:databricks-sql :week] |
| 216 | + [driver _ expr] |
| 217 | + (let [week-extract-fn (fn [expr] |
| 218 | + (-> (hsql/call :date_sub |
| 219 | + (hx/+ (hx/->timestamp expr) |
| 220 | + (hsql/raw "interval '7' day")) |
| 221 | + (->DateExtract :dow (hx/->timestamp expr))) |
| 222 | + (hx/with-database-type-info "timestamp")))] |
| 223 | + (sql.qp/adjust-start-of-week driver week-extract-fn expr))) |
| 224 | + |
| 225 | +(defmethod sql.qp/date [:databricks-sql :quarter] |
| 226 | + [_ _ expr] |
| 227 | + (hsql/call :add_months |
| 228 | + (hsql/call :trunc (hx/->timestamp expr) (hx/literal :year)) |
| 229 | + (hx/* (hx/- (hsql/call :quarter (hx/->timestamp expr)) |
| 230 | + 1) |
| 231 | + 3))) |
| 232 | + |
| 233 | +(defmethod sql.qp/->honeysql [:databricks-sql :replace] |
| 234 | + [driver [_ arg pattern replacement]] |
| 235 | + (hsql/call :regexp_replace |
| 236 | + (sql.qp/->honeysql driver arg) |
| 237 | + (sql.qp/->honeysql driver pattern) |
| 238 | + (sql.qp/->honeysql driver replacement))) |
| 239 | + |
| 240 | +(defmethod sql.qp/->honeysql [:databricks-sql :regex-match-first] |
| 241 | + [driver [_ arg pattern]] |
| 242 | + (hsql/call :regexp_extract (sql.qp/->honeysql driver arg) (sql.qp/->honeysql driver pattern) 0)) |
| 243 | + |
| 244 | +(defmethod sql.qp/->honeysql [:databricks-sql :median] |
| 245 | + [driver [_ arg]] |
| 246 | + (hsql/call :percentile (sql.qp/->honeysql driver arg) 0.5)) |
| 247 | + |
| 248 | +(defmethod sql.qp/->honeysql [:databricks-sql :percentile] |
| 249 | + [driver [_ arg p]] |
| 250 | + (hsql/call :percentile (sql.qp/->honeysql driver arg) (sql.qp/->honeysql driver p))) |
| 251 | + |
| 252 | +(defmethod sql.qp/add-interval-honeysql-form :databricks-sql |
| 253 | + [driver hsql-form amount unit] |
| 254 | + (if (= unit :quarter) |
| 255 | + (recur driver hsql-form (* amount 3) :month) |
| 256 | + (hx/+ (hx/->timestamp hsql-form) (hsql/raw (format "(INTERVAL '%d' %s)" (int amount) (name unit)))))) |
0 commit comments