OmniSciDB  eee9fa949c
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DateTimeUtils.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "DateAdd.h"
20 #include "DateTruncate.h"
21 
22 #include <cstdint>
23 #include <ctime>
24 #include <map>
25 #include <string>
26 
27 #include "../Shared/sqldefs.h"
28 
29 namespace {
30 
31 static const std::map<std::pair<int32_t, ExtractField>, std::pair<SQLOps, int64_t>>
38 
39 static const std::map<std::pair<int32_t, DatetruncField>, int64_t>
43 
44 } // namespace
45 
46 namespace DateTimeUtils {
47 
48 // Enum helpers for precision scaling up/down.
50 
51 constexpr inline int64_t get_timestamp_precision_scale(const int32_t dimen) {
52  switch (dimen) {
53  case 0:
54  return 1;
55  case 3:
56  return kMilliSecsPerSec;
57  case 6:
58  return kMicroSecsPerSec;
59  case 9:
60  return kNanoSecsPerSec;
61  default:
62  throw std::runtime_error("Unknown dimen = " + std::to_string(dimen));
63  }
64  return -1;
65 }
66 
67 constexpr inline int64_t get_dateadd_timestamp_precision_scale(const DateaddField field) {
68  switch (field) {
69  case daMILLISECOND:
70  return kMilliSecsPerSec;
71  case daMICROSECOND:
72  return kMicroSecsPerSec;
73  case daNANOSECOND:
74  return kNanoSecsPerSec;
75  default:
76  throw std::runtime_error("Unknown field = " + std::to_string(field));
77  }
78  return -1;
79 }
80 
81 constexpr inline int64_t get_extract_timestamp_precision_scale(const ExtractField field) {
82  switch (field) {
83  case kMILLISECOND:
84  return kMilliSecsPerSec;
85  case kMICROSECOND:
86  return kMicroSecsPerSec;
87  case kNANOSECOND:
88  return kNanoSecsPerSec;
89  default:
90  throw std::runtime_error("Unknown field = " + std::to_string(field));
91  }
92  return -1;
93 }
94 
95 constexpr inline bool is_subsecond_extract_field(const ExtractField& field) {
96  return field == kMILLISECOND || field == kMICROSECOND || field == kNANOSECOND;
97 }
98 
99 constexpr inline bool is_subsecond_dateadd_field(const DateaddField field) {
100  return field == daMILLISECOND || field == daMICROSECOND || field == daNANOSECOND;
101 }
102 
103 constexpr inline bool is_subsecond_datetrunc_field(const DatetruncField field) {
104  return field == dtMILLISECOND || field == dtMICROSECOND || field == dtNANOSECOND;
105 }
106 
107 const inline std::pair<SQLOps, int64_t> get_dateadd_high_precision_adjusted_scale(
108  const DateaddField field,
109  int32_t dimen) {
110  switch (field) {
111  case daNANOSECOND:
112  switch (dimen) {
113  case 9:
114  return {};
115  case 6:
116  return {kDIVIDE, kMilliSecsPerSec};
117  case 3:
118  return {kDIVIDE, kMicroSecsPerSec};
119  default:
120  throw std::runtime_error("Unknown dimen = " + std::to_string(dimen));
121  }
122  case daMICROSECOND:
123  switch (dimen) {
124  case 9:
125  return {kMULTIPLY, kMilliSecsPerSec};
126  case 6:
127  return {};
128  case 3:
129  return {kDIVIDE, kMilliSecsPerSec};
130  default:
131  throw std::runtime_error("Unknown dimen = " + std::to_string(dimen));
132  }
133  case daMILLISECOND:
134  switch (dimen) {
135  case 9:
136  return {kMULTIPLY, kMicroSecsPerSec};
137  case 6:
138  return {kMULTIPLY, kMilliSecsPerSec};
139  case 3:
140  return {};
141  default:
142  throw std::runtime_error("Unknown dimen = " + std::to_string(dimen));
143  }
144  default:
145  throw std::runtime_error("Unknown field = " + std::to_string(field));
146  }
147  return {};
148 }
149 
150 const inline std::pair<SQLOps, int64_t> get_extract_high_precision_adjusted_scale(
151  const ExtractField& field,
152  const int32_t dimen) {
153  const auto result = extract_precision_lookup.find(std::make_pair(dimen, field));
154  if (result != extract_precision_lookup.end()) {
155  return result->second;
156  }
157  return {};
158 }
159 
161  const int32_t dimen) {
162  const auto result = datetrunc_precision_lookup.find(std::make_pair(dimen, field));
163  if (result != datetrunc_precision_lookup.end()) {
164  return result->second;
165  }
166  return -1;
167 }
168 
169 constexpr inline int64_t get_datetime_scaled_epoch(const ScalingType direction,
170  const int64_t epoch,
171  const int32_t dimen) {
172  switch (direction) {
173  case ScaleUp: {
174  const auto scaled_epoch = epoch * get_timestamp_precision_scale(dimen);
175  if (epoch && epoch != scaled_epoch / get_timestamp_precision_scale(dimen)) {
176  throw std::runtime_error(
177  "Value Overflow/underflow detected while scaling DateTime precision.");
178  }
179  return scaled_epoch;
180  }
181  case ScaleDown:
182  return epoch / get_timestamp_precision_scale(dimen);
183  default:
184  abort();
185  }
186  return std::numeric_limits<int64_t>::min();
187 }
188 
189 } // namespace DateTimeUtils
constexpr int64_t get_extract_timestamp_precision_scale(const ExtractField field)
Definition: DateTimeUtils.h:81
static constexpr int64_t kNanoSecsPerSec
constexpr int64_t get_dateadd_timestamp_precision_scale(const DateaddField field)
Definition: DateTimeUtils.h:67
const std::pair< SQLOps, int64_t > get_extract_high_precision_adjusted_scale(const ExtractField &field, const int32_t dimen)
constexpr int64_t get_datetime_scaled_epoch(const ScalingType direction, const int64_t epoch, const int32_t dimen)
static const std::map< std::pair< int32_t, ExtractField >, std::pair< SQLOps, int64_t > > extract_precision_lookup
Definition: DateTimeUtils.h:32
std::string to_string(char const *&&v)
static const std::map< std::pair< int32_t, DatetruncField >, int64_t > datetrunc_precision_lookup
Definition: DateTimeUtils.h:40
static constexpr int64_t kMilliSecsPerSec
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
const std::pair< SQLOps, int64_t > get_dateadd_high_precision_adjusted_scale(const DateaddField field, int32_t dimen)
DateaddField
Definition: DateAdd.h:42
DatetruncField
Definition: DateTruncate.h:42
constexpr bool is_subsecond_datetrunc_field(const DatetruncField field)
ExtractField
constexpr bool is_subsecond_dateadd_field(const DateaddField field)
Definition: DateTimeUtils.h:99
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:51
constexpr bool is_subsecond_extract_field(const ExtractField &field)
Definition: DateTimeUtils.h:95
static constexpr int64_t kMicroSecsPerSec
const int64_t get_datetrunc_high_precision_scale(const DatetruncField &field, const int32_t dimen)