Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CurrentDate, CurrentTime and CurrentTimestamp Functions Part1 #2500

Merged
merged 7 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/function/builtin_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ import like;
import minus;
import modulo;
import multiply;
import current_date;
import current_time;
import current_timestamp;
import century;
import year;
import month;
Expand Down Expand Up @@ -166,6 +169,9 @@ void BuiltinFunctions::RegisterScalarFunction() {
RegisterPositionFunction(catalog_ptr_);

// date and time functions
RegisterCurrentDateFunction(catalog_ptr_);
RegisterCurrentTimeFunction(catalog_ptr_);
RegisterCurrentTimestampFunction(catalog_ptr_);
RegisterCenturyFunction(catalog_ptr_);
RegisterYearFunction(catalog_ptr_);
RegisterMonthFunction(catalog_ptr_);
Expand Down
87 changes: 87 additions & 0 deletions src/function/scalar/current_date.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright(C) 2025 InfiniFlow, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
module;
#include <chrono>
module current_date;
import stl;
import catalog;
import status;
import logical_type;
import infinity_exception;
import scalar_function;
import scalar_function_set;
import third_party;
import internal_types;
import data_type;
import column_vector;

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);
auto now = system_clock::now();
auto sys_days = std::chrono::floor<std::chrono::days>(now);
result.value = sys_days.time_since_epoch().count();
TimeZoneResetHelper();
}

void RegisterCurrentDateFunction(const UniquePtr<Catalog> &catalog_ptr) {
String func_name = "currentdate";

SharedPtr<ScalarFunctionSet> function_set_ptr = MakeShared<ScalarFunctionSet>(func_name);

ScalarFunction current_date_function(func_name,
{DataType(LogicalType::kVarchar)},
DataType(LogicalType::kDate),
&ScalarFunction::UnaryFunction<VarcharT, DateT, CurrentDateFunction>);
function_set_ptr->AddFunction(current_date_function);

Catalog::AddFunctionSet(catalog_ptr.get(), function_set_ptr);
}

} // namespace infinity
27 changes: 27 additions & 0 deletions src/function/scalar/current_date.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright(C) 2025 InfiniFlow, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

module;

export module current_date;

import stl;

namespace infinity {

class Catalog;

export void RegisterCurrentDateFunction(const UniquePtr<Catalog> &catalog_ptr);

} // namespace infinity
88 changes: 88 additions & 0 deletions src/function/scalar/current_time.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright(C) 2025 InfiniFlow, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
module;
#include <chrono>
module current_time;
import stl;
import catalog;
import status;
import logical_type;
import infinity_exception;
import scalar_function;
import scalar_function_set;
import third_party;
import internal_types;
import data_type;
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();
}

void RegisterCurrentTimeFunction(const UniquePtr<Catalog> &catalog_ptr) {
String func_name = "currenttime";

SharedPtr<ScalarFunctionSet> function_set_ptr = MakeShared<ScalarFunctionSet>(func_name);

ScalarFunction current_time_function(func_name,
{DataType(LogicalType::kVarchar)},
DataType(LogicalType::kTime),
&ScalarFunction::UnaryFunction<VarcharT, TimeT, CurrentTimeFunction>);
function_set_ptr->AddFunction(current_time_function);

Catalog::AddFunctionSet(catalog_ptr.get(), function_set_ptr);
}

} // namespace infinity
27 changes: 27 additions & 0 deletions src/function/scalar/current_time.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright(C) 2025 InfiniFlow, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

module;

export module current_time;

import stl;

namespace infinity {

class Catalog;

export void RegisterCurrentTimeFunction(const UniquePtr<Catalog> &catalog_ptr);

} // namespace infinity
89 changes: 89 additions & 0 deletions src/function/scalar/current_timestamp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright(C) 2025 InfiniFlow, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
module;
#include <chrono>
module current_timestamp;
import stl;
import catalog;
import status;
import logical_type;
import infinity_exception;
import scalar_function;
import scalar_function_set;
import third_party;
import internal_types;
import data_type;
import column_vector;

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();
}

void RegisterCurrentTimestampFunction(const UniquePtr<Catalog> &catalog_ptr) {
String func_name = "currenttimestamp";

SharedPtr<ScalarFunctionSet> function_set_ptr = MakeShared<ScalarFunctionSet>(func_name);

ScalarFunction current_timestamp_function(func_name,
{DataType(LogicalType::kVarchar)},
DataType(LogicalType::kTimestamp),
&ScalarFunction::UnaryFunction<VarcharT, TimestampT, CurrentTimestampFunction>);
function_set_ptr->AddFunction(current_timestamp_function);

Catalog::AddFunctionSet(catalog_ptr.get(), function_set_ptr);
}

} // namespace infinity
27 changes: 27 additions & 0 deletions src/function/scalar/current_timestamp.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright(C) 2025 InfiniFlow, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

module;

export module current_timestamp;

import stl;

namespace infinity {

class Catalog;

export void RegisterCurrentTimestampFunction(const UniquePtr<Catalog> &catalog_ptr);

} // namespace infinity
Loading