duckdb 0.3.5-dev464.0 → 0.3.5-dev503.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb.cpp +407 -150
- package/src/duckdb.hpp +75 -26
- package/src/parquet-amalgamation.cpp +36952 -36952
package/src/duckdb.cpp
CHANGED
|
@@ -23360,6 +23360,13 @@ bool TryCast::Operation(date_t input, date_t &result, bool strict) {
|
|
|
23360
23360
|
|
|
23361
23361
|
template <>
|
|
23362
23362
|
bool TryCast::Operation(date_t input, timestamp_t &result, bool strict) {
|
|
23363
|
+
if (input == date_t::infinity()) {
|
|
23364
|
+
result = timestamp_t::infinity();
|
|
23365
|
+
return true;
|
|
23366
|
+
} else if (input == date_t::ninfinity()) {
|
|
23367
|
+
result = timestamp_t::ninfinity();
|
|
23368
|
+
return true;
|
|
23369
|
+
}
|
|
23363
23370
|
return Timestamp::TryFromDatetime(input, Time::FromTime(0, 0, 0), result);
|
|
23364
23371
|
}
|
|
23365
23372
|
|
|
@@ -39321,6 +39328,18 @@ bool Date::ParseDoubleDigit(const char *buf, idx_t len, idx_t &pos, int32_t &res
|
|
|
39321
39328
|
return false;
|
|
39322
39329
|
}
|
|
39323
39330
|
|
|
39331
|
+
static bool TryConvertDateSpecial(const char *buf, idx_t len, idx_t &pos, const char *special) {
|
|
39332
|
+
auto p = pos;
|
|
39333
|
+
for (; p < len && *special; ++p) {
|
|
39334
|
+
const auto s = *special++;
|
|
39335
|
+
if (!s || StringUtil::CharacterToLower(buf[p]) != s) {
|
|
39336
|
+
return false;
|
|
39337
|
+
}
|
|
39338
|
+
}
|
|
39339
|
+
pos = p;
|
|
39340
|
+
return true;
|
|
39341
|
+
}
|
|
39342
|
+
|
|
39324
39343
|
bool Date::TryConvertDate(const char *buf, idx_t len, idx_t &pos, date_t &result, bool strict) {
|
|
39325
39344
|
pos = 0;
|
|
39326
39345
|
if (len == 0) {
|
|
@@ -39349,7 +39368,19 @@ bool Date::TryConvertDate(const char *buf, idx_t len, idx_t &pos, date_t &result
|
|
|
39349
39368
|
}
|
|
39350
39369
|
}
|
|
39351
39370
|
if (!StringUtil::CharacterIsDigit(buf[pos])) {
|
|
39352
|
-
|
|
39371
|
+
// Check for special values
|
|
39372
|
+
if (TryConvertDateSpecial(buf, len, pos, "infinity")) {
|
|
39373
|
+
result = yearneg ? date_t::ninfinity() : date_t::infinity();
|
|
39374
|
+
} else if (TryConvertDateSpecial(buf, len, pos, "epoch")) {
|
|
39375
|
+
result = date_t::epoch();
|
|
39376
|
+
} else {
|
|
39377
|
+
return false;
|
|
39378
|
+
}
|
|
39379
|
+
// skip trailing spaces - parsing must be strict here
|
|
39380
|
+
while (pos < len && StringUtil::CharacterIsSpace(buf[pos])) {
|
|
39381
|
+
pos++;
|
|
39382
|
+
}
|
|
39383
|
+
return pos == len;
|
|
39353
39384
|
}
|
|
39354
39385
|
// first parse the year
|
|
39355
39386
|
for (; pos < len && StringUtil::CharacterIsDigit(buf[pos]); pos++) {
|
|
@@ -39450,6 +39481,13 @@ date_t Date::FromString(const string &str, bool strict) {
|
|
|
39450
39481
|
}
|
|
39451
39482
|
|
|
39452
39483
|
string Date::ToString(date_t date) {
|
|
39484
|
+
// PG displays temporal infinities in lowercase,
|
|
39485
|
+
// but numerics in Titlecase.
|
|
39486
|
+
if (date == date_t::infinity()) {
|
|
39487
|
+
return "infinity";
|
|
39488
|
+
} else if (date == date_t::ninfinity()) {
|
|
39489
|
+
return "-infinity";
|
|
39490
|
+
}
|
|
39453
39491
|
int32_t date_units[3];
|
|
39454
39492
|
idx_t year_length;
|
|
39455
39493
|
bool add_bc;
|
|
@@ -41678,6 +41716,9 @@ bool Interval::GreaterThanEquals(interval_t left, interval_t right) {
|
|
|
41678
41716
|
}
|
|
41679
41717
|
|
|
41680
41718
|
date_t Interval::Add(date_t left, interval_t right) {
|
|
41719
|
+
if (!Date::IsFinite(left)) {
|
|
41720
|
+
return left;
|
|
41721
|
+
}
|
|
41681
41722
|
date_t result;
|
|
41682
41723
|
if (right.months != 0) {
|
|
41683
41724
|
int32_t year, month, day;
|
|
@@ -41707,6 +41748,9 @@ date_t Interval::Add(date_t left, interval_t right) {
|
|
|
41707
41748
|
throw OutOfRangeException("Date out of range");
|
|
41708
41749
|
}
|
|
41709
41750
|
}
|
|
41751
|
+
if (!Date::IsFinite(result)) {
|
|
41752
|
+
throw OutOfRangeException("Date out of range");
|
|
41753
|
+
}
|
|
41710
41754
|
return result;
|
|
41711
41755
|
}
|
|
41712
41756
|
|
|
@@ -41724,6 +41768,9 @@ dtime_t Interval::Add(dtime_t left, interval_t right, date_t &date) {
|
|
|
41724
41768
|
}
|
|
41725
41769
|
|
|
41726
41770
|
timestamp_t Interval::Add(timestamp_t left, interval_t right) {
|
|
41771
|
+
if (!Timestamp::IsFinite(left)) {
|
|
41772
|
+
return left;
|
|
41773
|
+
}
|
|
41727
41774
|
date_t date;
|
|
41728
41775
|
dtime_t time;
|
|
41729
41776
|
Timestamp::Convert(left, date, time);
|
|
@@ -42354,7 +42401,14 @@ bool Timestamp::TryConvertTimestamp(const char *str, idx_t len, timestamp_t &res
|
|
|
42354
42401
|
return false;
|
|
42355
42402
|
}
|
|
42356
42403
|
if (pos == len) {
|
|
42357
|
-
// no time: only a date
|
|
42404
|
+
// no time: only a date or special
|
|
42405
|
+
if (date == date_t::infinity()) {
|
|
42406
|
+
result = timestamp_t::infinity();
|
|
42407
|
+
return true;
|
|
42408
|
+
} else if (date == date_t::ninfinity()) {
|
|
42409
|
+
result = timestamp_t::ninfinity();
|
|
42410
|
+
return true;
|
|
42411
|
+
}
|
|
42358
42412
|
return Timestamp::TryFromDatetime(date, dtime_t(0), result);
|
|
42359
42413
|
}
|
|
42360
42414
|
// try to parse a time field
|
|
@@ -42461,6 +42515,11 @@ timestamp_t Timestamp::FromString(const string &str) {
|
|
|
42461
42515
|
}
|
|
42462
42516
|
|
|
42463
42517
|
string Timestamp::ToString(timestamp_t timestamp) {
|
|
42518
|
+
if (timestamp == timestamp_t::infinity()) {
|
|
42519
|
+
return "infinity";
|
|
42520
|
+
} else if (timestamp == timestamp_t::ninfinity()) {
|
|
42521
|
+
return "-infinity";
|
|
42522
|
+
}
|
|
42464
42523
|
date_t date;
|
|
42465
42524
|
dtime_t time;
|
|
42466
42525
|
Timestamp::Convert(timestamp, date, time);
|
|
@@ -42468,6 +42527,11 @@ string Timestamp::ToString(timestamp_t timestamp) {
|
|
|
42468
42527
|
}
|
|
42469
42528
|
|
|
42470
42529
|
date_t Timestamp::GetDate(timestamp_t timestamp) {
|
|
42530
|
+
if (timestamp == timestamp_t::infinity()) {
|
|
42531
|
+
return date_t::infinity();
|
|
42532
|
+
} else if (timestamp == timestamp_t::ninfinity()) {
|
|
42533
|
+
return date_t::ninfinity();
|
|
42534
|
+
}
|
|
42471
42535
|
return date_t((timestamp.value + (timestamp.value < 0)) / Interval::MICROS_PER_DAY - (timestamp.value < 0));
|
|
42472
42536
|
}
|
|
42473
42537
|
|
|
@@ -42483,7 +42547,7 @@ bool Timestamp::TryFromDatetime(date_t date, dtime_t time, timestamp_t &result)
|
|
|
42483
42547
|
if (!TryAddOperator::Operation<int64_t, int64_t, int64_t>(result.value, time.micros, result.value)) {
|
|
42484
42548
|
return false;
|
|
42485
42549
|
}
|
|
42486
|
-
return
|
|
42550
|
+
return Timestamp::IsFinite(result);
|
|
42487
42551
|
}
|
|
42488
42552
|
|
|
42489
42553
|
timestamp_t Timestamp::FromDatetime(date_t date, dtime_t time) {
|
|
@@ -43049,17 +43113,17 @@ Value Value::MaximumValue(const LogicalType &type) {
|
|
|
43049
43113
|
case LogicalTypeId::TIME:
|
|
43050
43114
|
return Value::TIME(dtime_t(Interval::SECS_PER_DAY * Interval::MICROS_PER_SEC - 1));
|
|
43051
43115
|
case LogicalTypeId::TIMESTAMP:
|
|
43052
|
-
return Value::TIMESTAMP(timestamp_t(NumericLimits<int64_t>::Maximum()));
|
|
43116
|
+
return Value::TIMESTAMP(timestamp_t(NumericLimits<int64_t>::Maximum() - 1));
|
|
43053
43117
|
case LogicalTypeId::TIMESTAMP_MS:
|
|
43054
43118
|
return MaximumValue(LogicalType::TIMESTAMP).CastAs(LogicalType::TIMESTAMP_MS);
|
|
43055
43119
|
case LogicalTypeId::TIMESTAMP_NS:
|
|
43056
|
-
return Value::TIMESTAMPNS(timestamp_t(NumericLimits<int64_t>::Maximum()));
|
|
43120
|
+
return Value::TIMESTAMPNS(timestamp_t(NumericLimits<int64_t>::Maximum() - 1));
|
|
43057
43121
|
case LogicalTypeId::TIMESTAMP_SEC:
|
|
43058
43122
|
return MaximumValue(LogicalType::TIMESTAMP).CastAs(LogicalType::TIMESTAMP_S);
|
|
43059
43123
|
case LogicalTypeId::TIME_TZ:
|
|
43060
43124
|
return Value::TIMETZ(dtime_t(Interval::SECS_PER_DAY * Interval::MICROS_PER_SEC - 1));
|
|
43061
43125
|
case LogicalTypeId::TIMESTAMP_TZ:
|
|
43062
|
-
return
|
|
43126
|
+
return MaximumValue(LogicalType::TIMESTAMP);
|
|
43063
43127
|
case LogicalTypeId::FLOAT:
|
|
43064
43128
|
return Value::FLOAT(NumericLimits<float>::Maximum());
|
|
43065
43129
|
case LogicalTypeId::DOUBLE:
|
|
@@ -43199,6 +43263,16 @@ bool Value::IsFinite(double input) {
|
|
|
43199
43263
|
return Value::DoubleIsFinite(input);
|
|
43200
43264
|
}
|
|
43201
43265
|
|
|
43266
|
+
template <>
|
|
43267
|
+
bool Value::IsFinite(date_t input) {
|
|
43268
|
+
return Date::IsFinite(input);
|
|
43269
|
+
}
|
|
43270
|
+
|
|
43271
|
+
template <>
|
|
43272
|
+
bool Value::IsFinite(timestamp_t input) {
|
|
43273
|
+
return Timestamp::IsFinite(input);
|
|
43274
|
+
}
|
|
43275
|
+
|
|
43202
43276
|
bool Value::StringIsValid(const char *str, idx_t length) {
|
|
43203
43277
|
auto utf_type = Utf8Proc::Analyze(str, length);
|
|
43204
43278
|
return utf_type != UnicodeType::INVALID;
|
|
@@ -44149,8 +44223,14 @@ string Value::ToString() const {
|
|
|
44149
44223
|
return Timestamp::ToString(value_.timestamp);
|
|
44150
44224
|
case LogicalTypeId::TIME_TZ:
|
|
44151
44225
|
return Time::ToString(value_.time) + Time::ToUTCOffset(0, 0);
|
|
44152
|
-
case LogicalTypeId::TIMESTAMP_TZ:
|
|
44153
|
-
|
|
44226
|
+
case LogicalTypeId::TIMESTAMP_TZ: {
|
|
44227
|
+
// Infinite TSTZ values do not display offsets in PG.
|
|
44228
|
+
auto ret = Timestamp::ToString(value_.timestamp);
|
|
44229
|
+
if (Timestamp::IsFinite(value_.timestamp)) {
|
|
44230
|
+
ret += Time::ToUTCOffset(0, 0);
|
|
44231
|
+
}
|
|
44232
|
+
return ret;
|
|
44233
|
+
}
|
|
44154
44234
|
case LogicalTypeId::TIMESTAMP_SEC:
|
|
44155
44235
|
return Timestamp::ToString(Timestamp::FromEpochSeconds(value_.timestamp.value));
|
|
44156
44236
|
case LogicalTypeId::TIMESTAMP_MS:
|
|
@@ -87010,17 +87090,30 @@ static void AgeFunctionStandard(DataChunk &input, ExpressionState &state, Vector
|
|
|
87010
87090
|
D_ASSERT(input.ColumnCount() == 1);
|
|
87011
87091
|
auto current_timestamp = Timestamp::GetCurrentTimestamp();
|
|
87012
87092
|
|
|
87013
|
-
UnaryExecutor::
|
|
87014
|
-
|
|
87015
|
-
|
|
87093
|
+
UnaryExecutor::ExecuteWithNulls<timestamp_t, interval_t>(input.data[0], result, input.size(),
|
|
87094
|
+
[&](timestamp_t input, ValidityMask &mask, idx_t idx) {
|
|
87095
|
+
if (Timestamp::IsFinite(input)) {
|
|
87096
|
+
return Interval::GetAge(current_timestamp, input);
|
|
87097
|
+
} else {
|
|
87098
|
+
mask.SetInvalid(idx);
|
|
87099
|
+
return interval_t();
|
|
87100
|
+
}
|
|
87101
|
+
});
|
|
87016
87102
|
}
|
|
87017
87103
|
|
|
87018
87104
|
static void AgeFunction(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
87019
87105
|
D_ASSERT(input.ColumnCount() == 2);
|
|
87020
87106
|
|
|
87021
|
-
BinaryExecutor::
|
|
87107
|
+
BinaryExecutor::ExecuteWithNulls<timestamp_t, timestamp_t, interval_t>(
|
|
87022
87108
|
input.data[0], input.data[1], result, input.size(),
|
|
87023
|
-
[&](timestamp_t input1, timestamp_t input2
|
|
87109
|
+
[&](timestamp_t input1, timestamp_t input2, ValidityMask &mask, idx_t idx) {
|
|
87110
|
+
if (Timestamp::IsFinite(input1) && Timestamp::IsFinite(input2)) {
|
|
87111
|
+
return Interval::GetAge(input1, input2);
|
|
87112
|
+
} else {
|
|
87113
|
+
mask.SetInvalid(idx);
|
|
87114
|
+
return interval_t();
|
|
87115
|
+
}
|
|
87116
|
+
});
|
|
87024
87117
|
}
|
|
87025
87118
|
|
|
87026
87119
|
void AgeFun::RegisterFunction(BuiltinFunctions &set) {
|
|
@@ -87121,6 +87214,19 @@ namespace duckdb {
|
|
|
87121
87214
|
// This function is an implementation of the "period-crossing" date difference function from T-SQL
|
|
87122
87215
|
// https://docs.microsoft.com/en-us/sql/t-sql/functions/datediff-transact-sql?view=sql-server-ver15
|
|
87123
87216
|
struct DateDiff {
|
|
87217
|
+
template <class TA, class TB, class TR, class OP>
|
|
87218
|
+
static inline void BinaryExecute(Vector &left, Vector &right, Vector &result, idx_t count) {
|
|
87219
|
+
BinaryExecutor::ExecuteWithNulls<TA, TB, TR>(
|
|
87220
|
+
left, right, result, count, [&](TA startdate, TB enddate, ValidityMask &mask, idx_t idx) {
|
|
87221
|
+
if (Value::IsFinite(startdate) && Value::IsFinite(enddate)) {
|
|
87222
|
+
return OP::template Operation<TA, TB, TR>(startdate, enddate);
|
|
87223
|
+
} else {
|
|
87224
|
+
mask.SetInvalid(idx);
|
|
87225
|
+
return TR();
|
|
87226
|
+
}
|
|
87227
|
+
});
|
|
87228
|
+
}
|
|
87229
|
+
|
|
87124
87230
|
struct YearOperator {
|
|
87125
87231
|
template <class TA, class TB, class TR>
|
|
87126
87232
|
static inline TR Operation(TA startdate, TB enddate) {
|
|
@@ -87427,8 +87533,13 @@ static int64_t DifferenceDates(DatePartSpecifier type, TA startdate, TB enddate)
|
|
|
87427
87533
|
|
|
87428
87534
|
struct DateDiffTernaryOperator {
|
|
87429
87535
|
template <typename TS, typename TA, typename TB, typename TR>
|
|
87430
|
-
static inline TR Operation(TS part, TA startdate, TB enddate) {
|
|
87431
|
-
|
|
87536
|
+
static inline TR Operation(TS part, TA startdate, TB enddate, ValidityMask &mask, idx_t idx) {
|
|
87537
|
+
if (Value::IsFinite(startdate) && Value::IsFinite(enddate)) {
|
|
87538
|
+
return DifferenceDates<TA, TB, TR>(GetDatePartSpecifier(part.GetString()), startdate, enddate);
|
|
87539
|
+
} else {
|
|
87540
|
+
mask.SetInvalid(idx);
|
|
87541
|
+
return TR();
|
|
87542
|
+
}
|
|
87432
87543
|
}
|
|
87433
87544
|
};
|
|
87434
87545
|
|
|
@@ -87436,51 +87547,51 @@ template <typename TA, typename TB, typename TR>
|
|
|
87436
87547
|
static void DateDiffBinaryExecutor(DatePartSpecifier type, Vector &left, Vector &right, Vector &result, idx_t count) {
|
|
87437
87548
|
switch (type) {
|
|
87438
87549
|
case DatePartSpecifier::YEAR:
|
|
87439
|
-
|
|
87550
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::YearOperator>(left, right, result, count);
|
|
87440
87551
|
break;
|
|
87441
87552
|
case DatePartSpecifier::MONTH:
|
|
87442
|
-
|
|
87553
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::MonthOperator>(left, right, result, count);
|
|
87443
87554
|
break;
|
|
87444
87555
|
case DatePartSpecifier::DAY:
|
|
87445
87556
|
case DatePartSpecifier::DOW:
|
|
87446
87557
|
case DatePartSpecifier::ISODOW:
|
|
87447
87558
|
case DatePartSpecifier::DOY:
|
|
87448
|
-
|
|
87559
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::DayOperator>(left, right, result, count);
|
|
87449
87560
|
break;
|
|
87450
87561
|
case DatePartSpecifier::DECADE:
|
|
87451
|
-
|
|
87562
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::DecadeOperator>(left, right, result, count);
|
|
87452
87563
|
break;
|
|
87453
87564
|
case DatePartSpecifier::CENTURY:
|
|
87454
|
-
|
|
87565
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::CenturyOperator>(left, right, result, count);
|
|
87455
87566
|
break;
|
|
87456
87567
|
case DatePartSpecifier::MILLENNIUM:
|
|
87457
|
-
|
|
87568
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::MilleniumOperator>(left, right, result, count);
|
|
87458
87569
|
break;
|
|
87459
87570
|
case DatePartSpecifier::QUARTER:
|
|
87460
|
-
|
|
87571
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::QuarterOperator>(left, right, result, count);
|
|
87461
87572
|
break;
|
|
87462
87573
|
case DatePartSpecifier::WEEK:
|
|
87463
87574
|
case DatePartSpecifier::YEARWEEK:
|
|
87464
|
-
|
|
87575
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::WeekOperator>(left, right, result, count);
|
|
87465
87576
|
break;
|
|
87466
87577
|
case DatePartSpecifier::ISOYEAR:
|
|
87467
|
-
|
|
87578
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::ISOYearOperator>(left, right, result, count);
|
|
87468
87579
|
break;
|
|
87469
87580
|
case DatePartSpecifier::MICROSECONDS:
|
|
87470
|
-
|
|
87581
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::MicrosecondsOperator>(left, right, result, count);
|
|
87471
87582
|
break;
|
|
87472
87583
|
case DatePartSpecifier::MILLISECONDS:
|
|
87473
|
-
|
|
87584
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::MillisecondsOperator>(left, right, result, count);
|
|
87474
87585
|
break;
|
|
87475
87586
|
case DatePartSpecifier::SECOND:
|
|
87476
87587
|
case DatePartSpecifier::EPOCH:
|
|
87477
|
-
|
|
87588
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::SecondsOperator>(left, right, result, count);
|
|
87478
87589
|
break;
|
|
87479
87590
|
case DatePartSpecifier::MINUTE:
|
|
87480
|
-
|
|
87591
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::MinutesOperator>(left, right, result, count);
|
|
87481
87592
|
break;
|
|
87482
87593
|
case DatePartSpecifier::HOUR:
|
|
87483
|
-
|
|
87594
|
+
DateDiff::BinaryExecute<TA, TB, TR, DateDiff::HoursOperator>(left, right, result, count);
|
|
87484
87595
|
break;
|
|
87485
87596
|
default:
|
|
87486
87597
|
throw NotImplementedException("Specifier type not implemented for DATEDIFF");
|
|
@@ -87491,8 +87602,8 @@ template <typename T>
|
|
|
87491
87602
|
static void DateDiffFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
87492
87603
|
D_ASSERT(args.ColumnCount() == 3);
|
|
87493
87604
|
auto &part_arg = args.data[0];
|
|
87494
|
-
auto &
|
|
87495
|
-
auto &
|
|
87605
|
+
auto &start_arg = args.data[1];
|
|
87606
|
+
auto &end_arg = args.data[2];
|
|
87496
87607
|
|
|
87497
87608
|
if (part_arg.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
87498
87609
|
// Common case of constant part.
|
|
@@ -87501,11 +87612,12 @@ static void DateDiffFunction(DataChunk &args, ExpressionState &state, Vector &re
|
|
|
87501
87612
|
ConstantVector::SetNull(result, true);
|
|
87502
87613
|
} else {
|
|
87503
87614
|
const auto type = GetDatePartSpecifier(ConstantVector::GetData<string_t>(part_arg)->GetString());
|
|
87504
|
-
DateDiffBinaryExecutor<T, T, int64_t>(type,
|
|
87615
|
+
DateDiffBinaryExecutor<T, T, int64_t>(type, start_arg, end_arg, result, args.size());
|
|
87505
87616
|
}
|
|
87506
87617
|
} else {
|
|
87507
|
-
TernaryExecutor::
|
|
87508
|
-
|
|
87618
|
+
TernaryExecutor::ExecuteWithNulls<string_t, T, T, int64_t>(
|
|
87619
|
+
part_arg, start_arg, end_arg, result, args.size(),
|
|
87620
|
+
DateDiffTernaryOperator::Operation<string_t, T, T, int64_t>);
|
|
87509
87621
|
}
|
|
87510
87622
|
}
|
|
87511
87623
|
|
|
@@ -87680,39 +87792,6 @@ DatePartSpecifier GetDateTypePartSpecifier(const string &specifier, LogicalType
|
|
|
87680
87792
|
throw NotImplementedException("\"%s\" units \"%s\" not recognized", LogicalTypeIdToString(type.id()), specifier);
|
|
87681
87793
|
}
|
|
87682
87794
|
|
|
87683
|
-
template <class T>
|
|
87684
|
-
static void LastYearFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
87685
|
-
int32_t last_year = 0;
|
|
87686
|
-
UnaryExecutor::Execute<T, int64_t>(args.data[0], result, args.size(),
|
|
87687
|
-
[&](T input) { return Date::ExtractYear(input, &last_year); });
|
|
87688
|
-
}
|
|
87689
|
-
|
|
87690
|
-
template <class T, class OP>
|
|
87691
|
-
static unique_ptr<BaseStatistics> PropagateDatePartStatistics(vector<unique_ptr<BaseStatistics>> &child_stats) {
|
|
87692
|
-
// we can only propagate complex date part stats if the child has stats
|
|
87693
|
-
if (!child_stats[0]) {
|
|
87694
|
-
return nullptr;
|
|
87695
|
-
}
|
|
87696
|
-
auto &nstats = (NumericStatistics &)*child_stats[0];
|
|
87697
|
-
if (nstats.min.IsNull() || nstats.max.IsNull()) {
|
|
87698
|
-
return nullptr;
|
|
87699
|
-
}
|
|
87700
|
-
// run the operator on both the min and the max, this gives us the [min, max] bound
|
|
87701
|
-
auto min = nstats.min.GetValueUnsafe<T>();
|
|
87702
|
-
auto max = nstats.max.GetValueUnsafe<T>();
|
|
87703
|
-
if (min > max) {
|
|
87704
|
-
return nullptr;
|
|
87705
|
-
}
|
|
87706
|
-
auto min_part = OP::template Operation<T, int64_t>(min);
|
|
87707
|
-
auto max_part = OP::template Operation<T, int64_t>(max);
|
|
87708
|
-
auto result = make_unique<NumericStatistics>(LogicalType::BIGINT, Value::BIGINT(min_part), Value::BIGINT(max_part),
|
|
87709
|
-
StatisticsType::LOCAL_STATS);
|
|
87710
|
-
if (child_stats[0]->validity_stats) {
|
|
87711
|
-
result->validity_stats = child_stats[0]->validity_stats->Copy();
|
|
87712
|
-
}
|
|
87713
|
-
return move(result);
|
|
87714
|
-
}
|
|
87715
|
-
|
|
87716
87795
|
template <int64_t MIN, int64_t MAX>
|
|
87717
87796
|
static unique_ptr<BaseStatistics> PropagateSimpleDatePartStatistics(vector<unique_ptr<BaseStatistics>> &child_stats) {
|
|
87718
87797
|
// we can always propagate simple date part statistics
|
|
@@ -87729,6 +87808,56 @@ static unique_ptr<BaseStatistics> PropagateSimpleDatePartStatistics(vector<uniqu
|
|
|
87729
87808
|
}
|
|
87730
87809
|
|
|
87731
87810
|
struct DatePart {
|
|
87811
|
+
template <class T, class OP>
|
|
87812
|
+
static unique_ptr<BaseStatistics> PropagateDatePartStatistics(vector<unique_ptr<BaseStatistics>> &child_stats) {
|
|
87813
|
+
// we can only propagate complex date part stats if the child has stats
|
|
87814
|
+
if (!child_stats[0]) {
|
|
87815
|
+
return nullptr;
|
|
87816
|
+
}
|
|
87817
|
+
auto &nstats = (NumericStatistics &)*child_stats[0];
|
|
87818
|
+
if (nstats.min.IsNull() || nstats.max.IsNull()) {
|
|
87819
|
+
return nullptr;
|
|
87820
|
+
}
|
|
87821
|
+
// run the operator on both the min and the max, this gives us the [min, max] bound
|
|
87822
|
+
auto min = nstats.min.GetValueUnsafe<T>();
|
|
87823
|
+
auto max = nstats.max.GetValueUnsafe<T>();
|
|
87824
|
+
if (min > max) {
|
|
87825
|
+
return nullptr;
|
|
87826
|
+
}
|
|
87827
|
+
// Infinities prevent us from computing generic ranges
|
|
87828
|
+
if (!Value::IsFinite(min) || !Value::IsFinite(max)) {
|
|
87829
|
+
return nullptr;
|
|
87830
|
+
}
|
|
87831
|
+
auto min_part = OP::template Operation<T, int64_t>(min);
|
|
87832
|
+
auto max_part = OP::template Operation<T, int64_t>(max);
|
|
87833
|
+
auto result = make_unique<NumericStatistics>(LogicalType::BIGINT, Value::BIGINT(min_part),
|
|
87834
|
+
Value::BIGINT(max_part), StatisticsType::LOCAL_STATS);
|
|
87835
|
+
if (child_stats[0]->validity_stats) {
|
|
87836
|
+
result->validity_stats = child_stats[0]->validity_stats->Copy();
|
|
87837
|
+
}
|
|
87838
|
+
return move(result);
|
|
87839
|
+
}
|
|
87840
|
+
|
|
87841
|
+
template <typename OP>
|
|
87842
|
+
struct PartOperator {
|
|
87843
|
+
template <class TA, class TR>
|
|
87844
|
+
static inline TR Operation(TA input, ValidityMask &mask, idx_t idx, void *dataptr) {
|
|
87845
|
+
if (Value::IsFinite(input)) {
|
|
87846
|
+
return OP::template Operation<TA, TR>(input);
|
|
87847
|
+
} else {
|
|
87848
|
+
mask.SetInvalid(idx);
|
|
87849
|
+
return TR();
|
|
87850
|
+
}
|
|
87851
|
+
}
|
|
87852
|
+
};
|
|
87853
|
+
|
|
87854
|
+
template <class TA, class TR, class OP>
|
|
87855
|
+
static void UnaryFunction(DataChunk &input, ExpressionState &state, Vector &result) {
|
|
87856
|
+
D_ASSERT(input.ColumnCount() >= 1);
|
|
87857
|
+
using IOP = PartOperator<OP>;
|
|
87858
|
+
UnaryExecutor::GenericExecute<TA, TR, IOP>(input.data[0], result, input.size(), nullptr, true);
|
|
87859
|
+
}
|
|
87860
|
+
|
|
87732
87861
|
struct YearOperator {
|
|
87733
87862
|
template <class TA, class TR>
|
|
87734
87863
|
static inline TR Operation(TA input) {
|
|
@@ -88229,6 +88358,20 @@ struct DatePart {
|
|
|
88229
88358
|
};
|
|
88230
88359
|
};
|
|
88231
88360
|
|
|
88361
|
+
template <class T>
|
|
88362
|
+
static void LastYearFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
88363
|
+
int32_t last_year = 0;
|
|
88364
|
+
UnaryExecutor::ExecuteWithNulls<T, int64_t>(args.data[0], result, args.size(),
|
|
88365
|
+
[&](T input, ValidityMask &mask, idx_t idx) {
|
|
88366
|
+
if (Value::IsFinite(input)) {
|
|
88367
|
+
return Date::ExtractYear(input, &last_year);
|
|
88368
|
+
} else {
|
|
88369
|
+
mask.SetInvalid(idx);
|
|
88370
|
+
return 0;
|
|
88371
|
+
}
|
|
88372
|
+
});
|
|
88373
|
+
}
|
|
88374
|
+
|
|
88232
88375
|
template <>
|
|
88233
88376
|
int64_t DatePart::YearOperator::Operation(timestamp_t input) {
|
|
88234
88377
|
return YearOperator::Operation<date_t, int64_t>(Timestamp::GetDate(input));
|
|
@@ -88728,21 +88871,21 @@ static int64_t ExtractElement(DatePartSpecifier type, T element) {
|
|
|
88728
88871
|
}
|
|
88729
88872
|
}
|
|
88730
88873
|
|
|
88731
|
-
struct DatePartBinaryOperator {
|
|
88732
|
-
template <class TA, class TB, class TR>
|
|
88733
|
-
static inline TR Operation(TA specifier, TB date) {
|
|
88734
|
-
return ExtractElement<TB>(GetDatePartSpecifier(specifier.GetString()), date);
|
|
88735
|
-
}
|
|
88736
|
-
};
|
|
88737
|
-
|
|
88738
88874
|
template <typename T>
|
|
88739
88875
|
static void DatePartFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
88740
88876
|
D_ASSERT(args.ColumnCount() == 2);
|
|
88741
|
-
auto &
|
|
88877
|
+
auto &spec_arg = args.data[0];
|
|
88742
88878
|
auto &date_arg = args.data[1];
|
|
88743
88879
|
|
|
88744
|
-
BinaryExecutor::
|
|
88745
|
-
|
|
88880
|
+
BinaryExecutor::ExecuteWithNulls<string_t, T, int64_t>(
|
|
88881
|
+
spec_arg, date_arg, result, args.size(), [&](string_t specifier, T date, ValidityMask &mask, idx_t idx) {
|
|
88882
|
+
if (Value::IsFinite(date)) {
|
|
88883
|
+
return ExtractElement<T>(GetDatePartSpecifier(specifier.GetString()), date);
|
|
88884
|
+
} else {
|
|
88885
|
+
mask.SetInvalid(idx);
|
|
88886
|
+
return int64_t(0);
|
|
88887
|
+
}
|
|
88888
|
+
});
|
|
88746
88889
|
}
|
|
88747
88890
|
|
|
88748
88891
|
void AddGenericDatePartOperator(BuiltinFunctions &set, const string &name, scalar_function_t date_func,
|
|
@@ -88759,8 +88902,8 @@ void AddGenericDatePartOperator(BuiltinFunctions &set, const string &name, scala
|
|
|
88759
88902
|
|
|
88760
88903
|
template <class OP>
|
|
88761
88904
|
static void AddDatePartOperator(BuiltinFunctions &set, string name) {
|
|
88762
|
-
AddGenericDatePartOperator(set, name,
|
|
88763
|
-
|
|
88905
|
+
AddGenericDatePartOperator(set, name, DatePart::UnaryFunction<date_t, int64_t, OP>,
|
|
88906
|
+
DatePart::UnaryFunction<timestamp_t, int64_t, OP>,
|
|
88764
88907
|
ScalarFunction::UnaryFunction<interval_t, int64_t, OP>,
|
|
88765
88908
|
OP::template PropagateStatistics<date_t>, OP::template PropagateStatistics<timestamp_t>);
|
|
88766
88909
|
}
|
|
@@ -88783,10 +88926,10 @@ void AddGenericTimePartOperator(BuiltinFunctions &set, const string &name, scala
|
|
|
88783
88926
|
template <class OP>
|
|
88784
88927
|
static void AddTimePartOperator(BuiltinFunctions &set, string name) {
|
|
88785
88928
|
AddGenericTimePartOperator(
|
|
88786
|
-
set, name,
|
|
88787
|
-
ScalarFunction::UnaryFunction<
|
|
88788
|
-
|
|
88789
|
-
OP::template PropagateStatistics<
|
|
88929
|
+
set, name, DatePart::UnaryFunction<date_t, int64_t, OP>, DatePart::UnaryFunction<timestamp_t, int64_t, OP>,
|
|
88930
|
+
ScalarFunction::UnaryFunction<interval_t, int64_t, OP>, ScalarFunction::UnaryFunction<dtime_t, int64_t, OP>,
|
|
88931
|
+
OP::template PropagateStatistics<date_t>, OP::template PropagateStatistics<timestamp_t>,
|
|
88932
|
+
OP::template PropagateStatistics<dtime_t>);
|
|
88790
88933
|
}
|
|
88791
88934
|
|
|
88792
88935
|
struct LastDayOperator {
|
|
@@ -88914,7 +89057,13 @@ struct StructDatePart {
|
|
|
88914
89057
|
}
|
|
88915
89058
|
}
|
|
88916
89059
|
auto tdata = ConstantVector::GetData<INPUT_TYPE>(input);
|
|
88917
|
-
|
|
89060
|
+
if (Value::IsFinite(tdata[0])) {
|
|
89061
|
+
DatePart::StructOperator::Operation(part_values.data(), tdata[0], 0, part_mask);
|
|
89062
|
+
} else {
|
|
89063
|
+
for (auto &child_entry : child_entries) {
|
|
89064
|
+
ConstantVector::SetNull(*child_entry, true);
|
|
89065
|
+
}
|
|
89066
|
+
}
|
|
88918
89067
|
}
|
|
88919
89068
|
} else {
|
|
88920
89069
|
VectorData rdata;
|
|
@@ -88949,7 +89098,13 @@ struct StructDatePart {
|
|
|
88949
89098
|
for (idx_t i = 0; i < count; ++i) {
|
|
88950
89099
|
const auto idx = rdata.sel->get_index(i);
|
|
88951
89100
|
if (arg_valid.RowIsValid(idx)) {
|
|
88952
|
-
|
|
89101
|
+
if (Value::IsFinite(tdata[idx])) {
|
|
89102
|
+
DatePart::StructOperator::Operation(part_values.data(), tdata[idx], idx, part_mask);
|
|
89103
|
+
} else {
|
|
89104
|
+
for (auto &child_entry : child_entries) {
|
|
89105
|
+
FlatVector::Validity(*child_entry).SetInvalid(idx);
|
|
89106
|
+
}
|
|
89107
|
+
}
|
|
88953
89108
|
} else {
|
|
88954
89109
|
res_valid.SetInvalid(idx);
|
|
88955
89110
|
for (auto &child_entry : child_entries) {
|
|
@@ -89018,25 +89173,25 @@ void DatePartFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
89018
89173
|
// register the last_day function
|
|
89019
89174
|
ScalarFunctionSet last_day("last_day");
|
|
89020
89175
|
last_day.AddFunction(ScalarFunction({LogicalType::DATE}, LogicalType::DATE,
|
|
89021
|
-
|
|
89176
|
+
DatePart::UnaryFunction<date_t, date_t, LastDayOperator>));
|
|
89022
89177
|
last_day.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::DATE,
|
|
89023
|
-
|
|
89178
|
+
DatePart::UnaryFunction<timestamp_t, date_t, LastDayOperator>));
|
|
89024
89179
|
set.AddFunction(last_day);
|
|
89025
89180
|
|
|
89026
89181
|
// register the monthname function
|
|
89027
89182
|
ScalarFunctionSet monthname("monthname");
|
|
89028
89183
|
monthname.AddFunction(ScalarFunction({LogicalType::DATE}, LogicalType::VARCHAR,
|
|
89029
|
-
|
|
89184
|
+
DatePart::UnaryFunction<date_t, string_t, MonthNameOperator>));
|
|
89030
89185
|
monthname.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::VARCHAR,
|
|
89031
|
-
|
|
89186
|
+
DatePart::UnaryFunction<timestamp_t, string_t, MonthNameOperator>));
|
|
89032
89187
|
set.AddFunction(monthname);
|
|
89033
89188
|
|
|
89034
89189
|
// register the dayname function
|
|
89035
89190
|
ScalarFunctionSet dayname("dayname");
|
|
89036
89191
|
dayname.AddFunction(ScalarFunction({LogicalType::DATE}, LogicalType::VARCHAR,
|
|
89037
|
-
|
|
89192
|
+
DatePart::UnaryFunction<date_t, string_t, DayNameOperator>));
|
|
89038
89193
|
dayname.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::VARCHAR,
|
|
89039
|
-
|
|
89194
|
+
DatePart::UnaryFunction<timestamp_t, string_t, DayNameOperator>));
|
|
89040
89195
|
set.AddFunction(dayname);
|
|
89041
89196
|
|
|
89042
89197
|
// finally the actual date_part function
|
|
@@ -89077,6 +89232,19 @@ void DatePartFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
89077
89232
|
namespace duckdb {
|
|
89078
89233
|
|
|
89079
89234
|
struct DateSub {
|
|
89235
|
+
template <class TA, class TB, class TR, class OP>
|
|
89236
|
+
static inline void BinaryExecute(Vector &left, Vector &right, Vector &result, idx_t count) {
|
|
89237
|
+
BinaryExecutor::ExecuteWithNulls<TA, TB, TR>(
|
|
89238
|
+
left, right, result, count, [&](TA startdate, TB enddate, ValidityMask &mask, idx_t idx) {
|
|
89239
|
+
if (Value::IsFinite(startdate) && Value::IsFinite(enddate)) {
|
|
89240
|
+
return OP::template Operation<TA, TB, TR>(startdate, enddate);
|
|
89241
|
+
} else {
|
|
89242
|
+
mask.SetInvalid(idx);
|
|
89243
|
+
return TR();
|
|
89244
|
+
}
|
|
89245
|
+
});
|
|
89246
|
+
}
|
|
89247
|
+
|
|
89080
89248
|
struct MonthOperator {
|
|
89081
89249
|
template <class TA, class TB, class TR>
|
|
89082
89250
|
static inline TR Operation(TA start_ts, TB end_ts) {
|
|
@@ -89403,8 +89571,13 @@ static int64_t SubtractDateParts(DatePartSpecifier type, TA startdate, TB enddat
|
|
|
89403
89571
|
|
|
89404
89572
|
struct DateSubTernaryOperator {
|
|
89405
89573
|
template <typename TS, typename TA, typename TB, typename TR>
|
|
89406
|
-
static inline TR Operation(TS part, TA startdate, TB enddate) {
|
|
89407
|
-
|
|
89574
|
+
static inline TR Operation(TS part, TA startdate, TB enddate, ValidityMask &mask, idx_t idx) {
|
|
89575
|
+
if (Value::IsFinite(startdate) && Value::IsFinite(enddate)) {
|
|
89576
|
+
return SubtractDateParts<TA, TB, TR>(GetDatePartSpecifier(part.GetString()), startdate, enddate);
|
|
89577
|
+
} else {
|
|
89578
|
+
mask.SetInvalid(idx);
|
|
89579
|
+
return TR();
|
|
89580
|
+
}
|
|
89408
89581
|
}
|
|
89409
89582
|
};
|
|
89410
89583
|
|
|
@@ -89413,48 +89586,48 @@ static void DateSubBinaryExecutor(DatePartSpecifier type, Vector &left, Vector &
|
|
|
89413
89586
|
switch (type) {
|
|
89414
89587
|
case DatePartSpecifier::YEAR:
|
|
89415
89588
|
case DatePartSpecifier::ISOYEAR:
|
|
89416
|
-
|
|
89589
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::YearOperator>(left, right, result, count);
|
|
89417
89590
|
break;
|
|
89418
89591
|
case DatePartSpecifier::MONTH:
|
|
89419
|
-
|
|
89592
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::MonthOperator>(left, right, result, count);
|
|
89420
89593
|
break;
|
|
89421
89594
|
case DatePartSpecifier::DAY:
|
|
89422
89595
|
case DatePartSpecifier::DOW:
|
|
89423
89596
|
case DatePartSpecifier::ISODOW:
|
|
89424
89597
|
case DatePartSpecifier::DOY:
|
|
89425
|
-
|
|
89598
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::DayOperator>(left, right, result, count);
|
|
89426
89599
|
break;
|
|
89427
89600
|
case DatePartSpecifier::DECADE:
|
|
89428
|
-
|
|
89601
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::DecadeOperator>(left, right, result, count);
|
|
89429
89602
|
break;
|
|
89430
89603
|
case DatePartSpecifier::CENTURY:
|
|
89431
|
-
|
|
89604
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::CenturyOperator>(left, right, result, count);
|
|
89432
89605
|
break;
|
|
89433
89606
|
case DatePartSpecifier::MILLENNIUM:
|
|
89434
|
-
|
|
89607
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::MilleniumOperator>(left, right, result, count);
|
|
89435
89608
|
break;
|
|
89436
89609
|
case DatePartSpecifier::QUARTER:
|
|
89437
|
-
|
|
89610
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::QuarterOperator>(left, right, result, count);
|
|
89438
89611
|
break;
|
|
89439
89612
|
case DatePartSpecifier::WEEK:
|
|
89440
89613
|
case DatePartSpecifier::YEARWEEK:
|
|
89441
|
-
|
|
89614
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::WeekOperator>(left, right, result, count);
|
|
89442
89615
|
break;
|
|
89443
89616
|
case DatePartSpecifier::MICROSECONDS:
|
|
89444
|
-
|
|
89617
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::MicrosecondsOperator>(left, right, result, count);
|
|
89445
89618
|
break;
|
|
89446
89619
|
case DatePartSpecifier::MILLISECONDS:
|
|
89447
|
-
|
|
89620
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::MillisecondsOperator>(left, right, result, count);
|
|
89448
89621
|
break;
|
|
89449
89622
|
case DatePartSpecifier::SECOND:
|
|
89450
89623
|
case DatePartSpecifier::EPOCH:
|
|
89451
|
-
|
|
89624
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::SecondsOperator>(left, right, result, count);
|
|
89452
89625
|
break;
|
|
89453
89626
|
case DatePartSpecifier::MINUTE:
|
|
89454
|
-
|
|
89627
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::MinutesOperator>(left, right, result, count);
|
|
89455
89628
|
break;
|
|
89456
89629
|
case DatePartSpecifier::HOUR:
|
|
89457
|
-
|
|
89630
|
+
DateSub::BinaryExecute<TA, TB, TR, DateSub::HoursOperator>(left, right, result, count);
|
|
89458
89631
|
break;
|
|
89459
89632
|
default:
|
|
89460
89633
|
throw NotImplementedException("Specifier type not implemented for DATESUB");
|
|
@@ -89465,8 +89638,8 @@ template <typename T>
|
|
|
89465
89638
|
static void DateSubFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
89466
89639
|
D_ASSERT(args.ColumnCount() == 3);
|
|
89467
89640
|
auto &part_arg = args.data[0];
|
|
89468
|
-
auto &
|
|
89469
|
-
auto &
|
|
89641
|
+
auto &start_arg = args.data[1];
|
|
89642
|
+
auto &end_arg = args.data[2];
|
|
89470
89643
|
|
|
89471
89644
|
if (part_arg.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
89472
89645
|
// Common case of constant part.
|
|
@@ -89475,11 +89648,12 @@ static void DateSubFunction(DataChunk &args, ExpressionState &state, Vector &res
|
|
|
89475
89648
|
ConstantVector::SetNull(result, true);
|
|
89476
89649
|
} else {
|
|
89477
89650
|
const auto type = GetDatePartSpecifier(ConstantVector::GetData<string_t>(part_arg)->GetString());
|
|
89478
|
-
DateSubBinaryExecutor<T, T, int64_t>(type,
|
|
89651
|
+
DateSubBinaryExecutor<T, T, int64_t>(type, start_arg, end_arg, result, args.size());
|
|
89479
89652
|
}
|
|
89480
89653
|
} else {
|
|
89481
|
-
TernaryExecutor::
|
|
89482
|
-
|
|
89654
|
+
TernaryExecutor::ExecuteWithNulls<string_t, T, T, int64_t>(
|
|
89655
|
+
part_arg, start_arg, end_arg, result, args.size(),
|
|
89656
|
+
DateSubTernaryOperator::Operation<string_t, T, T, int64_t>);
|
|
89483
89657
|
}
|
|
89484
89658
|
}
|
|
89485
89659
|
|
|
@@ -89506,9 +89680,21 @@ void DateSubFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
89506
89680
|
|
|
89507
89681
|
|
|
89508
89682
|
|
|
89683
|
+
|
|
89684
|
+
|
|
89509
89685
|
namespace duckdb {
|
|
89510
89686
|
|
|
89511
89687
|
struct DateTrunc {
|
|
89688
|
+
template <class TA, class TR, class OP>
|
|
89689
|
+
static inline void UnaryExecute(Vector &left, Vector &result, idx_t count) {
|
|
89690
|
+
UnaryExecutor::Execute<TA, TR>(left, result, count, [&](TA input) {
|
|
89691
|
+
if (Value::IsFinite(input)) {
|
|
89692
|
+
return OP::template Operation<TA, TR>(input);
|
|
89693
|
+
} else {
|
|
89694
|
+
return Cast::template Operation<TA, TR>(input);
|
|
89695
|
+
}
|
|
89696
|
+
});
|
|
89697
|
+
}
|
|
89512
89698
|
|
|
89513
89699
|
struct MillenniumOperator {
|
|
89514
89700
|
template <class TA, class TR>
|
|
@@ -89813,6 +89999,10 @@ interval_t DateTrunc::MicrosecondOperator::Operation(interval_t input) {
|
|
|
89813
89999
|
|
|
89814
90000
|
template <class TA, class TR>
|
|
89815
90001
|
static TR TruncateElement(DatePartSpecifier type, TA element) {
|
|
90002
|
+
if (!Value::IsFinite(element)) {
|
|
90003
|
+
return Cast::template Operation<TA, TR>(element);
|
|
90004
|
+
}
|
|
90005
|
+
|
|
89816
90006
|
switch (type) {
|
|
89817
90007
|
case DatePartSpecifier::MILLENNIUM:
|
|
89818
90008
|
return DateTrunc::MillenniumOperator::Operation<TA, TR>(element);
|
|
@@ -89863,51 +90053,51 @@ template <typename TA, typename TR>
|
|
|
89863
90053
|
static void DateTruncUnaryExecutor(DatePartSpecifier type, Vector &left, Vector &result, idx_t count) {
|
|
89864
90054
|
switch (type) {
|
|
89865
90055
|
case DatePartSpecifier::MILLENNIUM:
|
|
89866
|
-
|
|
90056
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::MillenniumOperator>(left, result, count);
|
|
89867
90057
|
break;
|
|
89868
90058
|
case DatePartSpecifier::CENTURY:
|
|
89869
|
-
|
|
90059
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::CenturyOperator>(left, result, count);
|
|
89870
90060
|
break;
|
|
89871
90061
|
case DatePartSpecifier::DECADE:
|
|
89872
|
-
|
|
90062
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::DecadeOperator>(left, result, count);
|
|
89873
90063
|
break;
|
|
89874
90064
|
case DatePartSpecifier::YEAR:
|
|
89875
|
-
|
|
90065
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::YearOperator>(left, result, count);
|
|
89876
90066
|
break;
|
|
89877
90067
|
case DatePartSpecifier::QUARTER:
|
|
89878
|
-
|
|
90068
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::QuarterOperator>(left, result, count);
|
|
89879
90069
|
break;
|
|
89880
90070
|
case DatePartSpecifier::MONTH:
|
|
89881
|
-
|
|
90071
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::MonthOperator>(left, result, count);
|
|
89882
90072
|
break;
|
|
89883
90073
|
case DatePartSpecifier::WEEK:
|
|
89884
90074
|
case DatePartSpecifier::YEARWEEK:
|
|
89885
|
-
|
|
90075
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::WeekOperator>(left, result, count);
|
|
89886
90076
|
break;
|
|
89887
90077
|
case DatePartSpecifier::ISOYEAR:
|
|
89888
|
-
|
|
90078
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::ISOYearOperator>(left, result, count);
|
|
89889
90079
|
break;
|
|
89890
90080
|
case DatePartSpecifier::DAY:
|
|
89891
90081
|
case DatePartSpecifier::DOW:
|
|
89892
90082
|
case DatePartSpecifier::ISODOW:
|
|
89893
90083
|
case DatePartSpecifier::DOY:
|
|
89894
|
-
|
|
90084
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::DayOperator>(left, result, count);
|
|
89895
90085
|
break;
|
|
89896
90086
|
case DatePartSpecifier::HOUR:
|
|
89897
|
-
|
|
90087
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::HourOperator>(left, result, count);
|
|
89898
90088
|
break;
|
|
89899
90089
|
case DatePartSpecifier::MINUTE:
|
|
89900
|
-
|
|
90090
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::MinuteOperator>(left, result, count);
|
|
89901
90091
|
break;
|
|
89902
90092
|
case DatePartSpecifier::SECOND:
|
|
89903
90093
|
case DatePartSpecifier::EPOCH:
|
|
89904
|
-
|
|
90094
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::SecondOperator>(left, result, count);
|
|
89905
90095
|
break;
|
|
89906
90096
|
case DatePartSpecifier::MILLISECONDS:
|
|
89907
|
-
|
|
90097
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::MillisecondOperator>(left, result, count);
|
|
89908
90098
|
break;
|
|
89909
90099
|
case DatePartSpecifier::MICROSECONDS:
|
|
89910
|
-
|
|
90100
|
+
DateTrunc::UnaryExecute<TA, TR, DateTrunc::MicrosecondOperator>(left, result, count);
|
|
89911
90101
|
break;
|
|
89912
90102
|
default:
|
|
89913
90103
|
throw NotImplementedException("Specifier type not implemented for DATETRUNC");
|
|
@@ -90838,14 +91028,20 @@ static void StrfTimeFunctionDate(DataChunk &args, ExpressionState &state, Vector
|
|
|
90838
91028
|
ConstantVector::SetNull(result, true);
|
|
90839
91029
|
return;
|
|
90840
91030
|
}
|
|
90841
|
-
UnaryExecutor::
|
|
90842
|
-
|
|
90843
|
-
|
|
90844
|
-
|
|
90845
|
-
|
|
90846
|
-
|
|
90847
|
-
|
|
90848
|
-
|
|
91031
|
+
UnaryExecutor::ExecuteWithNulls<date_t, string_t>(
|
|
91032
|
+
args.data[REVERSED ? 1 : 0], result, args.size(), [&](date_t input, ValidityMask &mask, idx_t idx) {
|
|
91033
|
+
if (Date::IsFinite(input)) {
|
|
91034
|
+
dtime_t time(0);
|
|
91035
|
+
idx_t len = info.format.GetLength(input, time, 0, nullptr);
|
|
91036
|
+
string_t target = StringVector::EmptyString(result, len);
|
|
91037
|
+
info.format.FormatString(input, time, target.GetDataWriteable());
|
|
91038
|
+
target.Finalize();
|
|
91039
|
+
return target;
|
|
91040
|
+
} else {
|
|
91041
|
+
mask.SetInvalid(idx);
|
|
91042
|
+
return string_t();
|
|
91043
|
+
}
|
|
91044
|
+
});
|
|
90849
91045
|
}
|
|
90850
91046
|
|
|
90851
91047
|
template <bool REVERSED>
|
|
@@ -90859,17 +91055,22 @@ static void StrfTimeFunctionTimestamp(DataChunk &args, ExpressionState &state, V
|
|
|
90859
91055
|
return;
|
|
90860
91056
|
}
|
|
90861
91057
|
|
|
90862
|
-
UnaryExecutor::
|
|
90863
|
-
|
|
90864
|
-
|
|
90865
|
-
|
|
90866
|
-
|
|
90867
|
-
|
|
90868
|
-
|
|
90869
|
-
|
|
90870
|
-
|
|
90871
|
-
|
|
90872
|
-
|
|
91058
|
+
UnaryExecutor::ExecuteWithNulls<timestamp_t, string_t>(
|
|
91059
|
+
args.data[REVERSED ? 1 : 0], result, args.size(), [&](timestamp_t input, ValidityMask &mask, idx_t idx) {
|
|
91060
|
+
if (Timestamp::IsFinite(input)) {
|
|
91061
|
+
date_t date;
|
|
91062
|
+
dtime_t time;
|
|
91063
|
+
Timestamp::Convert(input, date, time);
|
|
91064
|
+
idx_t len = info.format.GetLength(date, time, 0, nullptr);
|
|
91065
|
+
string_t target = StringVector::EmptyString(result, len);
|
|
91066
|
+
info.format.FormatString(date, time, target.GetDataWriteable());
|
|
91067
|
+
target.Finalize();
|
|
91068
|
+
return target;
|
|
91069
|
+
} else {
|
|
91070
|
+
mask.SetInvalid(idx);
|
|
91071
|
+
return string_t();
|
|
91072
|
+
}
|
|
91073
|
+
});
|
|
90873
91074
|
}
|
|
90874
91075
|
|
|
90875
91076
|
void StrfTimeFun::RegisterFunction(BuiltinFunctions &set) {
|
|
@@ -94202,6 +94403,7 @@ void ListValueFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
94202
94403
|
|
|
94203
94404
|
|
|
94204
94405
|
|
|
94406
|
+
|
|
94205
94407
|
namespace duckdb {
|
|
94206
94408
|
|
|
94207
94409
|
struct NumericRangeInfo {
|
|
@@ -94260,6 +94462,11 @@ struct TimestampRangeInfo {
|
|
|
94260
94462
|
// interval is 0: no result
|
|
94261
94463
|
return 0;
|
|
94262
94464
|
}
|
|
94465
|
+
// We don't allow infinite bounds because they generate errors or infinite loops
|
|
94466
|
+
if (!Timestamp::IsFinite(start_value) || !Timestamp::IsFinite(end_value)) {
|
|
94467
|
+
throw InvalidInputException("Interval infinite bounds not supported");
|
|
94468
|
+
}
|
|
94469
|
+
|
|
94263
94470
|
if (is_negative && is_positive) {
|
|
94264
94471
|
// we don't allow a mix of
|
|
94265
94472
|
throw InvalidInputException("Interval with mix of negative/positive entries not supported");
|
|
@@ -96178,11 +96385,18 @@ interval_t AddOperator::Operation(interval_t left, interval_t right) {
|
|
|
96178
96385
|
|
|
96179
96386
|
template <>
|
|
96180
96387
|
date_t AddOperator::Operation(date_t left, int32_t right) {
|
|
96181
|
-
|
|
96182
|
-
|
|
96388
|
+
if (!Value::IsFinite(left)) {
|
|
96389
|
+
return left;
|
|
96390
|
+
}
|
|
96391
|
+
int32_t days;
|
|
96392
|
+
if (!TryAddOperator::Operation(left.days, right, days)) {
|
|
96393
|
+
throw OutOfRangeException("Date out of range");
|
|
96394
|
+
}
|
|
96395
|
+
date_t result(days);
|
|
96396
|
+
if (!Value::IsFinite(result)) {
|
|
96183
96397
|
throw OutOfRangeException("Date out of range");
|
|
96184
96398
|
}
|
|
96185
|
-
return
|
|
96399
|
+
return result;
|
|
96186
96400
|
}
|
|
96187
96401
|
|
|
96188
96402
|
template <>
|
|
@@ -96192,6 +96406,11 @@ date_t AddOperator::Operation(int32_t left, date_t right) {
|
|
|
96192
96406
|
|
|
96193
96407
|
template <>
|
|
96194
96408
|
timestamp_t AddOperator::Operation(date_t left, dtime_t right) {
|
|
96409
|
+
if (left == date_t::infinity()) {
|
|
96410
|
+
return timestamp_t::infinity();
|
|
96411
|
+
} else if (left == date_t::ninfinity()) {
|
|
96412
|
+
return timestamp_t::ninfinity();
|
|
96413
|
+
}
|
|
96195
96414
|
timestamp_t result;
|
|
96196
96415
|
if (!Timestamp::TryFromDatetime(left, right, result)) {
|
|
96197
96416
|
throw OutOfRangeException("Timestamp out of range");
|
|
@@ -97750,6 +97969,7 @@ hugeint_t DecimalMultiplyOverflowCheck::Operation(hugeint_t left, hugeint_t righ
|
|
|
97750
97969
|
|
|
97751
97970
|
|
|
97752
97971
|
|
|
97972
|
+
|
|
97753
97973
|
#include <limits>
|
|
97754
97974
|
|
|
97755
97975
|
namespace duckdb {
|
|
@@ -97782,11 +98002,19 @@ int64_t SubtractOperator::Operation(date_t left, date_t right) {
|
|
|
97782
98002
|
|
|
97783
98003
|
template <>
|
|
97784
98004
|
date_t SubtractOperator::Operation(date_t left, int32_t right) {
|
|
97785
|
-
|
|
97786
|
-
|
|
98005
|
+
if (!Date::IsFinite(left)) {
|
|
98006
|
+
return left;
|
|
98007
|
+
}
|
|
98008
|
+
int32_t days;
|
|
98009
|
+
if (!TrySubtractOperator::Operation(left.days, right, days)) {
|
|
97787
98010
|
throw OutOfRangeException("Date out of range");
|
|
97788
98011
|
}
|
|
97789
|
-
|
|
98012
|
+
|
|
98013
|
+
date_t result(days);
|
|
98014
|
+
if (!Date::IsFinite(result)) {
|
|
98015
|
+
throw OutOfRangeException("Date out of range");
|
|
98016
|
+
}
|
|
98017
|
+
return result;
|
|
97790
98018
|
}
|
|
97791
98019
|
|
|
97792
98020
|
template <>
|
|
@@ -104810,6 +105038,7 @@ struct SummaryTableFunction {
|
|
|
104810
105038
|
|
|
104811
105039
|
|
|
104812
105040
|
|
|
105041
|
+
|
|
104813
105042
|
namespace duckdb {
|
|
104814
105043
|
|
|
104815
105044
|
//===--------------------------------------------------------------------===//
|
|
@@ -104954,6 +105183,11 @@ static unique_ptr<FunctionData> RangeDateTimeBind(ClientContext &context, TableF
|
|
|
104954
105183
|
result->end = inputs[1].GetValue<timestamp_t>();
|
|
104955
105184
|
result->increment = inputs[2].GetValue<interval_t>();
|
|
104956
105185
|
|
|
105186
|
+
// Infinities either cause errors or infinite loops, so just ban them
|
|
105187
|
+
if (!Timestamp::IsFinite(result->start) || !Timestamp::IsFinite(result->end)) {
|
|
105188
|
+
throw BinderException("RANGE with infinite bounds is not supported");
|
|
105189
|
+
}
|
|
105190
|
+
|
|
104957
105191
|
if (result->increment.months == 0 && result->increment.days == 0 && result->increment.micros == 0) {
|
|
104958
105192
|
throw BinderException("interval cannot be 0!");
|
|
104959
105193
|
}
|
|
@@ -108125,6 +108359,8 @@ void PragmaTableInfo::RegisterFunction(BuiltinFunctions &set) {
|
|
|
108125
108359
|
} // namespace duckdb
|
|
108126
108360
|
|
|
108127
108361
|
|
|
108362
|
+
|
|
108363
|
+
|
|
108128
108364
|
#include <cmath>
|
|
108129
108365
|
#include <limits>
|
|
108130
108366
|
|
|
@@ -108236,6 +108472,27 @@ static vector<TestType> GetTestTypes() {
|
|
|
108236
108472
|
Value::DOUBLE(-std::numeric_limits<double>::infinity()), Value(LogicalType::DOUBLE), Value::DOUBLE(-42)});
|
|
108237
108473
|
result.emplace_back(double_list_type, "double_array", empty_double_list, double_list);
|
|
108238
108474
|
|
|
108475
|
+
auto date_list_type = LogicalType::LIST(LogicalType::DATE);
|
|
108476
|
+
auto empty_date_list = Value::EMPTYLIST(LogicalType::DATE);
|
|
108477
|
+
auto date_list =
|
|
108478
|
+
Value::LIST({Value::DATE(date_t()), Value::DATE(date_t::infinity()), Value::DATE(date_t::ninfinity()),
|
|
108479
|
+
Value(LogicalType::DATE), Value::DATE(Date::FromString("2022-05-12"))});
|
|
108480
|
+
result.emplace_back(date_list_type, "date_array", empty_date_list, date_list);
|
|
108481
|
+
|
|
108482
|
+
auto timestamp_list_type = LogicalType::LIST(LogicalType::TIMESTAMP);
|
|
108483
|
+
auto empty_timestamp_list = Value::EMPTYLIST(LogicalType::TIMESTAMP);
|
|
108484
|
+
auto timestamp_list = Value::LIST({Value::TIMESTAMP(timestamp_t()), Value::TIMESTAMP(timestamp_t::infinity()),
|
|
108485
|
+
Value::TIMESTAMP(timestamp_t::ninfinity()), Value(LogicalType::TIMESTAMP),
|
|
108486
|
+
Value::TIMESTAMP(Timestamp::FromString("2022-05-12 16:23:45"))});
|
|
108487
|
+
result.emplace_back(timestamp_list_type, "timestamp_array", empty_timestamp_list, timestamp_list);
|
|
108488
|
+
|
|
108489
|
+
auto timestamptz_list_type = LogicalType::LIST(LogicalType::TIMESTAMP_TZ);
|
|
108490
|
+
auto empty_timestamptz_list = Value::EMPTYLIST(LogicalType::TIMESTAMP_TZ);
|
|
108491
|
+
auto timestamptz_list = Value::LIST({Value::TIMESTAMPTZ(timestamp_t()), Value::TIMESTAMPTZ(timestamp_t::infinity()),
|
|
108492
|
+
Value::TIMESTAMPTZ(timestamp_t::ninfinity()), Value(LogicalType::TIMESTAMP_TZ),
|
|
108493
|
+
Value::TIMESTAMPTZ(Timestamp::FromString("2022-05-12 16:23:45-07"))});
|
|
108494
|
+
result.emplace_back(timestamptz_list_type, "timestamptz_array", empty_timestamptz_list, timestamptz_list);
|
|
108495
|
+
|
|
108239
108496
|
auto varchar_list_type = LogicalType::LIST(LogicalType::VARCHAR);
|
|
108240
108497
|
auto empty_varchar_list = Value::EMPTYLIST(LogicalType::VARCHAR);
|
|
108241
108498
|
auto varchar_list =
|