Merge pull request #54479 from rschu1ze/todayssinceyearzero

Add function toDaysSinceYearZero()
This commit is contained in:
Robert Schulze 2023-09-11 17:05:28 +02:00 committed by GitHub
commit 49f29861a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 476 additions and 289 deletions

View File

@ -725,6 +725,42 @@ SELECT toDate('2016-12-27') AS date, toYearWeek(date) AS yearWeek0, toYearWeek(d
└────────────┴───────────┴───────────┴───────────┴───────────────┘
```
## toDaysSinceYearZero
Returns for a given date, the number of days passed since [1 January 0000](https://en.wikipedia.org/wiki/Year_zero) in the [proleptic Gregorian calendar defined by ISO 8601](https://en.wikipedia.org/wiki/Gregorian_calendar#Proleptic_Gregorian_calendar). The calculation is the same as in MySQL's [`TO_DAYS()`](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_to-days) function.
**Syntax**
``` sql
toDaysSinceYearZero(date)
```
Aliases: `TO_DAYS`
**Arguments**
- `date` — The date to calculate the number of days passed since year zero from. [Date](../../sql-reference/data-types/date.md) or [Date32](../../sql-reference/data-types/date32.md).
**Returned value**
The number of days passed since date 0000-01-01.
Type: [UInt32](../../sql-reference/data-types/int-uint.md).
**Example**
``` sql
SELECT toDaysSinceYearZero(toDate('2023-09-08'));
```
Result:
``` text
┌─toDaysSinceYearZero(toDate('2023-09-08')))─┐
│ 713569 │
└────────────────────────────────────────────┘
```
## age
Returns the `unit` component of the difference between `startdate` and `enddate`. The difference is calculated using a precision of 1 microsecond.

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ REGISTER_FUNCTION(Base64Decode)
{
factory.registerFunction<FunctionBase64Conversion<Base64Decode>>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("FROM_BASE64", "base64Decode", FunctionFactory::CaseInsensitive);
}
}

View File

@ -9,7 +9,7 @@ REGISTER_FUNCTION(Base64Encode)
{
factory.registerFunction<FunctionBase64Conversion<Base64Encode>>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("TO_BASE64", "base64Encode", FunctionFactory::CaseInsensitive);
}
}

View File

@ -13,7 +13,7 @@ REGISTER_FUNCTION(ToDayOfMonth)
{
factory.registerFunction<FunctionToDayOfMonth>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("DAY", "toDayOfMonth", FunctionFactory::CaseInsensitive);
factory.registerAlias("DAYOFMONTH", "toDayOfMonth", FunctionFactory::CaseInsensitive);
}

View File

@ -12,7 +12,7 @@ REGISTER_FUNCTION(ToDayOfWeek)
{
factory.registerFunction<FunctionToDayOfWeek>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("DAYOFWEEK", "toDayOfWeek", FunctionFactory::CaseInsensitive);
}

View File

@ -13,7 +13,7 @@ REGISTER_FUNCTION(ToDayOfYear)
{
factory.registerFunction<FunctionToDayOfYear>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("DAYOFYEAR", "toDayOfYear", FunctionFactory::CaseInsensitive);
}

View File

@ -0,0 +1,83 @@
#include <Columns/ColumnsNumber.h>
#include <DataTypes/DataTypeDate.h>
#include <DataTypes/DataTypeDate32.h>
#include <DataTypes/DataTypesNumber.h>
#include <Functions/DateTimeTransforms.h>
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionHelpers.h>
#include <Functions/IFunction.h>
namespace DB
{
namespace ErrorCodes
{
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
}
namespace
{
/** Returns number of days passed since 0000-01-01 */
class FunctionToDaysSinceYearZero : public IFunction
{
using ResultType = DataTypeUInt32;
public:
static constexpr auto name = "toDaysSinceYearZero";
static FunctionPtr create(ContextPtr context) { return std::make_shared<FunctionToDaysSinceYearZero>(context); }
explicit FunctionToDaysSinceYearZero(ContextPtr /*context*/) {}
String getName() const override { return name; }
size_t getNumberOfArguments() const override { return 1; }
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; }
bool useDefaultImplementationForConstants() const override { return true; }
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
{
FunctionArgumentDescriptors mandatory_args{
{"date", &isDateOrDate32<IDataType>, nullptr, "Date or Date32"}
};
validateFunctionArgumentTypes(*this, arguments, mandatory_args);
return std::make_shared<DataTypeUInt32>();
}
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
{
const IDataType * from_type = arguments[0].type.get();
WhichDataType which(from_type);
if (which.isDate())
return DateTimeTransformImpl<DataTypeDate, ResultType, ToDaysSinceYearZeroImpl>::execute(arguments, result_type, input_rows_count);
else if (which.isDate32())
return DateTimeTransformImpl<DataTypeDate32, ResultType, ToDaysSinceYearZeroImpl>::execute(arguments, result_type, input_rows_count);
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
"Illegal type {} of argument of function {}",
arguments[0].type->getName(), this->getName());
}
};
}
REGISTER_FUNCTION(ToDaysSinceYearZero)
{
factory.registerFunction<FunctionToDaysSinceYearZero>(
FunctionDocumentation{
.description=R"(
Returns for a given date, the number of days passed since 1 January 0000 in the proleptic Gregorian calendar defined by ISO 8601.
The calculation is the same as in MySQL's TO_DAYS() function.
)",
.examples{
{"typical", "SELECT toDaysSinceYearZero(toDate('2023-09-08'))", "713569"}},
.categories{"Dates and Times"}
});
/// MySQL compatibility alias.
factory.registerAlias("TO_DAYS", FunctionToDaysSinceYearZero::name, FunctionFactory::CaseInsensitive);
}
}

View File

@ -13,7 +13,7 @@ REGISTER_FUNCTION(ToHour)
{
factory.registerFunction<FunctionToHour>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("HOUR", "toHour", FunctionFactory::CaseInsensitive);
}

View File

@ -13,7 +13,7 @@ REGISTER_FUNCTION(ToMinute)
{
factory.registerFunction<FunctionToMinute>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("MINUTE", "toMinute", FunctionFactory::CaseInsensitive);
}

View File

@ -12,7 +12,7 @@ using FunctionToMonth = FunctionDateOrDateTimeToSomething<DataTypeUInt8, ToMonth
REGISTER_FUNCTION(ToMonth)
{
factory.registerFunction<FunctionToMonth>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("MONTH", "toMonth", FunctionFactory::CaseInsensitive);
}

View File

@ -12,7 +12,7 @@ using FunctionToQuarter = FunctionDateOrDateTimeToSomething<DataTypeUInt8, ToQua
REGISTER_FUNCTION(ToQuarter)
{
factory.registerFunction<FunctionToQuarter>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("QUARTER", "toQuarter", FunctionFactory::CaseInsensitive);
}

View File

@ -13,7 +13,7 @@ REGISTER_FUNCTION(ToSecond)
{
factory.registerFunction<FunctionToSecond>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("SECOND", "toSecond", FunctionFactory::CaseInsensitive);
}

View File

@ -13,7 +13,7 @@ REGISTER_FUNCTION(ToYear)
{
factory.registerFunction<FunctionToYear>();
/// MysQL compatibility alias.
/// MySQL compatibility alias.
factory.registerAlias("YEAR", "toYear", FunctionFactory::CaseInsensitive);
}

View File

@ -0,0 +1,13 @@
Invalid parameters
Const argument
693961
713569
668394
713569
\N
Non-const argument
713569
713569
MySQL alias
713569
713569

View File

@ -0,0 +1,22 @@
SELECT 'Invalid parameters';
SELECT toDaysSinceYearZero(); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
SELECT toDaysSinceYearZero(toDate('2023-09-08'), toDate('2023-09-08')); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
SELECT toDaysSinceYearZero('str'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT toDaysSinceYearZero(42); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT toDaysSinceYearZero(toDateTime('2023-09-08 11:11:11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT toDaysSinceYearZero(toDateTime64('2023-09-08 11:11:11', 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT 'Const argument';
SELECT toDaysSinceYearZero(toDate('1970-01-01'));
SELECT toDaysSinceYearZero(toDate('2023-09-08'));
SELECT toDaysSinceYearZero(toDate32('1900-01-01'));
SELECT toDaysSinceYearZero(toDate32('2023-09-08'));
SELECT toDaysSinceYearZero(NULL);
SELECT 'Non-const argument';
SELECT toDaysSinceYearZero(materialize(toDate('2023-09-08')));
SELECT toDaysSinceYearZero(materialize(toDate32('2023-09-08')));
SELECT 'MySQL alias';
SELECT to_days(toDate('2023-09-08'));
SELECT TO_DAYS(toDate('2023-09-08'));

View File

@ -2002,6 +2002,7 @@ privateKeyPassphraseHandler
prlimit
procfs
profiler
proleptic
prometheus
proto
protobuf
@ -2358,6 +2359,7 @@ toDateTimeOrZero
toDayOfMonth
toDayOfWeek
toDayOfYear
toDaysSinceYearZero
toDecimal
toDecimalString
toFixedString