|
213 | 213 | teradata-spec |
214 | 214 | (sql-jdbc.common/handle-additional-options details-map, :seperator-style :comma))) |
215 | 215 |
|
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)]) |
218 | 218 |
|
219 | | -(def ^:private ^:const one-day (:raw "INTERVAL '1' DAY")) |
| 219 | +(def ^:private ^:const one-day [:raw "INTERVAL '1' DAY"]) |
220 | 220 |
|
221 | | -(def ^:private ^:const now (:raw "CURRENT_TIMESTAMP")) |
| 221 | +(def ^:private ^:const now [:raw "CURRENT_TIMESTAMP"]) |
222 | 222 |
|
223 | 223 | (defmethod sql.qp/date [:teradata :default] [_ _ expr] expr) |
224 | 224 | (defmethod sql.qp/date [:teradata :minute] [_ _ expr] (:to_timestamp (:raw "'yyyy-mm-dd hh24:mi'") expr)) |
|
229 | 229 | (defmethod sql.qp/date [:teradata :day-of-week] [driver _ expr] (h2x/inc (h2x/- (sql.qp/date driver :day expr) |
230 | 230 | (sql.qp/date driver :week expr)))) |
231 | 231 | (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)) |
240 | 240 | (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)) |
242 | 242 |
|
243 | 243 | (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))]) |
245 | 245 |
|
246 | 246 | (defmethod sql.qp/add-interval-honeysql-form :teradata [_ hsql-form amount unit] |
247 | 247 | (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"}) |
261 | 263 |
|
262 | 264 | (defmethod sql.qp/unix-timestamp->honeysql [:teradata :seconds] [_ _ field-or-value] |
263 | 265 | (:to_timestamp field-or-value)) |
|
384 | 386 | (get-method driver/execute-reducible-query :sql-jdbc) driver (cleanup-query query) context respond) |
385 | 387 | ) |
386 | 388 |
|
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 | | - |
416 | 389 | (defmethod sql.qp/current-datetime-honeysql-form :teradata [_] now) |
417 | 390 |
|
418 | 391 | ; TODO check if overriding apply-top-level-clause could make nested queries work |
|
0 commit comments