Skip to content

Commit 29f8ccc

Browse files
committed
Fix intervales
1 parent 02460e5 commit 29f8ccc

File tree

1 file changed

+29
-56
lines changed

1 file changed

+29
-56
lines changed

src/metabase/driver/teradata.clj

Lines changed: 29 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,12 @@
213213
teradata-spec
214214
(sql-jdbc.common/handle-additional-options details-map, :seperator-style :comma)))
215215

216-
;; trunc always returns a date in Teradata
217-
(defn- date-trunc [unit expr] (-> [:trunc expr (h2x/literal unit)]))
216+
(defn- trunc [format-template v]
217+
[:trunc v (h2x/literal format-template)])
218218

219-
(def ^:private ^:const one-day (:raw "INTERVAL '1' DAY"))
219+
(def ^:private ^:const one-day [:raw "INTERVAL '1' DAY"])
220220

221-
(def ^:private ^:const now (:raw "CURRENT_TIMESTAMP"))
221+
(def ^:private ^:const now [:raw "CURRENT_TIMESTAMP"])
222222

223223
(defmethod sql.qp/date [:teradata :default] [_ _ expr] expr)
224224
(defmethod sql.qp/date [:teradata :minute] [_ _ expr] (:to_timestamp (:raw "'yyyy-mm-dd hh24:mi'") expr))
@@ -229,35 +229,37 @@
229229
(defmethod sql.qp/date [:teradata :day-of-week] [driver _ expr] (h2x/inc (h2x/- (sql.qp/date driver :day expr)
230230
(sql.qp/date driver :week expr))))
231231
(defmethod sql.qp/date [:teradata :day-of-month] [_ _ expr] [::h2x/extract :day expr])
232-
(defmethod sql.qp/date [:teradata :day-of-year] [driver _ expr] (h2x/inc (h2x/- (sql.qp/date driver :day expr) (date-trunc :year expr))))
233-
(defmethod sql.qp/date [:teradata :week] [_ _ expr] (h2x/->date (date-trunc :day expr))) ; Same behaviour as with Oracle.
234-
(defmethod sql.qp/date [:teradata :week-of-year] [_ _ expr] (h2x/inc (h2x// (h2x/- (date-trunc :iw expr)
235-
(date-trunc :iy expr))
236-
7)))
237-
(defmethod sql.qp/date [:teradata :month] [_ _ expr] (date-trunc :mm expr))
238-
(defmethod sql.qp/date [:teradata :month-of-year] [_ _ expr] [::h2x/extract :month expr])
239-
(defmethod sql.qp/date [:teradata :quarter] [_ _ expr] (date-trunc :q expr))
232+
(defmethod sql.qp/date [:teradata :day-of-year] [driver _ expr] (h2x/inc (h2x/- (sql.qp/date driver :day expr) (trunc :year expr))))
233+
(defmethod sql.qp/date [:teradata :week] [_ _ expr] (trunc :day expr)) ; Same behaviour as with Oracle.
234+
(defmethod sql.qp/date [:teradata :week-of-year] [_ _ expr] (h2x/inc (h2x// (h2x/- (trunc :iw expr)
235+
(trunc :iy expr))
236+
7)))
237+
(defmethod sql.qp/date [:teradata :month] [_ _ expr] (trunc :month expr))
238+
(defmethod sql.qp/date [:teradata :month-of-year] [_ _ expr] [::h2x/extract :month expr])
239+
(defmethod sql.qp/date [:teradata :quarter] [_ _ expr] (trunc :q expr))
240240
(defmethod sql.qp/date [:teradata :quarter-of-year] [driver _ expr] (h2x// (h2x/+ (sql.qp/date driver :month-of-year (sql.qp/date driver :quarter expr)) 2) 3))
241-
(defmethod sql.qp/date [:teradata :year] [_ _ expr] (date-trunc :year expr))
241+
(defmethod sql.qp/date [:teradata :year] [_ _ expr] (trunc :year expr))
242242

243243
(defn- num-to-interval [unit amount]
244-
(:raw (format "INTERVAL '%d' %s" (int (Math/abs amount)) (name unit))))
244+
[:raw (format "INTERVAL '%d' %s" (int (Math/abs amount)) (name unit))])
245245

246246
(defmethod sql.qp/add-interval-honeysql-form :teradata [_ hsql-form amount unit]
247247
(let [op (if (>= amount 0) h2x/+ h2x/-)]
248-
(op (if
249-
(= unit :month)
250-
(date-trunc :month hsql-form)
251-
(hsql-form))
252-
(case unit
253-
:second (num-to-interval :second amount)
254-
:minute (num-to-interval :minute amount)
255-
:hour (num-to-interval :hour amount)
256-
:day (num-to-interval :day amount)
257-
:week (num-to-interval :day (* amount 7))
258-
:month (num-to-interval :month amount)
259-
:quarter (num-to-interval :month (* amount 3))
260-
:year (num-to-interval :year amount)))))
248+
(op (if (= unit :month)
249+
(trunc :month hsql-form)
250+
(h2x/->timestamp hsql-form))
251+
(case unit
252+
:second (num-to-interval :second amount)
253+
:minute (num-to-interval :minute amount)
254+
:hour (num-to-interval :hour amount)
255+
:day (num-to-interval :day amount)
256+
:week (num-to-interval :day (* amount 7))
257+
:month (num-to-interval :month amount)
258+
:quarter (num-to-interval :month (* amount 3))
259+
:year (num-to-interval :year amount)))))
260+
261+
(def ^:private timestamp-types
262+
#{"timestamp" "timestamp with time zone" "timestamp with local time zone"})
261263

262264
(defmethod sql.qp/unix-timestamp->honeysql [:teradata :seconds] [_ _ field-or-value]
263265
(:to_timestamp field-or-value))
@@ -384,35 +386,6 @@
384386
(get-method driver/execute-reducible-query :sql-jdbc) driver (cleanup-query query) context respond)
385387
)
386388

387-
(defn- num-to-ds-interval [unit v]
388-
(let [v (if (number? v)
389-
[:inline v]
390-
v)]
391-
[:numtodsinterval v (h2x/literal unit)]))
392-
393-
(defn- num-to-ym-interval [unit v]
394-
(let [v (if (number? v)
395-
[:inline v]
396-
v)]
397-
[:numtoyminterval v (h2x/literal unit)]))
398-
399-
(def ^:private timestamp-types
400-
#{"timestamp" "timestamp with time zone" "timestamp with local time zone"})
401-
402-
(defn- cast-to-timestamp-if-needed
403-
"If `hsql-form` isn't already one of the [[timestamp-types]], cast it to `timestamp`."
404-
[hsql-form]
405-
(h2x/cast-unless-type-in "timestamp" timestamp-types hsql-form))
406-
407-
(defn- cast-to-date-if-needed
408-
"If `hsql-form` isn't already one of the [[timestamp-types]] *or* `date`, cast it to `date`."
409-
[hsql-form]
410-
(h2x/cast-unless-type-in "date" (conj timestamp-types "date") hsql-form))
411-
412-
(defn- add-months [hsql-form amount]
413-
(-> [:add_months (cast-to-date-if-needed hsql-form) amount]
414-
(h2x/with-database-type-info "date")))
415-
416389
(defmethod sql.qp/current-datetime-honeysql-form :teradata [_] now)
417390

418391
; TODO check if overriding apply-top-level-clause could make nested queries work

0 commit comments

Comments
 (0)