Skip to content
Snippets Groups Projects
Commit 4b2dbd6d authored by Cam Saül's avatar Cam Saül
Browse files

Add new date-string->literal ISQLDriver protocol method

parent d8383d7b
No related branches found
No related tags found
No related merge requests found
......@@ -106,7 +106,7 @@
:fields (set (table-schema->metabase-field-info (.getSchema (get-table database table-name))))})
(def ^:private ^:const query-timeout-seconds 60)
(def ^:private ^:const ^Integer query-timeout-seconds 60)
(defn- ^QueryResponse execute-bigquery
([{{:keys [project-id]} :details, :as database} query-string]
......@@ -236,6 +236,9 @@
:quarter-of-year (hx/quarter expr)
:year (hx/year expr)))
(defn- date-string->literal [^String date-string]
(hx/->timestamp (hx/literal (u/format-date "yyyy-MM-dd 00:00" (u/->Date date-string)))))
(defn- unix-timestamp->timestamp [expr seconds-or-milliseconds]
(case seconds-or-milliseconds
:seconds (hsql/call :sec_to_timestamp expr)
......@@ -381,6 +384,7 @@
:connection-details->spec (constantly nil) ; since we don't use JDBC
:current-datetime-fn (constantly :%current_timestamp)
:date (u/drop-first-arg date)
:date-string->literal (u/drop-first-arg date-string->literal)
:field->alias (u/drop-first-arg field->alias)
:prepare-value (u/drop-first-arg prepare-value)
:quote-style (constantly :sqlserver) ; we want identifiers quoted [like].[this]
......@@ -421,8 +425,10 @@
;; TODO - either write BigQuery-speciifc tests for FK functionality or add additional code to manually set up these FK relationships for FK tables
:features (constantly (set/union #{:basic-aggregations
:standard-deviation-aggregations
:expression-aggregations
:native-parameters}
:native-parameters
;; Expression aggregations *would* work, but BigQuery doesn't support the auto-generated column names. BQ column names
;; can only be alphanumeric or underscores. If we slugified the auto-generated column names, we could enable this feature.
#_:expression-aggregations}
(when-not config/is-test?
;; during unit tests don't treat bigquery as having FK support
#{:foreign-keys})))
......
......@@ -58,6 +58,11 @@
(date [this, ^Keyword unit, field-or-value]
"Return a HoneySQL form for truncating a date or timestamp field or value to a given resolution, or extracting a date component.")
(date-string->literal [this, ^String date-string]
"*OPTIONAL*. Return an appropriate HoneySQL form to represent a DATE-STRING literal.
The default implementation is just `hx/literal`; in other words, it just single-quotes DATE-STRING. Some drivers like BigQuery or Oracle need to do something more advanced.
(This is used for the implementation of SQL parameters).")
(excluded-schemas ^java.util.Set [this]
"*OPTIONAL*. Set of string names of schemas to skip syncing tables from.")
......@@ -203,6 +208,7 @@
([table field]
(hx/qualify-and-escape-dots (:schema table) (:name table) (:name field))))
(defn- query
"Execute a HONEYSQL-FROM query against DATABASE, DRIVER, and optionally TABLE."
([driver database honeysql-form]
......@@ -412,6 +418,7 @@
:apply-page (resolve 'metabase.driver.generic-sql.query-processor/apply-page)
:column->special-type (constantly nil)
:current-datetime-fn (constantly :%now)
:date-string->literal (u/drop-first-arg hx/literal)
:excluded-schemas (constantly nil)
:field->alias (u/drop-first-arg name)
:field-percent-urls fast-field-percent-urls
......
......@@ -86,6 +86,11 @@
3)
:year (hsql/call :extract :year v)))
(defn- date-string->literal [^String date-string]
(hsql/call :to_timestamp
(hx/literal (u/format-date "yyyy-MM-dd" (u/->Date date-string)))
(hx/literal "YYYY-MM-DD")))
(def ^:private ^:const now (hsql/raw "SYSDATE"))
(def ^:private ^:const date-1970-01-01 (hsql/call :to_timestamp (hx/literal :1970-01-01) (hx/literal :YYYY-MM-DD)))
......@@ -218,6 +223,7 @@
:connection-details->spec (u/drop-first-arg connection-details->spec)
:current-datetime-fn (constantly now)
:date (u/drop-first-arg date)
:date-string->literal (u/drop-first-arg date-string->literal)
:excluded-schemas (fn [& _]
(set/union
#{"ANONYMOUS"
......
......@@ -46,21 +46,10 @@
(first (hsql/format x
:quoting ((resolve 'metabase.driver.generic-sql/quote-style) *driver*))))
(defn- format-oracle-date [s]
(format "to_timestamp('%s', 'YYYY-MM-DD')" (u/format-date "yyyy-MM-dd" (u/->Date s))))
(defn- oracle-driver? ^Boolean []
;; we can't just import OracleDriver the normal way here because that would cause a cyclic load dependency
(boolean (when-let [oracle-driver-class (u/ignore-exceptions (Class/forName "metabase.driver.oracle.OracleDriver"))]
(instance? oracle-driver-class *driver*))))
(defn- format-date
;; This is a dirty dirty HACK! Unfortuantely Oracle is super-dumb when it comes to automatically converting strings to dates
;; so we need to add the cast here
[date]
(if (oracle-driver?)
(format-oracle-date date)
(str \' date \')))
(defn- format-date-string
"Format DATE-STRING as an appropriate literal using the driver's definition of `date-string->literal`."
^String [^String date-string]
(honeysql->sql ((resolve 'metabase.driver.generic-sql/date-string->literal) *driver* date-string)))
(extend-protocol ISQLParamSubstituion
nil (->sql [_] "NULL")
......@@ -80,13 +69,13 @@
Date
(->sql [{:keys [s]}]
(format-date s))
(format-date-string s))
DateRange
(->sql [{:keys [start end]}]
(if (= start end)
(format "= %s" (format-date start))
(format "BETWEEN %s AND %s" (format-date start) (format-date end))))
(format "= %s" (format-date-string start))
(format "BETWEEN %s AND %s" (format-date-string start) (format-date-string end))))
Dimension
(->sql [{:keys [field param], :as dimension}]
......@@ -175,10 +164,10 @@
(defn- parse-value-for-type [param-type value]
(cond
(= param-type "number") (->NumberValue value)
(= param-type "number") (->NumberValue value)
(and (= param-type "dimension")
(= (get-in value [:param :type]) "number")) (update-in value [:param :value] ->NumberValue)
:else value))
(= (get-in value [:param :type]) "number")) (update-in value [:param :value] ->NumberValue)
:else value))
(defn- value-for-tag
"Given a map TAG (a value in the `:template_tags` dictionary) return the corresponding value from the PARAMS sequence.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment