Skip to content

Commit

Permalink
Add CurrentDate, CurrentTime and CurrentTimestamp Functions Part2 (#2524
Browse files Browse the repository at this point in the history
)

### What problem does this PR solve?

_Optimized code improves execution efficiency._

Issue link:(#2033)

### Type of change

- [x] Performance Improvement
  • Loading branch information
kche0169 authored Feb 17, 2025
1 parent 424f9e0 commit a102a36
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 91 deletions.
32 changes: 32 additions & 0 deletions src/executor/operator/physical_command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,38 @@ bool PhysicalCommand::Execute(QueryContext *query_context, OperatorState *operat
config->SetOptimizeInterval(interval);
break;
}
case GlobalOptionIndex::kTimeZone:{
if (set_command->value_type() != SetVarType::kString) {
Status status = Status::DataTypeMismatch("String", set_command->value_type_str());
RecoverableError(status);
}
String tz;
i32 tz_bias = 0;
Config::ParseTimeZoneStr(set_command->value_str(), tz, tz_bias);
if (tz_bias < -12 || tz_bias > 12) {
Status status = Status::InvalidCommand(fmt::format("Attempt to set time zone bias: {}", tz_bias));
RecoverableError(status);
}
if (tz == "UTC" || tz == "GMT") {
config->SetTimeZone(set_command->value_str());
config->SetTimeZoneBias(tz_bias);
return true;
}
break;
}
case GlobalOptionIndex::kTimeZoneBias: {
if (set_command->value_type() != SetVarType::kInteger) {
Status status = Status::DataTypeMismatch("Integer", set_command->value_type_str());
RecoverableError(status);
}
i64 bias = set_command->value_int();
if (bias < -12 || bias > 12) {
Status status = Status::InvalidCommand(fmt::format("Attempt to set time zone bias: {}", bias));
RecoverableError(status);
}
config->SetTimeZoneBias(bias);
break;
}
case GlobalOptionIndex::kInvalid: {
Status status = Status::InvalidCommand(fmt::format("Unknown config: {}", set_command->var_name()));
RecoverableError(status);
Expand Down
36 changes: 9 additions & 27 deletions src/function/scalar/current_date.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,41 @@ module;
#include <chrono>
module current_date;
import stl;
import config;
import catalog;
import status;
import logical_type;
import infinity_context;
import infinity_exception;
import scalar_function;
import scalar_function_set;
import third_party;
import internal_types;
import data_type;
import column_vector;
import singleton;

namespace infinity {
using namespace std::chrono;
struct CurrentDateFunction {
const char* defaultTZ = "Asia/Shanghai";
template <typename TA, typename TB>
static inline void Run(TA &left, TB &result) {
Status status = Status::NotSupport("Not implemented");
RecoverableError(status);
return;
}
static inline void TimeZoneConvertHelper(VarcharT &left) {
const char* tzValue = std::getenv("TZ");
const std::string str = left.ToString();
const char* newTZ = str.c_str();
if ( tzValue == newTZ) {
return;
}
if (setenv("TZ", newTZ, 1) != 0) {
const char* newTZ = CurrentDateFunction().defaultTZ;
setenv("TZ", newTZ, 1);
}
tzset();
return;
}
static inline void TimeZoneResetHelper() {
const char* tzValue = std::getenv("TZ");
if (tzValue == CurrentDateFunction().defaultTZ) {
return;
}
setenv("TZ", CurrentDateFunction().defaultTZ, 1);
tzset();
return;
}
};

template <>
inline void CurrentDateFunction::Run(VarcharT &left, DateT &result) {
TimeZoneConvertHelper(left);
String tz_str = left.ToString();
// Config::SetUserTimeZone(tz_str);
InfinityContext& infinityContext = InfinityContext::instance();
Config* config = infinityContext.config();
auto offset = config->TimeZoneBias();
auto now = system_clock::now();
auto sys_days = std::chrono::floor<std::chrono::days>(now);
result.value = sys_days.time_since_epoch().count();
TimeZoneResetHelper();
result.value = sys_days.time_since_epoch().count() + offset * (60 * 60);
}

void RegisterCurrentDateFunction(const UniquePtr<Catalog> &catalog_ptr) {
Expand Down
42 changes: 11 additions & 31 deletions src/function/scalar/current_time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ module;
#include <chrono>
module current_time;
import stl;
import config;
import catalog;
import status;
import logical_type;
import infinity_context;
import infinity_exception;
import scalar_function;
import scalar_function_set;
Expand All @@ -29,46 +31,24 @@ import column_vector;
namespace infinity {
using namespace std::chrono;
struct CurrentTimeFunction {
const char* defaultTZ = "Asia/Shanghai";
template <typename TA, typename TB>
static inline void Run(TA &left, TB &result) {
Status status = Status::NotSupport("Not implemented");
RecoverableError(status);
}
static inline void TimeZoneConvertHelper(VarcharT &left) {
const char* tzValue = std::getenv("TZ");
const std::string str = left.ToString();
const char* newTZ = str.c_str();
if ( tzValue == newTZ) {
return;
}
if (setenv("TZ", newTZ, 1) != 0) {
const char* newTZ = "Asia/Shanghai";
setenv("TZ", newTZ, 1);
}
tzset();
return;
}

static inline void TimeZoneResetHelper() {
const char* tzValue = std::getenv("TZ");
if (tzValue == CurrentTimeFunction().defaultTZ) {
return;
}
setenv("TZ", CurrentTimeFunction().defaultTZ, 1);
tzset();
return;
}
};

template <>
inline void CurrentTimeFunction::Run(VarcharT &left, TimeT &result) {
TimeZoneConvertHelper(left);
auto now = system_clock::now();
auto sys_days = std::chrono::floor<std::chrono::days>(now);
auto sys_secs = std::chrono::floor<std::chrono::seconds>(now);
result.value = static_cast<i32>(sys_secs.time_since_epoch().count() - sys_days.time_since_epoch().count());
TimeZoneResetHelper();
String tz_str = left.ToString();
InfinityContext& infinityContext = InfinityContext::instance();
Config* config = infinityContext.config();
auto offset = config->TimeZoneBias();
hours offset_hour(offset);
auto now = system_clock::now() + offset_hour;
auto sys_days = std::chrono::floor<std::chrono::days>(now);
auto sys_secs = std::chrono::floor<std::chrono::seconds>(now);
result.value = static_cast<i32>(sys_secs.time_since_epoch().count() - sys_days.time_since_epoch().count());
}

void RegisterCurrentTimeFunction(const UniquePtr<Catalog> &catalog_ptr) {
Expand Down
45 changes: 13 additions & 32 deletions src/function/scalar/current_timestamp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,61 +15,42 @@ module;
#include <chrono>
module current_timestamp;
import stl;
import config;
import catalog;
import status;
import logical_type;
import infinity_context;
import infinity_exception;
import scalar_function;
import scalar_function_set;
import third_party;
import internal_types;
import data_type;
import column_vector;
import query_context;

namespace infinity {
using namespace std::chrono;
struct CurrentTimestampFunction {
const char* defaultTZ = "Asia/Shanghai";
template <typename TA, typename TB>
static inline void Run(TA &left, TB &result) {
Status status = Status::NotSupport("Not implemented");
RecoverableError(status);
}
static inline void TimeZoneConvertHelper(VarcharT &left) {
const char* tzValue = std::getenv("TZ");
const std::string str = left.ToString();
const char* newTZ = str.c_str();
if ( tzValue == newTZ) {
return;
}
if (setenv("TZ", newTZ, 1) != 0) {
const char* newTZ = "Asia/Shanghai";
setenv("TZ", newTZ, 1);
}
tzset();
return;
}

static inline void TimeZoneResetHelper() {
const char* tzValue = std::getenv("TZ");
if (tzValue == CurrentTimestampFunction().defaultTZ) {
return;
}
setenv("TZ", CurrentTimestampFunction().defaultTZ, 1);
tzset();
return;
}
};

template <>
inline void CurrentTimestampFunction::Run(VarcharT &left, TimestampT &result) {
TimeZoneConvertHelper(left);
auto now = system_clock::now();
auto sys_days = std::chrono::floor<std::chrono::days>(now);
auto sys_secs = std::chrono::floor<std::chrono::seconds>(now);
result.time.value = static_cast<i32>(sys_secs.time_since_epoch().count() - sys_days.time_since_epoch().count());
result.date.value = static_cast<i32>(sys_days.time_since_epoch().count());
TimeZoneResetHelper();
String tz_str = left.ToString();
InfinityContext& infinityContext = InfinityContext::instance();
Config* config = infinityContext.config();
auto offset = config->TimeZoneBias();
hours offset_hour(offset);
auto now = system_clock::now() + offset_hour;
auto sys_days = std::chrono::floor<std::chrono::days>(now);
auto sys_secs = std::chrono::floor<std::chrono::seconds>(now);
result.time.value = static_cast<i32>(sys_secs.time_since_epoch().count() - sys_days.time_since_epoch().count());
result.date.value = static_cast<i32>(sys_days.time_since_epoch().count());
}

void RegisterCurrentTimestampFunction(const UniquePtr<Catalog> &catalog_ptr) {
Expand Down
34 changes: 34 additions & 0 deletions src/main/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

module;


#include <string>
#include <unistd.h>

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


Status Config::ParseByteSize(const String &byte_size_str, i64 &byte_size) {

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

// Date and Time

void Config::SetTimeZone(const String &value) {
std::lock_guard<std::mutex> guard(mutex_);
BaseOption *base_option = global_options_.GetOptionByIndex(GlobalOptionIndex::kTimeZone);
if (base_option->data_type_ != BaseOptionDataType::kString) {
String error_message = "Attempt to set a non-string value to the time zone";
UnrecoverableError(error_message);
}
StringOption *time_zone_option = static_cast<StringOption *>(base_option);
time_zone_option->value_ = value;
return;
}


void Config::SetTimeZoneBias(i64 bias) {
std::lock_guard<std::mutex> guard(mutex_);
BaseOption *base_option = global_options_.GetOptionByIndex(GlobalOptionIndex::kTimeZoneBias);
if (base_option->data_type_ != BaseOptionDataType::kInteger) {
String error_message = "Attempt to set non-integer value to the time zone bias";
UnrecoverableError(error_message);
}
IntegerOption *time_zone_bias_option = static_cast<IntegerOption *>(base_option);
time_zone_bias_option->value_ = bias;
return;
}


//// Profiler
// bool enable_profiler() const { return system_option_.enable_profiler; }
//
// SizeT profile_record_capacity() const { return system_option_.profile_record_capacity; }

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

// void Config::SetUserTimeZone(const String &value) {
// ParseTimeZoneStr(value);
// }

void Config::PrintAll() {
fmt::print("Infinity system configs: \n");

Expand Down
16 changes: 15 additions & 1 deletion src/main/config.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -148,21 +148,35 @@ public:
// Resource
String ResourcePath();

// Date and Time

void SetTimeZone(const String &value);

void SetTimeZoneBias(i64);
public:
// Get config by name
Tuple<BaseOption *, Status> GetConfigByName(const String &name);

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

private:
void SetOption(const String &var_name, const String &value);

static void SetTimeZoneOuter(const String &value);

static void ParseTimeZoneStr(const String &time_zone_str, String &parsed_time_zone, i32 &parsed_time_zone_bias);

private:


// static void ParseTimeZoneStr(const String &time_zone_str);

static Status ParseByteSize(const String &byte_size_str, i64 &byte_size);

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

static u64 GetAvailableMem();


private:
std::mutex mutex_;
GlobalOptions global_options_;
Expand Down

0 comments on commit a102a36

Please sign in to comment.