LCOV - code coverage report
Current view: top level - monetdb5/modules/atoms - mtime.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 58 87 66.7 %
Date: 2024-11-14 20:04:02 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #ifndef __MTIME_H__
      14             : #define __MTIME_H__
      15             : 
      16             : #include "monetdb_config.h"
      17             : #include "gdk.h"
      18             : #include "gdk_time.h"
      19             : #include "mal_interpreter.h"
      20             : #include "mal_exception.h"
      21             : 
      22             : /* TODO change dayint again into an int instead of lng */
      23             : static inline lng
      24          83 : date_diff_imp(const date d1, const date d2)
      25             : {
      26          83 :         int diff = date_diff(d1, d2);
      27          83 :         return is_int_nil(diff) ? lng_nil : (lng) diff *(lng) (24 * 60 * 60 * 1000);
      28             : }
      29             : 
      30             : static inline daytime
      31          29 : time_sub_msec_interval(const daytime t, const lng ms)
      32             : {
      33          29 :         if (is_lng_nil(ms))
      34           0 :                 return daytime_nil;
      35          29 :         return daytime_add_usec_modulo(t, -ms * 1000);
      36             : }
      37             : 
      38             : static inline daytime
      39          25 : time_add_msec_interval(const daytime t, const lng ms)
      40             : {
      41          25 :         if (is_lng_nil(ms))
      42           0 :                 return daytime_nil;
      43          25 :         return daytime_add_usec_modulo(t, ms * 1000);
      44             : }
      45             : 
      46             : static inline str
      47          30 : date_sub_msec_interval(date *ret, date d, lng ms)
      48             : {
      49          30 :         if (is_date_nil(d) || is_lng_nil(ms)) {
      50           0 :                 *ret = date_nil;
      51           0 :                 return MAL_SUCCEED;
      52             :         }
      53          30 :         if (is_date_nil((*ret = date_add_day(d, (int) (-ms / (24 * 60 * 60 * 1000))))))
      54           0 :                 throw(MAL, "mtime.date_sub_msec_interval",
      55             :                           SQLSTATE(22003) "overflow in calculation");
      56             :         return MAL_SUCCEED;
      57             : }
      58             : 
      59             : static inline str
      60        2316 : date_add_msec_interval(date *ret, date d, lng ms)
      61             : {
      62        2316 :         if (is_date_nil(d) || is_lng_nil(ms)) {
      63           0 :                 *ret = date_nil;
      64           0 :                 return MAL_SUCCEED;
      65             :         }
      66        2316 :         if (is_date_nil((*ret = date_add_day(d, (int) (ms / (24 * 60 * 60 * 1000))))))
      67           0 :                 throw(MAL, "mtime.date_add_msec_interval",
      68             :                           SQLSTATE(22003) "overflow in calculation");
      69             :         return MAL_SUCCEED;
      70             : }
      71             : 
      72             : static inline str
      73         145 : timestamp_sub_msec_interval(timestamp *ret, timestamp ts, lng ms)
      74             : {
      75         145 :         if (is_timestamp_nil(ts) || is_lng_nil(ms)) {
      76           5 :                 *ret = timestamp_nil;
      77           5 :                 return MAL_SUCCEED;
      78             :         }
      79         140 :         if (is_timestamp_nil((*ret = timestamp_add_usec(ts, -ms * 1000))))
      80           0 :                 throw(MAL, "mtime.timestamp_sub_msec_interval",
      81             :                           SQLSTATE(22003) "overflow in calculation");
      82             :         return MAL_SUCCEED;
      83             : }
      84             : 
      85             : static inline str
      86           3 : timestamp_sub_month_interval(timestamp *ret, timestamp ts, int m)
      87             : {
      88           3 :         if (is_timestamp_nil(ts) || is_int_nil(m)) {
      89           0 :                 *ret = timestamp_nil;
      90           0 :                 return MAL_SUCCEED;
      91             :         }
      92           3 :         if (is_timestamp_nil((*ret = timestamp_add_month(ts, -m))))
      93           0 :                 throw(MAL, "mtime.timestamp_sub_month_interval",
      94             :                           SQLSTATE(22003) "overflow in calculation");
      95             :         return MAL_SUCCEED;
      96             : }
      97             : 
      98             : static inline str
      99           8 : timestamp_add_month_interval(timestamp *ret, timestamp ts, int m)
     100             : {
     101           8 :         if (is_timestamp_nil(ts) || is_int_nil(m)) {
     102           0 :                 *ret = timestamp_nil;
     103           0 :                 return MAL_SUCCEED;
     104             :         }
     105           8 :         if (is_timestamp_nil((*ret = timestamp_add_month(ts, m))))
     106           0 :                 throw(MAL, "mtime.timestamp_add_month_interval",
     107             :                           SQLSTATE(22003) "overflow in calculation");
     108             :         return MAL_SUCCEED;
     109             : }
     110             : 
     111             : static inline str
     112         472 : timestamp_add_msec_interval(timestamp *ret, timestamp ts, lng ms)
     113             : {
     114         472 :         if (is_timestamp_nil(ts) || is_lng_nil(ms)) {
     115          18 :                 *ret = timestamp_nil;
     116          18 :                 return MAL_SUCCEED;
     117             :         }
     118         454 :         if (is_timestamp_nil((*ret = timestamp_add_usec(ts, ms * 1000))))
     119           0 :                 throw(MAL, "mtime.timestamp_add_msec_interval",
     120             :                           SQLSTATE(22003) "overflow in calculation");
     121             :         return MAL_SUCCEED;
     122             : }
     123             : 
     124             : 
     125             : static inline str
     126           2 : odbc_timestamp_add_msec_interval_time(timestamp *ret, daytime t, lng ms)
     127             : {
     128           2 :         date today = timestamp_date(timestamp_current());
     129           2 :         timestamp ts = timestamp_create(today, t);
     130           2 :         if (is_timestamp_nil((*ret = timestamp_add_usec(ts, ms * 1000))))
     131           0 :                 throw(MAL, "mtime.odbc_timestamp_add_msec_interval_time",
     132             :                           SQLSTATE(22003) "overflow in calculation");
     133             :         return MAL_SUCCEED;
     134             : }
     135             : 
     136             : 
     137             : static inline str
     138           0 : odbc_timestamp_add_month_interval_time(timestamp *ret, daytime t, int m)
     139             : {
     140           0 :         date today = timestamp_date(timestamp_current());
     141           0 :         timestamp ts = timestamp_create(today, t);
     142           0 :         if (is_timestamp_nil((*ret = timestamp_add_month(ts, m))))
     143           0 :                 throw(MAL, "mtime.odbc_timestamp_add_month_interval_time",
     144             :                           SQLSTATE(22003) "overflow in calculation");
     145             :         return MAL_SUCCEED;
     146             : }
     147             : 
     148             : 
     149             : static inline str
     150           2 : odbc_timestamp_add_msec_interval_date(timestamp *ret, date d, lng ms)
     151             : {
     152           2 :         timestamp ts = timestamp_fromdate(d);
     153           2 :         if (is_timestamp_nil((*ret = timestamp_add_usec(ts, ms * 1000))))
     154           0 :                 throw(MAL, "mtime.odbc_timestamp_add_msec_interval_date",
     155             :                           SQLSTATE(22003) "overflow in calculation");
     156             :         return MAL_SUCCEED;
     157             : }
     158             : 
     159             : 
     160             : static inline str
     161           8 : date_submonths(date *ret, date d, int m)
     162             : {
     163           8 :         if (is_date_nil(d) || is_int_nil(m)) {
     164           0 :                 *ret = date_nil;
     165           0 :                 return MAL_SUCCEED;
     166             :         }
     167           8 :         if (is_date_nil((*ret = date_add_month(d, -m))))
     168           1 :                 throw(MAL, "mtime.date_submonths",
     169             :                           SQLSTATE(22003) "overflow in calculation");
     170             :         return MAL_SUCCEED;
     171             : }
     172             : 
     173             : static inline str
     174          35 : date_addmonths(date *ret, date d, int m)
     175             : {
     176          35 :         if (is_date_nil(d) || is_int_nil(m)) {
     177           0 :                 *ret = date_nil;
     178           0 :                 return MAL_SUCCEED;
     179             :         }
     180          35 :         if (is_date_nil((*ret = date_add_month(d, m))))
     181           0 :                 throw(MAL, "mtime.date_addmonths",
     182             :                           SQLSTATE(22003) "overflow in calculation");
     183             :         return MAL_SUCCEED;
     184             : }
     185             : 
     186             : #define date_to_msec_since_epoch(t) is_date_nil(t) ? lng_nil : (timestamp_diff(timestamp_create(t, daytime_create(0, 0, 0, 0)), unixepoch) / 1000)
     187             : #define daytime_to_msec_since_epoch(t) daytime_diff(t, daytime_create(0, 0, 0, 0))
     188             : 
     189             : static inline lng
     190         137 : TSDIFF(timestamp t1, timestamp t2)
     191             : {
     192         137 :         lng diff = timestamp_diff(t1, t2);
     193         137 :         if (!is_lng_nil(diff)) {
     194             : #ifndef TRUNCATE_NUMBERS
     195         133 :                 if (diff < 0)
     196          23 :                         diff = -((-diff + 500) / 1000);
     197             :                 else
     198         110 :                         diff = (diff + 500) / 1000;
     199             : #else
     200             :                 diff /= 1000;
     201             : #endif
     202             :         }
     203         137 :         return diff;
     204             : }
     205             : 
     206             : static inline int
     207          19 : timestamp_century(const timestamp t)
     208             : {
     209          19 :         if (is_timestamp_nil(t))
     210           2 :                 return int_nil;
     211          17 :         int y = date_year(timestamp_date(t));
     212          17 :         if (y > 0)
     213          17 :                 return (y - 1) / 100 + 1;
     214             :         else
     215           0 :                 return -((-y - 1) / 100 + 1);
     216             : }
     217             : 
     218             : #define timestamp_decade(t) is_timestamp_nil(t) ? int_nil : date_year(timestamp_date(t)) / 10
     219             : #define timestamp_year(t) date_year(timestamp_date(t))
     220             : #define timestamp_quarter(t) is_timestamp_nil(t) ? bte_nil : (date_month(timestamp_date(t)) - 1) / 3 + 1
     221             : #define timestamp_month(t) date_month(timestamp_date(t))
     222             : #define timestamp_day(t) date_day(timestamp_date(t))
     223             : #define timestamp_hours(t) daytime_hour(timestamp_daytime(t))
     224             : #define timestamp_minutes(t) daytime_min(timestamp_daytime(t))
     225             : #define timestamp_extract_usecond(ts)   daytime_sec_usec(timestamp_daytime(ts))
     226             : #define timestamp_to_msec_since_epoch(t) is_timestamp_nil(t) ? lng_nil : (timestamp_diff(t, unixepoch) / 1000)
     227             : 
     228             : #define sql_year(m) is_int_nil(m) ? int_nil : m / 12
     229             : #define sql_month(m) is_int_nil(m) ? int_nil : m % 12
     230             : #define sql_day(m) is_lng_nil(m) ? lng_nil : m / (24*60*60*1000)
     231             : #define sql_hours(m) is_lng_nil(m) ? int_nil : (int) ((m % (24*60*60*1000)) / (60*60*1000))
     232             : #define sql_minutes(m) is_lng_nil(m) ? int_nil : (int) ((m % (60*60*1000)) / (60*1000))
     233             : #define sql_seconds(m) is_lng_nil(m) ? int_nil : (int) ((m % (60*1000)) / 1000)
     234             : #define msec_since_epoch(ts)    ts
     235             : 
     236             : #endif /* __MTIME_H__ */

Generated by: LCOV version 1.14