Skip to content

Commit a102a36

Browse files
authored
Add CurrentDate, CurrentTime and CurrentTimestamp Functions Part2 (#2524)
### What problem does this PR solve? _Optimized code improves execution efficiency._ Issue link:(#2033) ### Type of change - [x] Performance Improvement
1 parent 424f9e0 commit a102a36

File tree

6 files changed

+114
-91
lines changed

6 files changed

+114
-91
lines changed

src/executor/operator/physical_command.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,38 @@ bool PhysicalCommand::Execute(QueryContext *query_context, OperatorState *operat
329329
config->SetOptimizeInterval(interval);
330330
break;
331331
}
332+
case GlobalOptionIndex::kTimeZone:{
333+
if (set_command->value_type() != SetVarType::kString) {
334+
Status status = Status::DataTypeMismatch("String", set_command->value_type_str());
335+
RecoverableError(status);
336+
}
337+
String tz;
338+
i32 tz_bias = 0;
339+
Config::ParseTimeZoneStr(set_command->value_str(), tz, tz_bias);
340+
if (tz_bias < -12 || tz_bias > 12) {
341+
Status status = Status::InvalidCommand(fmt::format("Attempt to set time zone bias: {}", tz_bias));
342+
RecoverableError(status);
343+
}
344+
if (tz == "UTC" || tz == "GMT") {
345+
config->SetTimeZone(set_command->value_str());
346+
config->SetTimeZoneBias(tz_bias);
347+
return true;
348+
}
349+
break;
350+
}
351+
case GlobalOptionIndex::kTimeZoneBias: {
352+
if (set_command->value_type() != SetVarType::kInteger) {
353+
Status status = Status::DataTypeMismatch("Integer", set_command->value_type_str());
354+
RecoverableError(status);
355+
}
356+
i64 bias = set_command->value_int();
357+
if (bias < -12 || bias > 12) {
358+
Status status = Status::InvalidCommand(fmt::format("Attempt to set time zone bias: {}", bias));
359+
RecoverableError(status);
360+
}
361+
config->SetTimeZoneBias(bias);
362+
break;
363+
}
332364
case GlobalOptionIndex::kInvalid: {
333365
Status status = Status::InvalidCommand(fmt::format("Unknown config: {}", set_command->var_name()));
334366
RecoverableError(status);

src/function/scalar/current_date.cpp

+9-27
Original file line numberDiff line numberDiff line change
@@ -15,59 +15,41 @@ module;
1515
#include <chrono>
1616
module current_date;
1717
import stl;
18+
import config;
1819
import catalog;
1920
import status;
2021
import logical_type;
22+
import infinity_context;
2123
import infinity_exception;
2224
import scalar_function;
2325
import scalar_function_set;
2426
import third_party;
2527
import internal_types;
2628
import data_type;
2729
import column_vector;
30+
import singleton;
2831

2932
namespace infinity {
3033
using namespace std::chrono;
3134
struct CurrentDateFunction {
32-
const char* defaultTZ = "Asia/Shanghai";
3335
template <typename TA, typename TB>
3436
static inline void Run(TA &left, TB &result) {
3537
Status status = Status::NotSupport("Not implemented");
3638
RecoverableError(status);
3739
return;
3840
}
39-
static inline void TimeZoneConvertHelper(VarcharT &left) {
40-
const char* tzValue = std::getenv("TZ");
41-
const std::string str = left.ToString();
42-
const char* newTZ = str.c_str();
43-
if ( tzValue == newTZ) {
44-
return;
45-
}
46-
if (setenv("TZ", newTZ, 1) != 0) {
47-
const char* newTZ = CurrentDateFunction().defaultTZ;
48-
setenv("TZ", newTZ, 1);
49-
}
50-
tzset();
51-
return;
52-
}
53-
static inline void TimeZoneResetHelper() {
54-
const char* tzValue = std::getenv("TZ");
55-
if (tzValue == CurrentDateFunction().defaultTZ) {
56-
return;
57-
}
58-
setenv("TZ", CurrentDateFunction().defaultTZ, 1);
59-
tzset();
60-
return;
61-
}
6241
};
6342

6443
template <>
6544
inline void CurrentDateFunction::Run(VarcharT &left, DateT &result) {
66-
TimeZoneConvertHelper(left);
45+
String tz_str = left.ToString();
46+
// Config::SetUserTimeZone(tz_str);
47+
InfinityContext& infinityContext = InfinityContext::instance();
48+
Config* config = infinityContext.config();
49+
auto offset = config->TimeZoneBias();
6750
auto now = system_clock::now();
6851
auto sys_days = std::chrono::floor<std::chrono::days>(now);
69-
result.value = sys_days.time_since_epoch().count();
70-
TimeZoneResetHelper();
52+
result.value = sys_days.time_since_epoch().count() + offset * (60 * 60);
7153
}
7254

7355
void RegisterCurrentDateFunction(const UniquePtr<Catalog> &catalog_ptr) {

src/function/scalar/current_time.cpp

+11-31
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ module;
1515
#include <chrono>
1616
module current_time;
1717
import stl;
18+
import config;
1819
import catalog;
1920
import status;
2021
import logical_type;
22+
import infinity_context;
2123
import infinity_exception;
2224
import scalar_function;
2325
import scalar_function_set;
@@ -29,46 +31,24 @@ import column_vector;
2931
namespace infinity {
3032
using namespace std::chrono;
3133
struct CurrentTimeFunction {
32-
const char* defaultTZ = "Asia/Shanghai";
3334
template <typename TA, typename TB>
3435
static inline void Run(TA &left, TB &result) {
3536
Status status = Status::NotSupport("Not implemented");
3637
RecoverableError(status);
3738
}
38-
static inline void TimeZoneConvertHelper(VarcharT &left) {
39-
const char* tzValue = std::getenv("TZ");
40-
const std::string str = left.ToString();
41-
const char* newTZ = str.c_str();
42-
if ( tzValue == newTZ) {
43-
return;
44-
}
45-
if (setenv("TZ", newTZ, 1) != 0) {
46-
const char* newTZ = "Asia/Shanghai";
47-
setenv("TZ", newTZ, 1);
48-
}
49-
tzset();
50-
return;
51-
}
52-
53-
static inline void TimeZoneResetHelper() {
54-
const char* tzValue = std::getenv("TZ");
55-
if (tzValue == CurrentTimeFunction().defaultTZ) {
56-
return;
57-
}
58-
setenv("TZ", CurrentTimeFunction().defaultTZ, 1);
59-
tzset();
60-
return;
61-
}
6239
};
6340

6441
template <>
6542
inline void CurrentTimeFunction::Run(VarcharT &left, TimeT &result) {
66-
TimeZoneConvertHelper(left);
67-
auto now = system_clock::now();
68-
auto sys_days = std::chrono::floor<std::chrono::days>(now);
69-
auto sys_secs = std::chrono::floor<std::chrono::seconds>(now);
70-
result.value = static_cast<i32>(sys_secs.time_since_epoch().count() - sys_days.time_since_epoch().count());
71-
TimeZoneResetHelper();
43+
String tz_str = left.ToString();
44+
InfinityContext& infinityContext = InfinityContext::instance();
45+
Config* config = infinityContext.config();
46+
auto offset = config->TimeZoneBias();
47+
hours offset_hour(offset);
48+
auto now = system_clock::now() + offset_hour;
49+
auto sys_days = std::chrono::floor<std::chrono::days>(now);
50+
auto sys_secs = std::chrono::floor<std::chrono::seconds>(now);
51+
result.value = static_cast<i32>(sys_secs.time_since_epoch().count() - sys_days.time_since_epoch().count());
7252
}
7353

7454
void RegisterCurrentTimeFunction(const UniquePtr<Catalog> &catalog_ptr) {

src/function/scalar/current_timestamp.cpp

+13-32
Original file line numberDiff line numberDiff line change
@@ -15,61 +15,42 @@ module;
1515
#include <chrono>
1616
module current_timestamp;
1717
import stl;
18+
import config;
1819
import catalog;
1920
import status;
2021
import logical_type;
22+
import infinity_context;
2123
import infinity_exception;
2224
import scalar_function;
2325
import scalar_function_set;
2426
import third_party;
2527
import internal_types;
2628
import data_type;
2729
import column_vector;
30+
import query_context;
2831

2932
namespace infinity {
3033
using namespace std::chrono;
3134
struct CurrentTimestampFunction {
32-
const char* defaultTZ = "Asia/Shanghai";
3335
template <typename TA, typename TB>
3436
static inline void Run(TA &left, TB &result) {
3537
Status status = Status::NotSupport("Not implemented");
3638
RecoverableError(status);
3739
}
38-
static inline void TimeZoneConvertHelper(VarcharT &left) {
39-
const char* tzValue = std::getenv("TZ");
40-
const std::string str = left.ToString();
41-
const char* newTZ = str.c_str();
42-
if ( tzValue == newTZ) {
43-
return;
44-
}
45-
if (setenv("TZ", newTZ, 1) != 0) {
46-
const char* newTZ = "Asia/Shanghai";
47-
setenv("TZ", newTZ, 1);
48-
}
49-
tzset();
50-
return;
51-
}
52-
53-
static inline void TimeZoneResetHelper() {
54-
const char* tzValue = std::getenv("TZ");
55-
if (tzValue == CurrentTimestampFunction().defaultTZ) {
56-
return;
57-
}
58-
setenv("TZ", CurrentTimestampFunction().defaultTZ, 1);
59-
tzset();
60-
return;
61-
}
6240
};
6341

6442
template <>
6543
inline void CurrentTimestampFunction::Run(VarcharT &left, TimestampT &result) {
66-
TimeZoneConvertHelper(left);
67-
auto now = system_clock::now();
68-
auto sys_days = std::chrono::floor<std::chrono::days>(now);
69-
auto sys_secs = std::chrono::floor<std::chrono::seconds>(now);
70-
result.time.value = static_cast<i32>(sys_secs.time_since_epoch().count() - sys_days.time_since_epoch().count());
71-
result.date.value = static_cast<i32>(sys_days.time_since_epoch().count());
72-
TimeZoneResetHelper();
44+
String tz_str = left.ToString();
45+
InfinityContext& infinityContext = InfinityContext::instance();
46+
Config* config = infinityContext.config();
47+
auto offset = config->TimeZoneBias();
48+
hours offset_hour(offset);
49+
auto now = system_clock::now() + offset_hour;
50+
auto sys_days = std::chrono::floor<std::chrono::days>(now);
51+
auto sys_secs = std::chrono::floor<std::chrono::seconds>(now);
52+
result.time.value = static_cast<i32>(sys_secs.time_since_epoch().count() - sys_days.time_since_epoch().count());
53+
result.date.value = static_cast<i32>(sys_days.time_since_epoch().count());
7354
}
7455

7556
void RegisterCurrentTimestampFunction(const UniquePtr<Catalog> &catalog_ptr) {

src/main/config.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
module;
1616

17+
1718
#include <string>
1819
#include <unistd.h>
1920

@@ -59,6 +60,7 @@ void Config::ParseTimeZoneStr(const String &time_zone_str, String &parsed_time_z
5960
parsed_time_zone_bias = std::stoi(time_zone_str.substr(3, String::npos));
6061
}
6162

63+
6264
Status Config::ParseByteSize(const String &byte_size_str, i64 &byte_size) {
6365

6466
HashMap<String, u64> byte_unit = {{"kb", 1024ul}, {"mb", 1024ul * 1024ul}, {"gb", 1024ul * 1024ul * 1024ul}};
@@ -2881,13 +2883,45 @@ String Config::ResourcePath() {
28812883
return global_options_.GetStringValue(GlobalOptionIndex::kResourcePath);
28822884
}
28832885

2886+
// Date and Time
2887+
2888+
void Config::SetTimeZone(const String &value) {
2889+
std::lock_guard<std::mutex> guard(mutex_);
2890+
BaseOption *base_option = global_options_.GetOptionByIndex(GlobalOptionIndex::kTimeZone);
2891+
if (base_option->data_type_ != BaseOptionDataType::kString) {
2892+
String error_message = "Attempt to set a non-string value to the time zone";
2893+
UnrecoverableError(error_message);
2894+
}
2895+
StringOption *time_zone_option = static_cast<StringOption *>(base_option);
2896+
time_zone_option->value_ = value;
2897+
return;
2898+
}
2899+
2900+
2901+
void Config::SetTimeZoneBias(i64 bias) {
2902+
std::lock_guard<std::mutex> guard(mutex_);
2903+
BaseOption *base_option = global_options_.GetOptionByIndex(GlobalOptionIndex::kTimeZoneBias);
2904+
if (base_option->data_type_ != BaseOptionDataType::kInteger) {
2905+
String error_message = "Attempt to set non-integer value to the time zone bias";
2906+
UnrecoverableError(error_message);
2907+
}
2908+
IntegerOption *time_zone_bias_option = static_cast<IntegerOption *>(base_option);
2909+
time_zone_bias_option->value_ = bias;
2910+
return;
2911+
}
2912+
2913+
28842914
//// Profiler
28852915
// bool enable_profiler() const { return system_option_.enable_profiler; }
28862916
//
28872917
// SizeT profile_record_capacity() const { return system_option_.profile_record_capacity; }
28882918

28892919
Tuple<BaseOption *, Status> Config::GetConfigByName(const String &name) { return global_options_.GetOptionByName(name); }
28902920

2921+
// void Config::SetUserTimeZone(const String &value) {
2922+
// ParseTimeZoneStr(value);
2923+
// }
2924+
28912925
void Config::PrintAll() {
28922926
fmt::print("Infinity system configs: \n");
28932927

src/main/config.cppm

+15-1
Original file line numberDiff line numberDiff line change
@@ -148,21 +148,35 @@ public:
148148
// Resource
149149
String ResourcePath();
150150

151+
// Date and Time
152+
153+
void SetTimeZone(const String &value);
154+
155+
void SetTimeZoneBias(i64);
151156
public:
152157
// Get config by name
153158
Tuple<BaseOption *, Status> GetConfigByName(const String &name);
154159

155160
GlobalOptionIndex GetOptionIndex(const String &var_name) const { return global_options_.GetOptionIndex(var_name); }
156161

157-
private:
162+
void SetOption(const String &var_name, const String &value);
163+
164+
static void SetTimeZoneOuter(const String &value);
165+
158166
static void ParseTimeZoneStr(const String &time_zone_str, String &parsed_time_zone, i32 &parsed_time_zone_bias);
159167

168+
private:
169+
170+
171+
// static void ParseTimeZoneStr(const String &time_zone_str);
172+
160173
static Status ParseByteSize(const String &byte_size_str, i64 &byte_size);
161174

162175
static Status ParseTimeInfo(const String &time_info, i64 &time_seconds);
163176

164177
static u64 GetAvailableMem();
165178

179+
166180
private:
167181
std::mutex mutex_;
168182
GlobalOptions global_options_;

0 commit comments

Comments
 (0)