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 DayOfYear, DayOfMonth, DayOfWeek Functions #2467

Merged
merged 14 commits into from
Jan 20, 2025
60 changes: 60 additions & 0 deletions python/test_pysdk/test_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -1191,4 +1191,64 @@ def test_select_second(self, suffix):
assert res['second(c3)'][0] == 11, "The value of second(c3) should be 11"

res = db_obj.drop_table("test_select_second" + suffix)
assert res.error_code == ErrorCode.OK

def test_select_day_of_month(self, suffix):
db_obj = self.infinity_obj.get_database("default_db")
db_obj.drop_table("test_select_day_of_month" + suffix, ConflictType.Ignore)
db_obj.create_table("test_select_day_of_month" + suffix,
{"c1": {"type": "date"},
"c2": {"type": "datetime"},
"c3": {"type": "timestamp"}}, ConflictType.Error)
table_obj = db_obj.get_table("test_select_day_of_month" + suffix)
table_obj.insert(
[{"c1":"2024-09-23", "c2": "2022-05-26 21:44:33", "c3":"2024-09-23 20:45:11"}])

res, extra_res = table_obj.output(["dayofmonth(c1)", "dayofmonth(c2)", "dayofmonth(c3)"]).to_pl()
print(res)
assert res['dayofmonth(c1)'][0] == 23, "The value of day_of_month(c1) should be 23"
assert res['dayofmonth(c2)'][0] == 26, "The value of day_of_monthc2) should be 26"
assert res['dayofmonth(c3)'][0] == 23, "The value of day_of_month(c3) should be 23"

res = db_obj.drop_table("test_select_day_of_month" + suffix)
assert res.error_code == ErrorCode.OK

def test_select_day_of_year(self, suffix):
db_obj = self.infinity_obj.get_database("default_db")
db_obj.drop_table("test_select_day_of_year" + suffix, ConflictType.Ignore)
db_obj.create_table("test_select_day_of_year" + suffix,
{"c1": {"type": "date"},
"c2": {"type": "datetime"},
"c3": {"type": "timestamp"}}, ConflictType.Error)
table_obj = db_obj.get_table("test_select_day_of_year" + suffix)
table_obj.insert(
[{"c1":"2024-09-23", "c2": "2022-05-26 21:44:33", "c3":"2024-09-23 20:45:11"}])

res, extra_res = table_obj.output(["dayofyear(c1)", "dayofyear(c2)", "dayofyear(c3)"]).to_pl()
print(res)
assert res['dayofyear(c1)'][0] == 267, "The value of day_of_year(c1) should be 267"
assert res['dayofyear(c2)'][0] == 146, "The value of day_of_yearc2) should be 146"
assert res['dayofyear(c3)'][0] == 267, "The value of day_of_year(c3) should be 267"

res = db_obj.drop_table("test_select_day_of_year" + suffix)
assert res.error_code == ErrorCode.OK

def test_select_day_of_week(self, suffix):
db_obj = self.infinity_obj.get_database("default_db")
db_obj.drop_table("test_select_day_of_week" + suffix, ConflictType.Ignore)
db_obj.create_table("test_select_day_of_week" + suffix,
{"c1": {"type": "date"},
"c2": {"type": "datetime"},
"c3": {"type": "timestamp"}}, ConflictType.Error)
table_obj = db_obj.get_table("test_select_day_of_week" + suffix)
table_obj.insert(
[{"c1":"2025-01-16", "c2": "2025-01-16 21:44:33", "c3":"2025-01-16 20:45:11"}])

res, extra_res = table_obj.output(["dayofweek(c1)", "dayofweek(c2)", "dayofweek(c3)"]).to_pl()
print(res)
assert res['dayofweek(c1)'][0] == 4, "The value of day_of_week(c1) should be 4"
assert res['dayofweek(c2)'][0] == 4, "The value of day_of_week(c2) should be 4"
assert res['dayofweek(c3)'][0] == 4, "The value of day_of_week(c3) should be 4"

res = db_obj.drop_table("test_select_day_of_week" + suffix)
assert res.error_code == ErrorCode.OK
6 changes: 6 additions & 0 deletions src/function/builtin_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ import day;
import hour;
import minute;
import second;
import day_of_month;
import day_of_week;
import day_of_year;
import not_func;
import or_func;
import plus;
Expand Down Expand Up @@ -162,6 +165,9 @@ void BuiltinFunctions::RegisterScalarFunction() {
RegisterHourFunction(catalog_ptr_);
RegisterMinuteFunction(catalog_ptr_);
RegisterSecondFunction(catalog_ptr_);
RegisterDayOfYearFunction(catalog_ptr_);
RegisterDayOfMonthFunction(catalog_ptr_);
RegisterDayOfWeekFunction(catalog_ptr_);
}

void BuiltinFunctions::RegisterTableFunction() {}
Expand Down
102 changes: 102 additions & 0 deletions src/function/scalar/day_of_month.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// 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;
module day_of_month;
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 DayOfMonthFunction {
template <typename TA, typename TB>
static inline bool Run(TA left, TB &result) {
Status status = Status::NotSupport("Not implemented");
RecoverableError(status);
return false;
}

};

template <>
inline bool DayOfMonthFunction::Run(DateT left, BigIntT &result) {
year_month_day ymd;
DateT::OuterDate2YMD(left, ymd);
sys_days sd = sys_days(ymd);
year_month_day start{ymd.year(), ymd.month(), day(1)};
sys_days start_sd = sys_days(start);
auto days_diff = sd - start_sd;
result = days_diff.count() + 1;
return true;
}

template <>
inline bool DayOfMonthFunction::Run(DateTimeT left, BigIntT &result) {
year_month_day ymd;
DateTimeT::OuterDateTime2YMD(left.date, ymd);
sys_days sd = sys_days(ymd);
year_month_day start{ymd.year(), ymd.month(), day(1)};
sys_days start_sd = sys_days(start);
auto days_diff = sd - start_sd;
result = days_diff.count() + 1;
return true;
}

template <>
inline bool DayOfMonthFunction::Run(TimestampT left, BigIntT &result) {
year_month_day ymd;
TimestampT::OuterDateTime2YMD(left.date, ymd);
sys_days sd = sys_days(ymd);
year_month_day start{ymd.year(), ymd.month(), day(1)};
sys_days start_sd = sys_days(start);
auto days_diff = sd - start_sd;
result = days_diff.count() + 1;
return true;
}

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

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

ScalarFunction day_of_month_date_function(func_name,
{DataType(LogicalType::kDate)},
{DataType(LogicalType::kBigInt)},
&ScalarFunction::UnaryFunctionWithFailure<DateT, BigIntT, DayOfMonthFunction>);
function_set_ptr->AddFunction(day_of_month_date_function);

ScalarFunction day_of_month_datetime_function(func_name,
{DataType(LogicalType::kDateTime)},
{DataType(LogicalType::kBigInt)},
&ScalarFunction::UnaryFunctionWithFailure<DateTimeT, BigIntT, DayOfMonthFunction>);
function_set_ptr->AddFunction(day_of_month_datetime_function);

ScalarFunction day_of_month_timestamp_function(func_name,
{DataType(LogicalType::kTimestamp)},
{DataType(LogicalType::kBigInt)},
&ScalarFunction::UnaryFunctionWithFailure<TimestampT, BigIntT, DayOfMonthFunction>);
function_set_ptr->AddFunction(day_of_month_timestamp_function);

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

} // namespace infinity
26 changes: 26 additions & 0 deletions src/function/scalar/day_of_month.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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 day_of_month;

import stl;
namespace infinity {

class Catalog;

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

} // namespace infinity
105 changes: 105 additions & 0 deletions src/function/scalar/day_of_week.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// 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 day_of_week;
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 DayOfWeekFunction {
template <typename TA, typename TB>
static inline bool Run(TA left, TB &result) {
Status status = Status::NotSupport("Not implemented");
RecoverableError(status);
return false;
}

};

template <>
inline bool DayOfWeekFunction::Run(DateT left, BigIntT &result) {
year_month_day ymd;
DateT::OuterDate2YMD(left, ymd);
weekday wd = weekday{ymd};
days diff = (wd - weekday{0}) % days{7};
sys_days ymd_sys_days = sys_days(ymd);
sys_days monday_sys_days = ymd_sys_days - diff;
result = (ymd_sys_days - monday_sys_days).count();
return true;
}

template <>
inline bool DayOfWeekFunction::Run(DateTimeT left, BigIntT &result) {
year_month_day ymd;
DateTimeT::OuterDateTime2YMD(left.date, ymd);
weekday wd = weekday{ymd};
days diff = (wd - weekday{0}) % days{7};
sys_days ymd_sys_days = sys_days(ymd);
sys_days monday_sys_days = ymd_sys_days - diff;
result = (ymd_sys_days - monday_sys_days).count();
return true;
}

template <>
inline bool DayOfWeekFunction::Run(TimestampT left, BigIntT &result) {
year_month_day ymd;
TimestampT::OuterDateTime2YMD(left.date, ymd);
weekday wd = weekday{ymd};
days diff = (wd - weekday{0}) % days{7};
sys_days ymd_sys_days = sys_days(ymd);
sys_days monday_sys_days = ymd_sys_days - diff;
result = (ymd_sys_days - monday_sys_days).count();
return true;
}

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

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

ScalarFunction day_of_week_date_function(func_name,
{DataType(LogicalType::kDate)},
{DataType(LogicalType::kBigInt)},
&ScalarFunction::UnaryFunctionWithFailure<DateT, BigIntT, DayOfWeekFunction>);
function_set_ptr->AddFunction(day_of_week_date_function);

ScalarFunction day_of_week_datetime_function(func_name,
{DataType(LogicalType::kDateTime)},
{DataType(LogicalType::kBigInt)},
&ScalarFunction::UnaryFunctionWithFailure<DateTimeT, BigIntT, DayOfWeekFunction>);
function_set_ptr->AddFunction(day_of_week_datetime_function);

ScalarFunction day_of_week_timestamp_function(func_name,
{DataType(LogicalType::kTimestamp)},
{DataType(LogicalType::kBigInt)},
&ScalarFunction::UnaryFunctionWithFailure<TimestampT, BigIntT, DayOfWeekFunction>);
function_set_ptr->AddFunction(day_of_week_timestamp_function);

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

} // namespace infinity
26 changes: 26 additions & 0 deletions src/function/scalar/day_of_week.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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 day_of_week;

import stl;
namespace infinity {

class Catalog;

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

} // namespace infinity
Loading