duckdb 0.3.3-dev1321.0 → 0.3.3-dev1371.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 +522 -177
- package/src/duckdb.hpp +48 -15
- package/src/parquet-amalgamation.cpp +31223 -31223
package/src/duckdb.cpp
CHANGED
|
@@ -4681,7 +4681,44 @@ static DefaultMacro internal_macros[] = {
|
|
|
4681
4681
|
{DEFAULT_SCHEMA, "generate_subscripts", {"arr", "dim", nullptr}, "unnest(generate_series(1, array_length(arr, dim)))"},
|
|
4682
4682
|
{DEFAULT_SCHEMA, "fdiv", {"x", "y", nullptr}, "floor(x/y)"},
|
|
4683
4683
|
{DEFAULT_SCHEMA, "fmod", {"x", "y", nullptr}, "(x-y*floor(x/y))"},
|
|
4684
|
-
|
|
4684
|
+
|
|
4685
|
+
// algebraic list aggregates
|
|
4686
|
+
{DEFAULT_SCHEMA, "list_avg", {"l", nullptr}, "list_aggr(l, 'avg')"},
|
|
4687
|
+
{DEFAULT_SCHEMA, "list_var_samp", {"l", nullptr}, "list_aggr(l, 'var_samp')"},
|
|
4688
|
+
{DEFAULT_SCHEMA, "list_var_pop", {"l", nullptr}, "list_aggr(l, 'var_pop')"},
|
|
4689
|
+
{DEFAULT_SCHEMA, "list_stddev_pop", {"l", nullptr}, "list_aggr(l, 'stddev_pop')"},
|
|
4690
|
+
{DEFAULT_SCHEMA, "list_stddev_samp", {"l", nullptr}, "list_aggr(l, 'stddev_samp')"},
|
|
4691
|
+
{DEFAULT_SCHEMA, "list_sem", {"l", nullptr}, "list_aggr(l, 'sem')"},
|
|
4692
|
+
|
|
4693
|
+
// distributive list aggregates
|
|
4694
|
+
{DEFAULT_SCHEMA, "list_approx_count_distinct", {"l", nullptr}, "list_aggr(l, 'approx_count_distinct')"},
|
|
4695
|
+
{DEFAULT_SCHEMA, "list_bit_xor", {"l", nullptr}, "list_aggr(l, 'bit_xor')"},
|
|
4696
|
+
{DEFAULT_SCHEMA, "list_bit_or", {"l", nullptr}, "list_aggr(l, 'bit_or')"},
|
|
4697
|
+
{DEFAULT_SCHEMA, "list_bit_and", {"l", nullptr}, "list_aggr(l, 'bit_and')"},
|
|
4698
|
+
{DEFAULT_SCHEMA, "list_bool_and", {"l", nullptr}, "list_aggr(l, 'bool_and')"},
|
|
4699
|
+
{DEFAULT_SCHEMA, "list_bool_or", {"l", nullptr}, "list_aggr(l, 'bool_or')"},
|
|
4700
|
+
{DEFAULT_SCHEMA, "list_count", {"l", nullptr}, "list_aggr(l, 'count')"},
|
|
4701
|
+
{DEFAULT_SCHEMA, "list_entropy", {"l", nullptr}, "list_aggr(l, 'entropy')"},
|
|
4702
|
+
{DEFAULT_SCHEMA, "list_last", {"l", nullptr}, "list_aggr(l, 'last')"},
|
|
4703
|
+
{DEFAULT_SCHEMA, "list_first", {"l", nullptr}, "list_aggr(l, 'first')"},
|
|
4704
|
+
{DEFAULT_SCHEMA, "list_kurtosis", {"l", nullptr}, "list_aggr(l, 'kurtosis')"},
|
|
4705
|
+
{DEFAULT_SCHEMA, "list_min", {"l", nullptr}, "list_aggr(l, 'min')"},
|
|
4706
|
+
{DEFAULT_SCHEMA, "list_max", {"l", nullptr}, "list_aggr(l, 'max')"},
|
|
4707
|
+
{DEFAULT_SCHEMA, "list_product", {"l", nullptr}, "list_aggr(l, 'product')"},
|
|
4708
|
+
{DEFAULT_SCHEMA, "list_skewness", {"l", nullptr}, "list_aggr(l, 'skewness')"},
|
|
4709
|
+
{DEFAULT_SCHEMA, "list_sum", {"l", nullptr}, "list_aggr(l, 'sum')"},
|
|
4710
|
+
{DEFAULT_SCHEMA, "list_string_agg", {"l", nullptr}, "list_aggr(l, 'string_agg')"},
|
|
4711
|
+
|
|
4712
|
+
// holistic list aggregates
|
|
4713
|
+
{DEFAULT_SCHEMA, "list_mode", {"l", nullptr}, "list_aggr(l, 'mode')"},
|
|
4714
|
+
{DEFAULT_SCHEMA, "list_median", {"l", nullptr}, "list_aggr(l, 'median')"},
|
|
4715
|
+
{DEFAULT_SCHEMA, "list_mad", {"l", nullptr}, "list_aggr(l, 'mad')"},
|
|
4716
|
+
|
|
4717
|
+
// nested list aggregates
|
|
4718
|
+
{DEFAULT_SCHEMA, "list_histogram", {"l", nullptr}, "list_aggr(l, 'histogram')"},
|
|
4719
|
+
|
|
4720
|
+
{nullptr, nullptr, {nullptr}, nullptr}
|
|
4721
|
+
};
|
|
4685
4722
|
|
|
4686
4723
|
unique_ptr<CreateMacroInfo> DefaultFunctionGenerator::CreateInternalMacroInfo(DefaultMacro &default_macro) {
|
|
4687
4724
|
// parse the expression
|
|
@@ -26480,6 +26517,7 @@ static void TemplatedMatch(DataChunk &columns, VectorData col_data[], const RowL
|
|
|
26480
26517
|
switch (predicates[col_no]) {
|
|
26481
26518
|
case ExpressionType::COMPARE_EQUAL:
|
|
26482
26519
|
case ExpressionType::COMPARE_NOT_DISTINCT_FROM:
|
|
26520
|
+
case ExpressionType::COMPARE_DISTINCT_FROM:
|
|
26483
26521
|
TemplatedMatchOp<Equals, NO_MATCH_SEL>(vec, col, layout, rows, sel, count, col_no, no_match,
|
|
26484
26522
|
no_match_count);
|
|
26485
26523
|
break;
|
|
@@ -47487,7 +47525,7 @@ namespace duckdb {
|
|
|
47487
47525
|
//! JoinCondition represents a left-right comparison join condition
|
|
47488
47526
|
struct JoinCondition {
|
|
47489
47527
|
public:
|
|
47490
|
-
JoinCondition()
|
|
47528
|
+
JoinCondition() {
|
|
47491
47529
|
}
|
|
47492
47530
|
|
|
47493
47531
|
//! Turns the JoinCondition into an expression; note that this destroys the JoinCondition as the expression inherits
|
|
@@ -47498,17 +47536,14 @@ public:
|
|
|
47498
47536
|
unique_ptr<Expression> left;
|
|
47499
47537
|
unique_ptr<Expression> right;
|
|
47500
47538
|
ExpressionType comparison;
|
|
47501
|
-
//! NULL values are equal for just THIS JoinCondition (instead of the entire join).
|
|
47502
|
-
//! This is only supported by the HashJoin and can only be used in equality comparisons.
|
|
47503
|
-
bool null_values_are_equal = false;
|
|
47504
47539
|
};
|
|
47505
47540
|
|
|
47506
47541
|
class JoinSide {
|
|
47507
47542
|
public:
|
|
47508
|
-
enum
|
|
47543
|
+
enum JoinValue : uint8_t { NONE, LEFT, RIGHT, BOTH };
|
|
47509
47544
|
|
|
47510
47545
|
JoinSide() = default;
|
|
47511
|
-
constexpr JoinSide(
|
|
47546
|
+
constexpr JoinSide(JoinValue val) : value(val) { // NOLINT: Allow implicit conversion from `join_value`
|
|
47512
47547
|
}
|
|
47513
47548
|
|
|
47514
47549
|
bool operator==(JoinSide a) const {
|
|
@@ -47527,7 +47562,7 @@ public:
|
|
|
47527
47562
|
unordered_set<idx_t> &right_bindings);
|
|
47528
47563
|
|
|
47529
47564
|
private:
|
|
47530
|
-
|
|
47565
|
+
JoinValue value;
|
|
47531
47566
|
};
|
|
47532
47567
|
|
|
47533
47568
|
} // namespace duckdb
|
|
@@ -50935,7 +50970,8 @@ JoinHashTable::JoinHashTable(BufferManager &buffer_manager, const vector<JoinCon
|
|
|
50935
50970
|
D_ASSERT(condition.left->return_type == condition.right->return_type);
|
|
50936
50971
|
auto type = condition.left->return_type;
|
|
50937
50972
|
if (condition.comparison == ExpressionType::COMPARE_EQUAL ||
|
|
50938
|
-
condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM
|
|
50973
|
+
condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM ||
|
|
50974
|
+
condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM) {
|
|
50939
50975
|
// all equality conditions should be at the front
|
|
50940
50976
|
// all other conditions at the back
|
|
50941
50977
|
// this assert checks that
|
|
@@ -50944,10 +50980,8 @@ JoinHashTable::JoinHashTable(BufferManager &buffer_manager, const vector<JoinCon
|
|
|
50944
50980
|
}
|
|
50945
50981
|
|
|
50946
50982
|
predicates.push_back(condition.comparison);
|
|
50947
|
-
null_values_are_equal.push_back(condition.
|
|
50983
|
+
null_values_are_equal.push_back(condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM ||
|
|
50948
50984
|
condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM);
|
|
50949
|
-
D_ASSERT(!condition.null_values_are_equal ||
|
|
50950
|
-
(condition.null_values_are_equal && condition.comparison == ExpressionType::COMPARE_EQUAL));
|
|
50951
50985
|
|
|
50952
50986
|
condition_types.push_back(type);
|
|
50953
50987
|
}
|
|
@@ -68019,7 +68053,7 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
|
|
|
68019
68053
|
}
|
|
68020
68054
|
// with equality condition and null values not equal
|
|
68021
68055
|
for (auto &&condition : op.conditions) {
|
|
68022
|
-
if (condition.comparison != ExpressionType::COMPARE_EQUAL
|
|
68056
|
+
if (condition.comparison != ExpressionType::COMPARE_EQUAL) {
|
|
68023
68057
|
return;
|
|
68024
68058
|
}
|
|
68025
68059
|
}
|
|
@@ -68140,10 +68174,6 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalComparison
|
|
|
68140
68174
|
default:
|
|
68141
68175
|
throw NotImplementedException("Unimplemented comparison join");
|
|
68142
68176
|
}
|
|
68143
|
-
if (cond.null_values_are_equal) {
|
|
68144
|
-
D_ASSERT(cond.comparison == ExpressionType::COMPARE_EQUAL ||
|
|
68145
|
-
cond.comparison == ExpressionType::COMPARE_DISTINCT_FROM);
|
|
68146
|
-
}
|
|
68147
68177
|
}
|
|
68148
68178
|
|
|
68149
68179
|
unique_ptr<PhysicalOperator> plan;
|
|
@@ -70555,10 +70585,9 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalSetOperati
|
|
|
70555
70585
|
// create equality condition for all columns
|
|
70556
70586
|
for (idx_t i = 0; i < types.size(); i++) {
|
|
70557
70587
|
JoinCondition cond;
|
|
70558
|
-
cond.comparison = ExpressionType::COMPARE_EQUAL;
|
|
70559
70588
|
cond.left = make_unique<BoundReferenceExpression>(types[i], i);
|
|
70560
70589
|
cond.right = make_unique<BoundReferenceExpression>(types[i], i);
|
|
70561
|
-
cond.
|
|
70590
|
+
cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
|
|
70562
70591
|
conditions.push_back(move(cond));
|
|
70563
70592
|
}
|
|
70564
70593
|
// EXCEPT is ANTI join
|
|
@@ -72448,22 +72477,22 @@ AggregateFunction GetAverageAggregate(PhysicalType type) {
|
|
|
72448
72477
|
switch (type) {
|
|
72449
72478
|
case PhysicalType::INT16:
|
|
72450
72479
|
return AggregateFunction::UnaryAggregate<AvgState<int64_t>, int16_t, double, IntegerAverageOperation>(
|
|
72451
|
-
LogicalType::SMALLINT, LogicalType::DOUBLE);
|
|
72480
|
+
LogicalType::SMALLINT, LogicalType::DOUBLE, true);
|
|
72452
72481
|
case PhysicalType::INT32: {
|
|
72453
72482
|
auto function =
|
|
72454
72483
|
AggregateFunction::UnaryAggregate<AvgState<hugeint_t>, int32_t, double, IntegerAverageOperationHugeint>(
|
|
72455
|
-
LogicalType::INTEGER, LogicalType::DOUBLE);
|
|
72484
|
+
LogicalType::INTEGER, LogicalType::DOUBLE, true);
|
|
72456
72485
|
return function;
|
|
72457
72486
|
}
|
|
72458
72487
|
case PhysicalType::INT64: {
|
|
72459
72488
|
auto function =
|
|
72460
72489
|
AggregateFunction::UnaryAggregate<AvgState<hugeint_t>, int64_t, double, IntegerAverageOperationHugeint>(
|
|
72461
|
-
LogicalType::BIGINT, LogicalType::DOUBLE);
|
|
72490
|
+
LogicalType::BIGINT, LogicalType::DOUBLE, true);
|
|
72462
72491
|
return function;
|
|
72463
72492
|
}
|
|
72464
72493
|
case PhysicalType::INT128:
|
|
72465
72494
|
return AggregateFunction::UnaryAggregate<AvgState<hugeint_t>, hugeint_t, double, HugeintAverageOperation>(
|
|
72466
|
-
LogicalType::HUGEINT, LogicalType::DOUBLE);
|
|
72495
|
+
LogicalType::HUGEINT, LogicalType::DOUBLE, true);
|
|
72467
72496
|
default:
|
|
72468
72497
|
throw InternalException("Unimplemented average aggregate");
|
|
72469
72498
|
}
|
|
@@ -72483,18 +72512,18 @@ unique_ptr<FunctionData> BindDecimalAvg(ClientContext &context, AggregateFunctio
|
|
|
72483
72512
|
void AvgFun::RegisterFunction(BuiltinFunctions &set) {
|
|
72484
72513
|
AggregateFunctionSet avg("avg");
|
|
72485
72514
|
avg.AddFunction(AggregateFunction({LogicalTypeId::DECIMAL}, LogicalTypeId::DECIMAL, nullptr, nullptr, nullptr,
|
|
72486
|
-
nullptr, nullptr, nullptr, BindDecimalAvg));
|
|
72515
|
+
nullptr, nullptr, true, nullptr, BindDecimalAvg));
|
|
72487
72516
|
avg.AddFunction(GetAverageAggregate(PhysicalType::INT16));
|
|
72488
72517
|
avg.AddFunction(GetAverageAggregate(PhysicalType::INT32));
|
|
72489
72518
|
avg.AddFunction(GetAverageAggregate(PhysicalType::INT64));
|
|
72490
72519
|
avg.AddFunction(GetAverageAggregate(PhysicalType::INT128));
|
|
72491
72520
|
avg.AddFunction(AggregateFunction::UnaryAggregate<AvgState<double>, double, double, NumericAverageOperation>(
|
|
72492
|
-
LogicalType::DOUBLE, LogicalType::DOUBLE));
|
|
72521
|
+
LogicalType::DOUBLE, LogicalType::DOUBLE, true));
|
|
72493
72522
|
set.AddFunction(avg);
|
|
72494
72523
|
|
|
72495
72524
|
AggregateFunctionSet favg("favg");
|
|
72496
72525
|
favg.AddFunction(AggregateFunction::UnaryAggregate<KahanAvgState, double, double, KahanAverageOperation>(
|
|
72497
|
-
LogicalType::DOUBLE, LogicalType::DOUBLE));
|
|
72526
|
+
LogicalType::DOUBLE, LogicalType::DOUBLE, true));
|
|
72498
72527
|
set.AddFunction(favg);
|
|
72499
72528
|
}
|
|
72500
72529
|
|
|
@@ -74423,24 +74452,24 @@ static AggregateFunction GetUnaryAggregate(LogicalType type) {
|
|
|
74423
74452
|
case LogicalTypeId::TIMESTAMP_TZ:
|
|
74424
74453
|
case LogicalTypeId::TIME_TZ:
|
|
74425
74454
|
case LogicalTypeId::BIGINT:
|
|
74426
|
-
return AggregateFunction::UnaryAggregate<MinMaxState<int64_t>, int64_t, int64_t, OP>(type, type);
|
|
74455
|
+
return AggregateFunction::UnaryAggregate<MinMaxState<int64_t>, int64_t, int64_t, OP>(type, type, true);
|
|
74427
74456
|
case LogicalTypeId::UTINYINT:
|
|
74428
|
-
return AggregateFunction::UnaryAggregate<MinMaxState<uint8_t>, uint8_t, uint8_t, OP>(type, type);
|
|
74457
|
+
return AggregateFunction::UnaryAggregate<MinMaxState<uint8_t>, uint8_t, uint8_t, OP>(type, type, true);
|
|
74429
74458
|
case LogicalTypeId::USMALLINT:
|
|
74430
|
-
return AggregateFunction::UnaryAggregate<MinMaxState<uint16_t>, uint16_t, uint16_t, OP>(type, type);
|
|
74459
|
+
return AggregateFunction::UnaryAggregate<MinMaxState<uint16_t>, uint16_t, uint16_t, OP>(type, type, true);
|
|
74431
74460
|
case LogicalTypeId::UINTEGER:
|
|
74432
|
-
return AggregateFunction::UnaryAggregate<MinMaxState<uint32_t>, uint32_t, uint32_t, OP>(type, type);
|
|
74461
|
+
return AggregateFunction::UnaryAggregate<MinMaxState<uint32_t>, uint32_t, uint32_t, OP>(type, type, true);
|
|
74433
74462
|
case LogicalTypeId::UBIGINT:
|
|
74434
|
-
return AggregateFunction::UnaryAggregate<MinMaxState<uint64_t>, uint64_t, uint64_t, OP>(type, type);
|
|
74463
|
+
return AggregateFunction::UnaryAggregate<MinMaxState<uint64_t>, uint64_t, uint64_t, OP>(type, type, true);
|
|
74435
74464
|
case LogicalTypeId::HUGEINT:
|
|
74436
74465
|
case LogicalTypeId::UUID:
|
|
74437
|
-
return AggregateFunction::UnaryAggregate<MinMaxState<hugeint_t>, hugeint_t, hugeint_t, OP>(type, type);
|
|
74466
|
+
return AggregateFunction::UnaryAggregate<MinMaxState<hugeint_t>, hugeint_t, hugeint_t, OP>(type, type, true);
|
|
74438
74467
|
case LogicalTypeId::FLOAT:
|
|
74439
|
-
return AggregateFunction::UnaryAggregate<MinMaxState<float>, float, float, OP>(type, type);
|
|
74468
|
+
return AggregateFunction::UnaryAggregate<MinMaxState<float>, float, float, OP>(type, type, true);
|
|
74440
74469
|
case LogicalTypeId::DOUBLE:
|
|
74441
|
-
return AggregateFunction::UnaryAggregate<MinMaxState<double>, double, double, OP>(type, type);
|
|
74470
|
+
return AggregateFunction::UnaryAggregate<MinMaxState<double>, double, double, OP>(type, type, true);
|
|
74442
74471
|
case LogicalTypeId::INTERVAL:
|
|
74443
|
-
return AggregateFunction::UnaryAggregate<MinMaxState<interval_t>, interval_t, interval_t, OP>(type, type);
|
|
74472
|
+
return AggregateFunction::UnaryAggregate<MinMaxState<interval_t>, interval_t, interval_t, OP>(type, type, true);
|
|
74444
74473
|
default:
|
|
74445
74474
|
throw InternalException("Unimplemented type for min/max aggregate");
|
|
74446
74475
|
}
|
|
@@ -74921,7 +74950,7 @@ static void AddMinMaxOperator(AggregateFunctionSet &set) {
|
|
|
74921
74950
|
AggregateFunction::UnaryAggregateDestructor<MinMaxState<string_t>, string_t, string_t, OP_STRING>(
|
|
74922
74951
|
type.id(), type.id()));
|
|
74923
74952
|
} else if (type.id() == LogicalTypeId::DECIMAL) {
|
|
74924
|
-
set.AddFunction(AggregateFunction({type}, type, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
74953
|
+
set.AddFunction(AggregateFunction({type}, type, nullptr, nullptr, nullptr, nullptr, nullptr, false, nullptr,
|
|
74925
74954
|
BindDecimalMinMax<OP>));
|
|
74926
74955
|
} else if (type.id() == LogicalTypeId::LIST || type.id() == LogicalTypeId::MAP ||
|
|
74927
74956
|
type.id() == LogicalTypeId::STRUCT) {
|
|
@@ -75350,13 +75379,13 @@ unique_ptr<BaseStatistics> SumPropagateStats(ClientContext &context, BoundAggreg
|
|
|
75350
75379
|
case PhysicalType::INT32:
|
|
75351
75380
|
expr.function =
|
|
75352
75381
|
AggregateFunction::UnaryAggregate<SumState<int64_t>, int32_t, hugeint_t, IntegerSumOperation>(
|
|
75353
|
-
LogicalType::INTEGER, LogicalType::HUGEINT);
|
|
75382
|
+
LogicalType::INTEGER, LogicalType::HUGEINT, true);
|
|
75354
75383
|
expr.function.name = "sum";
|
|
75355
75384
|
break;
|
|
75356
75385
|
case PhysicalType::INT64:
|
|
75357
75386
|
expr.function =
|
|
75358
75387
|
AggregateFunction::UnaryAggregate<SumState<int64_t>, int64_t, hugeint_t, IntegerSumOperation>(
|
|
75359
|
-
LogicalType::BIGINT, LogicalType::HUGEINT);
|
|
75388
|
+
LogicalType::BIGINT, LogicalType::HUGEINT, true);
|
|
75360
75389
|
expr.function.name = "sum";
|
|
75361
75390
|
break;
|
|
75362
75391
|
default:
|
|
@@ -75370,24 +75399,24 @@ AggregateFunction SumFun::GetSumAggregate(PhysicalType type) {
|
|
|
75370
75399
|
switch (type) {
|
|
75371
75400
|
case PhysicalType::INT16:
|
|
75372
75401
|
return AggregateFunction::UnaryAggregate<SumState<int64_t>, int16_t, hugeint_t, IntegerSumOperation>(
|
|
75373
|
-
LogicalType::SMALLINT, LogicalType::HUGEINT);
|
|
75402
|
+
LogicalType::SMALLINT, LogicalType::HUGEINT, true);
|
|
75374
75403
|
case PhysicalType::INT32: {
|
|
75375
75404
|
auto function =
|
|
75376
75405
|
AggregateFunction::UnaryAggregate<SumState<hugeint_t>, int32_t, hugeint_t, SumToHugeintOperation>(
|
|
75377
|
-
LogicalType::INTEGER, LogicalType::HUGEINT);
|
|
75406
|
+
LogicalType::INTEGER, LogicalType::HUGEINT, true);
|
|
75378
75407
|
function.statistics = SumPropagateStats;
|
|
75379
75408
|
return function;
|
|
75380
75409
|
}
|
|
75381
75410
|
case PhysicalType::INT64: {
|
|
75382
75411
|
auto function =
|
|
75383
75412
|
AggregateFunction::UnaryAggregate<SumState<hugeint_t>, int64_t, hugeint_t, SumToHugeintOperation>(
|
|
75384
|
-
LogicalType::BIGINT, LogicalType::HUGEINT);
|
|
75413
|
+
LogicalType::BIGINT, LogicalType::HUGEINT, true);
|
|
75385
75414
|
function.statistics = SumPropagateStats;
|
|
75386
75415
|
return function;
|
|
75387
75416
|
}
|
|
75388
75417
|
case PhysicalType::INT128:
|
|
75389
75418
|
return AggregateFunction::UnaryAggregate<SumState<hugeint_t>, hugeint_t, hugeint_t, HugeintSumOperation>(
|
|
75390
|
-
LogicalType::HUGEINT, LogicalType::HUGEINT);
|
|
75419
|
+
LogicalType::HUGEINT, LogicalType::HUGEINT, true);
|
|
75391
75420
|
default:
|
|
75392
75421
|
throw InternalException("Unimplemented sum aggregate");
|
|
75393
75422
|
}
|
|
@@ -75407,20 +75436,20 @@ void SumFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
75407
75436
|
AggregateFunctionSet sum("sum");
|
|
75408
75437
|
// decimal
|
|
75409
75438
|
sum.AddFunction(AggregateFunction({LogicalTypeId::DECIMAL}, LogicalTypeId::DECIMAL, nullptr, nullptr, nullptr,
|
|
75410
|
-
nullptr, nullptr, nullptr, BindDecimalSum));
|
|
75439
|
+
nullptr, nullptr, true, nullptr, BindDecimalSum));
|
|
75411
75440
|
sum.AddFunction(GetSumAggregate(PhysicalType::INT16));
|
|
75412
75441
|
sum.AddFunction(GetSumAggregate(PhysicalType::INT32));
|
|
75413
75442
|
sum.AddFunction(GetSumAggregate(PhysicalType::INT64));
|
|
75414
75443
|
sum.AddFunction(GetSumAggregate(PhysicalType::INT128));
|
|
75415
75444
|
sum.AddFunction(AggregateFunction::UnaryAggregate<SumState<double>, double, double, NumericSumOperation>(
|
|
75416
|
-
LogicalType::DOUBLE, LogicalType::DOUBLE));
|
|
75445
|
+
LogicalType::DOUBLE, LogicalType::DOUBLE, true));
|
|
75417
75446
|
|
|
75418
75447
|
set.AddFunction(sum);
|
|
75419
75448
|
|
|
75420
75449
|
// fsum
|
|
75421
75450
|
AggregateFunctionSet fsum("fsum");
|
|
75422
75451
|
fsum.AddFunction(AggregateFunction::UnaryAggregate<KahanSumState, double, double, KahanSumOperation>(
|
|
75423
|
-
LogicalType::DOUBLE, LogicalType::DOUBLE));
|
|
75452
|
+
LogicalType::DOUBLE, LogicalType::DOUBLE, true));
|
|
75424
75453
|
|
|
75425
75454
|
set.AddFunction(fsum);
|
|
75426
75455
|
|
|
@@ -78309,6 +78338,11 @@ struct ListPositionFun {
|
|
|
78309
78338
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
78310
78339
|
};
|
|
78311
78340
|
|
|
78341
|
+
struct ListAggregateFun {
|
|
78342
|
+
static ScalarFunction GetFunction();
|
|
78343
|
+
static void RegisterFunction(BuiltinFunctions &set);
|
|
78344
|
+
};
|
|
78345
|
+
|
|
78312
78346
|
struct CardinalityFun {
|
|
78313
78347
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
78314
78348
|
};
|
|
@@ -80080,9 +80114,9 @@ bool SimpleNamedParameterFunction::HasNamedParameters() {
|
|
|
80080
80114
|
}
|
|
80081
80115
|
|
|
80082
80116
|
BaseScalarFunction::BaseScalarFunction(string name_p, vector<LogicalType> arguments_p, LogicalType return_type_p,
|
|
80083
|
-
bool has_side_effects, LogicalType varargs_p)
|
|
80117
|
+
bool has_side_effects, LogicalType varargs_p, bool propagates_null_values_p)
|
|
80084
80118
|
: SimpleFunction(move(name_p), move(arguments_p), move(varargs_p)), return_type(move(return_type_p)),
|
|
80085
|
-
has_side_effects(has_side_effects) {
|
|
80119
|
+
has_side_effects(has_side_effects), propagates_null_values(propagates_null_values_p) {
|
|
80086
80120
|
}
|
|
80087
80121
|
|
|
80088
80122
|
BaseScalarFunction::~BaseScalarFunction() {
|
|
@@ -81150,8 +81184,8 @@ void CurrentDateFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
81150
81184
|
}
|
|
81151
81185
|
|
|
81152
81186
|
void CurrentTimestampFun::RegisterFunction(BuiltinFunctions &set) {
|
|
81153
|
-
set.AddFunction({"now", "current_timestamp"},
|
|
81154
|
-
|
|
81187
|
+
set.AddFunction({"now", "current_timestamp"}, ScalarFunction({}, LogicalType::TIMESTAMP, CurrentTimestampFunction,
|
|
81188
|
+
false, false, BindCurrentTime));
|
|
81155
81189
|
}
|
|
81156
81190
|
|
|
81157
81191
|
} // namespace duckdb
|
|
@@ -82798,9 +82832,9 @@ void AddGenericDatePartOperator(BuiltinFunctions &set, const string &name, scala
|
|
|
82798
82832
|
scalar_function_t ts_func, scalar_function_t interval_func,
|
|
82799
82833
|
function_statistics_t date_stats, function_statistics_t ts_stats) {
|
|
82800
82834
|
ScalarFunctionSet operator_set(name);
|
|
82801
|
-
operator_set.AddFunction(
|
|
82802
|
-
|
|
82803
|
-
operator_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), false,
|
|
82835
|
+
operator_set.AddFunction(ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, move(date_func), false, false,
|
|
82836
|
+
nullptr, nullptr, date_stats));
|
|
82837
|
+
operator_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), false, false,
|
|
82804
82838
|
nullptr, nullptr, ts_stats));
|
|
82805
82839
|
operator_set.AddFunction(ScalarFunction({LogicalType::INTERVAL}, LogicalType::BIGINT, move(interval_func)));
|
|
82806
82840
|
set.AddFunction(operator_set);
|
|
@@ -82819,13 +82853,13 @@ void AddGenericTimePartOperator(BuiltinFunctions &set, const string &name, scala
|
|
|
82819
82853
|
function_statistics_t date_stats, function_statistics_t ts_stats,
|
|
82820
82854
|
function_statistics_t time_stats) {
|
|
82821
82855
|
ScalarFunctionSet operator_set(name);
|
|
82822
|
-
operator_set.AddFunction(
|
|
82823
|
-
|
|
82824
|
-
operator_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), false,
|
|
82856
|
+
operator_set.AddFunction(ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, move(date_func), false, false,
|
|
82857
|
+
nullptr, nullptr, date_stats));
|
|
82858
|
+
operator_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), false, false,
|
|
82825
82859
|
nullptr, nullptr, ts_stats));
|
|
82826
82860
|
operator_set.AddFunction(ScalarFunction({LogicalType::INTERVAL}, LogicalType::BIGINT, move(interval_func)));
|
|
82827
|
-
operator_set.AddFunction(
|
|
82828
|
-
|
|
82861
|
+
operator_set.AddFunction(ScalarFunction({LogicalType::TIME}, LogicalType::BIGINT, move(time_func), false, false,
|
|
82862
|
+
nullptr, nullptr, time_stats));
|
|
82829
82863
|
set.AddFunction(operator_set);
|
|
82830
82864
|
}
|
|
82831
82865
|
|
|
@@ -83024,7 +83058,7 @@ struct StructDatePart {
|
|
|
83024
83058
|
static ScalarFunction GetFunction(const LogicalType &temporal_type) {
|
|
83025
83059
|
auto part_type = LogicalType::LIST(LogicalType::VARCHAR);
|
|
83026
83060
|
auto result_type = LogicalType::STRUCT({});
|
|
83027
|
-
return ScalarFunction({part_type, temporal_type}, result_type, Function<INPUT_TYPE>, false, Bind);
|
|
83061
|
+
return ScalarFunction({part_type, temporal_type}, result_type, Function<INPUT_TYPE>, false, false, Bind);
|
|
83028
83062
|
}
|
|
83029
83063
|
};
|
|
83030
83064
|
|
|
@@ -84804,16 +84838,16 @@ void StrfTimeFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
84804
84838
|
ScalarFunctionSet strftime("strftime");
|
|
84805
84839
|
|
|
84806
84840
|
strftime.AddFunction(ScalarFunction({LogicalType::DATE, LogicalType::VARCHAR}, LogicalType::VARCHAR,
|
|
84807
|
-
StrfTimeFunctionDate<false>, false, StrfTimeBindFunction<false>));
|
|
84841
|
+
StrfTimeFunctionDate<false>, false, false, StrfTimeBindFunction<false>));
|
|
84808
84842
|
|
|
84809
84843
|
strftime.AddFunction(ScalarFunction({LogicalType::TIMESTAMP, LogicalType::VARCHAR}, LogicalType::VARCHAR,
|
|
84810
|
-
StrfTimeFunctionTimestamp<false>, false, StrfTimeBindFunction<false>));
|
|
84844
|
+
StrfTimeFunctionTimestamp<false>, false, false, StrfTimeBindFunction<false>));
|
|
84811
84845
|
|
|
84812
84846
|
strftime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::DATE}, LogicalType::VARCHAR,
|
|
84813
|
-
StrfTimeFunctionDate<true>, false, StrfTimeBindFunction<true>));
|
|
84847
|
+
StrfTimeFunctionDate<true>, false, false, StrfTimeBindFunction<true>));
|
|
84814
84848
|
|
|
84815
84849
|
strftime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP}, LogicalType::VARCHAR,
|
|
84816
|
-
StrfTimeFunctionTimestamp<true>, false, StrfTimeBindFunction<true>));
|
|
84850
|
+
StrfTimeFunctionTimestamp<true>, false, false, StrfTimeBindFunction<true>));
|
|
84817
84851
|
|
|
84818
84852
|
set.AddFunction(strftime);
|
|
84819
84853
|
}
|
|
@@ -85376,7 +85410,7 @@ void StrpTimeFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
85376
85410
|
ScalarFunctionSet strptime("strptime");
|
|
85377
85411
|
|
|
85378
85412
|
strptime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::TIMESTAMP,
|
|
85379
|
-
StrpTimeFunction, false, StrpTimeBindFunction));
|
|
85413
|
+
StrpTimeFunction, false, false, StrpTimeBindFunction));
|
|
85380
85414
|
|
|
85381
85415
|
set.AddFunction(strptime);
|
|
85382
85416
|
}
|
|
@@ -86026,22 +86060,23 @@ static void LeastGreatestFunction(DataChunk &args, ExpressionState &state, Vecto
|
|
|
86026
86060
|
|
|
86027
86061
|
template <typename T, class OP>
|
|
86028
86062
|
ScalarFunction GetLeastGreatestFunction(const LogicalType &type) {
|
|
86029
|
-
return ScalarFunction({type}, type, LeastGreatestFunction<T, OP>, false, nullptr, nullptr, nullptr, nullptr,
|
|
86063
|
+
return ScalarFunction({type}, type, LeastGreatestFunction<T, OP>, true, false, nullptr, nullptr, nullptr, nullptr,
|
|
86064
|
+
type);
|
|
86030
86065
|
}
|
|
86031
86066
|
|
|
86032
86067
|
template <class OP>
|
|
86033
86068
|
static void RegisterLeastGreatest(BuiltinFunctions &set, const string &fun_name) {
|
|
86034
86069
|
ScalarFunctionSet fun_set(fun_name);
|
|
86035
86070
|
fun_set.AddFunction(ScalarFunction({LogicalType::BIGINT}, LogicalType::BIGINT, LeastGreatestFunction<int64_t, OP>,
|
|
86036
|
-
false, nullptr, nullptr, nullptr, nullptr, LogicalType::BIGINT));
|
|
86071
|
+
true, false, nullptr, nullptr, nullptr, nullptr, LogicalType::BIGINT));
|
|
86037
86072
|
fun_set.AddFunction(ScalarFunction({LogicalType::HUGEINT}, LogicalType::HUGEINT,
|
|
86038
|
-
LeastGreatestFunction<hugeint_t, OP>,
|
|
86039
|
-
LogicalType::HUGEINT));
|
|
86073
|
+
LeastGreatestFunction<hugeint_t, OP>, true, false, nullptr, nullptr, nullptr,
|
|
86074
|
+
nullptr, LogicalType::HUGEINT));
|
|
86040
86075
|
fun_set.AddFunction(ScalarFunction({LogicalType::DOUBLE}, LogicalType::DOUBLE, LeastGreatestFunction<double, OP>,
|
|
86041
|
-
false, nullptr, nullptr, nullptr, nullptr, LogicalType::DOUBLE));
|
|
86076
|
+
true, false, nullptr, nullptr, nullptr, nullptr, LogicalType::DOUBLE));
|
|
86042
86077
|
fun_set.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR,
|
|
86043
|
-
LeastGreatestFunction<string_t, OP, true>,
|
|
86044
|
-
nullptr, LogicalType::VARCHAR));
|
|
86078
|
+
LeastGreatestFunction<string_t, OP, true>, true, false, nullptr, nullptr,
|
|
86079
|
+
nullptr, nullptr, LogicalType::VARCHAR));
|
|
86045
86080
|
|
|
86046
86081
|
fun_set.AddFunction(GetLeastGreatestFunction<timestamp_t, OP>(LogicalType::TIMESTAMP));
|
|
86047
86082
|
fun_set.AddFunction(GetLeastGreatestFunction<time_t, OP>(LogicalType::TIME));
|
|
@@ -86336,7 +86371,7 @@ static unique_ptr<FunctionData> ArraySliceBind(ClientContext &context, ScalarFun
|
|
|
86336
86371
|
void ArraySliceFun::RegisterFunction(BuiltinFunctions &set) {
|
|
86337
86372
|
// the arguments and return types are actually set in the binder function
|
|
86338
86373
|
ScalarFunction fun({LogicalType::ANY, LogicalType::BIGINT, LogicalType::BIGINT}, LogicalType::ANY,
|
|
86339
|
-
ArraySliceFunction, false, ArraySliceBind);
|
|
86374
|
+
ArraySliceFunction, false, false, ArraySliceBind);
|
|
86340
86375
|
fun.varargs = LogicalType::ANY;
|
|
86341
86376
|
set.AddFunction({"array_slice", "list_slice"}, fun);
|
|
86342
86377
|
}
|
|
@@ -86552,13 +86587,13 @@ static unique_ptr<FunctionData> ListPositionBind(ClientContext &context, ScalarF
|
|
|
86552
86587
|
ScalarFunction ListContainsFun::GetFunction() {
|
|
86553
86588
|
return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::ANY}, // argument list
|
|
86554
86589
|
LogicalType::BOOLEAN, // return type
|
|
86555
|
-
ListContainsFunction, false, ListContainsBind, nullptr);
|
|
86590
|
+
ListContainsFunction, false, false, ListContainsBind, nullptr);
|
|
86556
86591
|
}
|
|
86557
86592
|
|
|
86558
86593
|
ScalarFunction ListPositionFun::GetFunction() {
|
|
86559
86594
|
return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::ANY}, // argument list
|
|
86560
86595
|
LogicalType::INTEGER, // return type
|
|
86561
|
-
ListPositionFunction, false, ListPositionBind, nullptr);
|
|
86596
|
+
ListPositionFunction, false, false, ListPositionBind, nullptr);
|
|
86562
86597
|
}
|
|
86563
86598
|
|
|
86564
86599
|
void ListContainsFun::RegisterFunction(BuiltinFunctions &set) {
|
|
@@ -86734,7 +86769,7 @@ static unique_ptr<BaseStatistics> ListFlattenStats(ClientContext &context, Bound
|
|
|
86734
86769
|
|
|
86735
86770
|
void ListFlattenFun::RegisterFunction(BuiltinFunctions &set) {
|
|
86736
86771
|
ScalarFunction fun({LogicalType::LIST(LogicalType::LIST(LogicalType::ANY))}, LogicalType::LIST(LogicalType::ANY),
|
|
86737
|
-
ListFlattenFunction, false, ListFlattenBind, nullptr, ListFlattenStats);
|
|
86772
|
+
ListFlattenFunction, false, false, ListFlattenBind, nullptr, ListFlattenStats);
|
|
86738
86773
|
set.AddFunction({"flatten"}, fun);
|
|
86739
86774
|
}
|
|
86740
86775
|
|
|
@@ -86746,6 +86781,227 @@ void ListFlattenFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
86746
86781
|
|
|
86747
86782
|
|
|
86748
86783
|
|
|
86784
|
+
|
|
86785
|
+
namespace duckdb {
|
|
86786
|
+
|
|
86787
|
+
// FIXME: use a local state for each thread to increase performance?
|
|
86788
|
+
// FIXME: benchmark the use of simple_update against using update (if applicable)
|
|
86789
|
+
|
|
86790
|
+
struct ListAggregatesBindData : public FunctionData {
|
|
86791
|
+
ListAggregatesBindData(const LogicalType &stype_p, unique_ptr<Expression> aggr_expr_p);
|
|
86792
|
+
~ListAggregatesBindData() override;
|
|
86793
|
+
|
|
86794
|
+
LogicalType stype;
|
|
86795
|
+
unique_ptr<Expression> aggr_expr;
|
|
86796
|
+
|
|
86797
|
+
unique_ptr<FunctionData> Copy() override;
|
|
86798
|
+
};
|
|
86799
|
+
|
|
86800
|
+
ListAggregatesBindData::ListAggregatesBindData(const LogicalType &stype_p, unique_ptr<Expression> aggr_expr_p)
|
|
86801
|
+
: stype(stype_p), aggr_expr(move(aggr_expr_p)) {
|
|
86802
|
+
}
|
|
86803
|
+
|
|
86804
|
+
unique_ptr<FunctionData> ListAggregatesBindData::Copy() {
|
|
86805
|
+
return make_unique<ListAggregatesBindData>(stype, aggr_expr->Copy());
|
|
86806
|
+
}
|
|
86807
|
+
|
|
86808
|
+
ListAggregatesBindData::~ListAggregatesBindData() {
|
|
86809
|
+
}
|
|
86810
|
+
|
|
86811
|
+
struct StateVector {
|
|
86812
|
+
StateVector(idx_t count_p, unique_ptr<Expression> aggr_expr_p)
|
|
86813
|
+
: count(count_p), aggr_expr(move(aggr_expr_p)), state_vector(Vector(LogicalType::POINTER, count_p)) {
|
|
86814
|
+
}
|
|
86815
|
+
|
|
86816
|
+
~StateVector() {
|
|
86817
|
+
// destroy objects within the aggregate states
|
|
86818
|
+
auto &aggr = (BoundAggregateExpression &)*aggr_expr;
|
|
86819
|
+
if (aggr.function.destructor) {
|
|
86820
|
+
aggr.function.destructor(state_vector, count);
|
|
86821
|
+
}
|
|
86822
|
+
}
|
|
86823
|
+
|
|
86824
|
+
idx_t count;
|
|
86825
|
+
unique_ptr<Expression> aggr_expr;
|
|
86826
|
+
Vector state_vector;
|
|
86827
|
+
};
|
|
86828
|
+
|
|
86829
|
+
static void ListAggregateFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
86830
|
+
|
|
86831
|
+
D_ASSERT(args.ColumnCount() == 2);
|
|
86832
|
+
auto count = args.size();
|
|
86833
|
+
Vector &lists = args.data[0];
|
|
86834
|
+
|
|
86835
|
+
// set the result vector
|
|
86836
|
+
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
86837
|
+
auto &result_validity = FlatVector::Validity(result);
|
|
86838
|
+
|
|
86839
|
+
if (lists.GetType().id() == LogicalTypeId::SQLNULL) {
|
|
86840
|
+
result_validity.SetInvalid(0);
|
|
86841
|
+
return;
|
|
86842
|
+
}
|
|
86843
|
+
|
|
86844
|
+
// get the aggregate function
|
|
86845
|
+
auto &func_expr = (BoundFunctionExpression &)state.expr;
|
|
86846
|
+
auto &info = (ListAggregatesBindData &)*func_expr.bind_info;
|
|
86847
|
+
auto &aggr = (BoundAggregateExpression &)*info.aggr_expr;
|
|
86848
|
+
|
|
86849
|
+
D_ASSERT(aggr.function.update);
|
|
86850
|
+
|
|
86851
|
+
auto lists_size = ListVector::GetListSize(lists);
|
|
86852
|
+
auto &child_vector = ListVector::GetEntry(lists);
|
|
86853
|
+
|
|
86854
|
+
VectorData child_data;
|
|
86855
|
+
child_vector.Orrify(lists_size, child_data);
|
|
86856
|
+
|
|
86857
|
+
VectorData lists_data;
|
|
86858
|
+
lists.Orrify(count, lists_data);
|
|
86859
|
+
auto list_entries = (list_entry_t *)lists_data.data;
|
|
86860
|
+
|
|
86861
|
+
// state_buffer holds the state for each list of this chunk
|
|
86862
|
+
idx_t size = aggr.function.state_size();
|
|
86863
|
+
auto state_buffer = unique_ptr<data_t[]>(new data_t[size * count]);
|
|
86864
|
+
|
|
86865
|
+
// state vector for initialize and finalize
|
|
86866
|
+
StateVector state_vector(count, info.aggr_expr->Copy());
|
|
86867
|
+
auto states = FlatVector::GetData<data_ptr_t>(state_vector.state_vector);
|
|
86868
|
+
|
|
86869
|
+
// state vector of STANDARD_VECTOR_SIZE holds the pointers to the states
|
|
86870
|
+
Vector state_vector_update = Vector(LogicalType::POINTER);
|
|
86871
|
+
auto states_update = FlatVector::GetData<data_ptr_t>(state_vector_update);
|
|
86872
|
+
|
|
86873
|
+
// selection vector pointing to the data
|
|
86874
|
+
SelectionVector sel_vector(STANDARD_VECTOR_SIZE);
|
|
86875
|
+
idx_t states_idx = 0;
|
|
86876
|
+
|
|
86877
|
+
for (idx_t i = 0; i < count; i++) {
|
|
86878
|
+
|
|
86879
|
+
// initialize the state for this list
|
|
86880
|
+
auto state_ptr = state_buffer.get() + size * i;
|
|
86881
|
+
states[i] = state_ptr;
|
|
86882
|
+
aggr.function.initialize(states[i]);
|
|
86883
|
+
|
|
86884
|
+
auto lists_index = lists_data.sel->get_index(i);
|
|
86885
|
+
const auto &list_entry = list_entries[lists_index];
|
|
86886
|
+
|
|
86887
|
+
// nothing to do for this list
|
|
86888
|
+
if (!lists_data.validity.RowIsValid(lists_index)) {
|
|
86889
|
+
result_validity.SetInvalid(i);
|
|
86890
|
+
continue;
|
|
86891
|
+
}
|
|
86892
|
+
|
|
86893
|
+
// skip empty list
|
|
86894
|
+
if (list_entry.length == 0) {
|
|
86895
|
+
continue;
|
|
86896
|
+
}
|
|
86897
|
+
|
|
86898
|
+
auto source_idx = child_data.sel->get_index(list_entry.offset);
|
|
86899
|
+
idx_t child_idx = 0;
|
|
86900
|
+
|
|
86901
|
+
while (child_idx < list_entry.length) {
|
|
86902
|
+
|
|
86903
|
+
// states vector is full, update
|
|
86904
|
+
if (states_idx == STANDARD_VECTOR_SIZE) {
|
|
86905
|
+
|
|
86906
|
+
// update the aggregate state(s)
|
|
86907
|
+
Vector slice = Vector(child_vector, sel_vector, states_idx);
|
|
86908
|
+
aggr.function.update(&slice, aggr.bind_info.get(), 1, state_vector_update, states_idx);
|
|
86909
|
+
|
|
86910
|
+
// reset values
|
|
86911
|
+
states_idx = 0;
|
|
86912
|
+
}
|
|
86913
|
+
|
|
86914
|
+
sel_vector.set_index(states_idx, source_idx + child_idx);
|
|
86915
|
+
states_update[states_idx] = state_ptr;
|
|
86916
|
+
states_idx++;
|
|
86917
|
+
child_idx++;
|
|
86918
|
+
}
|
|
86919
|
+
}
|
|
86920
|
+
|
|
86921
|
+
// update the remaining elements of the last list(s)
|
|
86922
|
+
if (states_idx != 0) {
|
|
86923
|
+
Vector slice = Vector(child_vector, sel_vector, states_idx);
|
|
86924
|
+
aggr.function.update(&slice, aggr.bind_info.get(), 1, state_vector_update, states_idx);
|
|
86925
|
+
}
|
|
86926
|
+
|
|
86927
|
+
// finalize all the aggregate states
|
|
86928
|
+
aggr.function.finalize(state_vector.state_vector, aggr.bind_info.get(), result, count, 0);
|
|
86929
|
+
}
|
|
86930
|
+
|
|
86931
|
+
static unique_ptr<FunctionData> ListAggregateBind(ClientContext &context, ScalarFunction &bound_function,
|
|
86932
|
+
vector<unique_ptr<Expression>> &arguments) {
|
|
86933
|
+
|
|
86934
|
+
// the list column and the name of the aggregate function
|
|
86935
|
+
D_ASSERT(bound_function.arguments.size() == 2);
|
|
86936
|
+
D_ASSERT(arguments.size() == 2);
|
|
86937
|
+
|
|
86938
|
+
if (arguments[0]->return_type.id() == LogicalTypeId::SQLNULL) {
|
|
86939
|
+
bound_function.arguments[0] = LogicalType::SQLNULL;
|
|
86940
|
+
bound_function.return_type = LogicalType::SQLNULL;
|
|
86941
|
+
return make_unique<VariableReturnBindData>(bound_function.return_type);
|
|
86942
|
+
}
|
|
86943
|
+
|
|
86944
|
+
D_ASSERT(LogicalTypeId::LIST == arguments[0]->return_type.id());
|
|
86945
|
+
auto list_child_type = ListType::GetChildType(arguments[0]->return_type);
|
|
86946
|
+
bound_function.return_type = list_child_type;
|
|
86947
|
+
|
|
86948
|
+
if (!arguments[1]->IsFoldable()) {
|
|
86949
|
+
throw InvalidInputException("Aggregate function name must be a constant");
|
|
86950
|
+
}
|
|
86951
|
+
|
|
86952
|
+
// get the function name
|
|
86953
|
+
Value function_value = ExpressionExecutor::EvaluateScalar(*arguments[1]);
|
|
86954
|
+
auto function_name = StringValue::Get(function_value);
|
|
86955
|
+
|
|
86956
|
+
vector<LogicalType> types;
|
|
86957
|
+
types.push_back(list_child_type);
|
|
86958
|
+
|
|
86959
|
+
// create the child expression and its type
|
|
86960
|
+
vector<unique_ptr<Expression>> children;
|
|
86961
|
+
auto expr = make_unique<BoundConstantExpression>(Value(LogicalType::SQLNULL));
|
|
86962
|
+
expr->return_type = list_child_type;
|
|
86963
|
+
children.push_back(move(expr));
|
|
86964
|
+
|
|
86965
|
+
// look up the aggregate function in the catalog
|
|
86966
|
+
QueryErrorContext error_context(nullptr, 0);
|
|
86967
|
+
auto func = (AggregateFunctionCatalogEntry *)Catalog::GetCatalog(context).GetEntry<AggregateFunctionCatalogEntry>(
|
|
86968
|
+
context, DEFAULT_SCHEMA, function_name, false, error_context);
|
|
86969
|
+
D_ASSERT(func->type == CatalogType::AGGREGATE_FUNCTION_ENTRY);
|
|
86970
|
+
|
|
86971
|
+
// find a matching aggregate function
|
|
86972
|
+
string error;
|
|
86973
|
+
auto best_function_idx = Function::BindFunction(func->name, func->functions, types, error);
|
|
86974
|
+
if (best_function_idx == DConstants::INVALID_INDEX) {
|
|
86975
|
+
throw BinderException("No matching aggregate function");
|
|
86976
|
+
}
|
|
86977
|
+
|
|
86978
|
+
// found a matching function, bind it as an aggregate
|
|
86979
|
+
auto &best_function = func->functions[best_function_idx];
|
|
86980
|
+
auto bound_aggr_function = AggregateFunction::BindAggregateFunction(context, best_function, move(children));
|
|
86981
|
+
|
|
86982
|
+
bound_function.arguments[0] =
|
|
86983
|
+
LogicalType::LIST(bound_aggr_function->function.arguments[0]); // for proper casting of the vectors
|
|
86984
|
+
bound_function.return_type = bound_aggr_function->function.return_type;
|
|
86985
|
+
return make_unique<ListAggregatesBindData>(bound_function.return_type, move(bound_aggr_function));
|
|
86986
|
+
}
|
|
86987
|
+
|
|
86988
|
+
ScalarFunction ListAggregateFun::GetFunction() {
|
|
86989
|
+
return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::VARCHAR}, LogicalType::ANY,
|
|
86990
|
+
ListAggregateFunction, false, ListAggregateBind, nullptr, nullptr, nullptr);
|
|
86991
|
+
}
|
|
86992
|
+
|
|
86993
|
+
void ListAggregateFun::RegisterFunction(BuiltinFunctions &set) {
|
|
86994
|
+
set.AddFunction({"list_aggregate", "array_aggregate", "list_aggr", "array_aggr"}, GetFunction());
|
|
86995
|
+
}
|
|
86996
|
+
|
|
86997
|
+
} // namespace duckdb
|
|
86998
|
+
|
|
86999
|
+
|
|
87000
|
+
|
|
87001
|
+
|
|
87002
|
+
|
|
87003
|
+
|
|
87004
|
+
|
|
86749
87005
|
namespace duckdb {
|
|
86750
87006
|
|
|
86751
87007
|
static void ListConcatFunction(DataChunk &args, ExpressionState &state, Vector &result) {
|
|
@@ -86866,8 +87122,8 @@ static unique_ptr<BaseStatistics> ListConcatStats(ClientContext &context, BoundF
|
|
|
86866
87122
|
ScalarFunction ListConcatFun::GetFunction() {
|
|
86867
87123
|
// the arguments and return types are actually set in the binder function
|
|
86868
87124
|
return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::LIST(LogicalType::ANY)},
|
|
86869
|
-
LogicalType::LIST(LogicalType::ANY), ListConcatFunction, false,
|
|
86870
|
-
ListConcatStats);
|
|
87125
|
+
LogicalType::LIST(LogicalType::ANY), ListConcatFunction, false, false, ListConcatBind,
|
|
87126
|
+
nullptr, ListConcatStats);
|
|
86871
87127
|
}
|
|
86872
87128
|
|
|
86873
87129
|
void ListConcatFun::RegisterFunction(BuiltinFunctions &set) {
|
|
@@ -87105,10 +87361,10 @@ static unique_ptr<BaseStatistics> ListExtractStats(ClientContext &context, Bound
|
|
|
87105
87361
|
void ListExtractFun::RegisterFunction(BuiltinFunctions &set) {
|
|
87106
87362
|
// the arguments and return types are actually set in the binder function
|
|
87107
87363
|
ScalarFunction lfun({LogicalType::LIST(LogicalType::ANY), LogicalType::BIGINT}, LogicalType::ANY,
|
|
87108
|
-
ListExtractFunction, false, ListExtractBind, nullptr, ListExtractStats);
|
|
87364
|
+
ListExtractFunction, false, false, ListExtractBind, nullptr, ListExtractStats);
|
|
87109
87365
|
|
|
87110
87366
|
ScalarFunction sfun({LogicalType::VARCHAR, LogicalType::INTEGER}, LogicalType::VARCHAR, ListExtractFunction, false,
|
|
87111
|
-
nullptr);
|
|
87367
|
+
false, nullptr);
|
|
87112
87368
|
|
|
87113
87369
|
ScalarFunctionSet list_extract("list_extract");
|
|
87114
87370
|
list_extract.AddFunction(lfun);
|
|
@@ -87967,7 +88223,7 @@ void AbsFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
87967
88223
|
ScalarFunctionSet abs("abs");
|
|
87968
88224
|
for (auto &type : LogicalType::Numeric()) {
|
|
87969
88225
|
if (type.id() == LogicalTypeId::DECIMAL) {
|
|
87970
|
-
abs.AddFunction(ScalarFunction({type}, type, nullptr, false, DecimalUnaryOpBind<AbsOperator>));
|
|
88226
|
+
abs.AddFunction(ScalarFunction({type}, type, nullptr, false, false, DecimalUnaryOpBind<AbsOperator>));
|
|
87971
88227
|
} else {
|
|
87972
88228
|
abs.AddFunction(ScalarFunction({type}, type, ScalarFunction::GetScalarUnaryFunction<AbsOperator>(type)));
|
|
87973
88229
|
}
|
|
@@ -88141,7 +88397,7 @@ void CeilFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
88141
88397
|
default:
|
|
88142
88398
|
throw InternalException("Unimplemented numeric type for function \"ceil\"");
|
|
88143
88399
|
}
|
|
88144
|
-
ceil.AddFunction(ScalarFunction({type}, type, func, false, bind_func));
|
|
88400
|
+
ceil.AddFunction(ScalarFunction({type}, type, func, false, false, bind_func));
|
|
88145
88401
|
}
|
|
88146
88402
|
|
|
88147
88403
|
set.AddFunction(ceil);
|
|
@@ -88197,7 +88453,7 @@ void FloorFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
88197
88453
|
default:
|
|
88198
88454
|
throw InternalException("Unimplemented numeric type for function \"floor\"");
|
|
88199
88455
|
}
|
|
88200
|
-
floor.AddFunction(ScalarFunction({type}, type, func, false, bind_func));
|
|
88456
|
+
floor.AddFunction(ScalarFunction({type}, type, func, false, false, bind_func));
|
|
88201
88457
|
}
|
|
88202
88458
|
set.AddFunction(floor);
|
|
88203
88459
|
}
|
|
@@ -88404,8 +88660,9 @@ void RoundFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
88404
88660
|
default:
|
|
88405
88661
|
throw InternalException("Unimplemented numeric type for function \"floor\"");
|
|
88406
88662
|
}
|
|
88407
|
-
round.AddFunction(ScalarFunction({type}, type, round_func, false, bind_func));
|
|
88408
|
-
round.AddFunction(
|
|
88663
|
+
round.AddFunction(ScalarFunction({type}, type, round_func, false, false, bind_func));
|
|
88664
|
+
round.AddFunction(
|
|
88665
|
+
ScalarFunction({type, LogicalType::INTEGER}, type, round_prec_func, false, false, bind_prec_func));
|
|
88409
88666
|
}
|
|
88410
88667
|
set.AddFunction(round);
|
|
88411
88668
|
}
|
|
@@ -89027,6 +89284,7 @@ void BuiltinFunctions::RegisterNestedFunctions() {
|
|
|
89027
89284
|
Register<ListConcatFun>();
|
|
89028
89285
|
Register<ListContainsFun>();
|
|
89029
89286
|
Register<ListPositionFun>();
|
|
89287
|
+
Register<ListAggregateFun>();
|
|
89030
89288
|
Register<ListValueFun>();
|
|
89031
89289
|
Register<ListExtractFun>();
|
|
89032
89290
|
Register<ListRangeFun>();
|
|
@@ -90003,23 +90261,23 @@ void MultiplyFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
90003
90261
|
ScalarFunctionSet functions("*");
|
|
90004
90262
|
for (auto &type : LogicalType::Numeric()) {
|
|
90005
90263
|
if (type.id() == LogicalTypeId::DECIMAL) {
|
|
90006
|
-
functions.AddFunction(ScalarFunction({type, type}, type, nullptr, false, BindDecimalMultiply));
|
|
90264
|
+
functions.AddFunction(ScalarFunction({type, type}, type, nullptr, true, false, BindDecimalMultiply));
|
|
90007
90265
|
} else if (TypeIsIntegral(type.InternalType()) && type.id() != LogicalTypeId::HUGEINT) {
|
|
90008
90266
|
functions.AddFunction(ScalarFunction(
|
|
90009
|
-
{type, type}, type, GetScalarIntegerFunction<MultiplyOperatorOverflowCheck>(type.InternalType()),
|
|
90010
|
-
nullptr, nullptr,
|
|
90267
|
+
{type, type}, type, GetScalarIntegerFunction<MultiplyOperatorOverflowCheck>(type.InternalType()), true,
|
|
90268
|
+
false, nullptr, nullptr,
|
|
90011
90269
|
PropagateNumericStats<TryMultiplyOperator, MultiplyPropagateStatistics, MultiplyOperator>));
|
|
90012
90270
|
} else {
|
|
90013
|
-
functions.AddFunction(
|
|
90014
|
-
|
|
90271
|
+
functions.AddFunction(ScalarFunction({type, type}, type,
|
|
90272
|
+
GetScalarBinaryFunction<MultiplyOperator>(type.InternalType()), true));
|
|
90015
90273
|
}
|
|
90016
90274
|
}
|
|
90017
90275
|
functions.AddFunction(
|
|
90018
90276
|
ScalarFunction({LogicalType::INTERVAL, LogicalType::BIGINT}, LogicalType::INTERVAL,
|
|
90019
|
-
ScalarFunction::BinaryFunction<interval_t, int64_t, interval_t, MultiplyOperator
|
|
90277
|
+
ScalarFunction::BinaryFunction<interval_t, int64_t, interval_t, MultiplyOperator>, true));
|
|
90020
90278
|
functions.AddFunction(
|
|
90021
90279
|
ScalarFunction({LogicalType::BIGINT, LogicalType::INTERVAL}, LogicalType::INTERVAL,
|
|
90022
|
-
ScalarFunction::BinaryFunction<int64_t, interval_t, interval_t, MultiplyOperator
|
|
90280
|
+
ScalarFunction::BinaryFunction<int64_t, interval_t, interval_t, MultiplyOperator>, true));
|
|
90023
90281
|
set.AddFunction(functions);
|
|
90024
90282
|
}
|
|
90025
90283
|
|
|
@@ -91257,7 +91515,7 @@ void LowerFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
91257
91515
|
void UpperFun::RegisterFunction(BuiltinFunctions &set) {
|
|
91258
91516
|
set.AddFunction({"upper", "ucase"},
|
|
91259
91517
|
ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR, CaseConvertFunction<true>, false,
|
|
91260
|
-
nullptr, nullptr, CaseConvertPropagateStats<true>));
|
|
91518
|
+
false, nullptr, nullptr, CaseConvertPropagateStats<true>));
|
|
91261
91519
|
}
|
|
91262
91520
|
|
|
91263
91521
|
} // namespace duckdb
|
|
@@ -91987,11 +92245,11 @@ static unique_ptr<FunctionData> ListLengthBind(ClientContext &context, ScalarFun
|
|
|
91987
92245
|
void LengthFun::RegisterFunction(BuiltinFunctions &set) {
|
|
91988
92246
|
ScalarFunction array_length_unary = ScalarFunction(
|
|
91989
92247
|
{LogicalType::LIST(LogicalType::ANY)}, LogicalType::BIGINT,
|
|
91990
|
-
ScalarFunction::UnaryFunction<list_entry_t, int64_t, ArrayLengthOperator>, false, ListLengthBind);
|
|
92248
|
+
ScalarFunction::UnaryFunction<list_entry_t, int64_t, ArrayLengthOperator>, false, false, ListLengthBind);
|
|
91991
92249
|
ScalarFunctionSet length("length");
|
|
91992
92250
|
length.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::BIGINT,
|
|
91993
92251
|
ScalarFunction::UnaryFunction<string_t, int64_t, StringLengthOperator>, false,
|
|
91994
|
-
nullptr, nullptr, LengthPropagateStats));
|
|
92252
|
+
false, nullptr, nullptr, LengthPropagateStats));
|
|
91995
92253
|
length.AddFunction(array_length_unary);
|
|
91996
92254
|
set.AddFunction(length);
|
|
91997
92255
|
length.name = "len";
|
|
@@ -92002,7 +92260,7 @@ void LengthFun::RegisterFunction(BuiltinFunctions &set) {
|
|
|
92002
92260
|
array_length.AddFunction(
|
|
92003
92261
|
ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::BIGINT}, LogicalType::BIGINT,
|
|
92004
92262
|
ScalarFunction::BinaryFunction<list_entry_t, int64_t, int64_t, ArrayLengthBinaryOperator>, false,
|
|
92005
|
-
ListLengthBind));
|
|
92263
|
+
false, ListLengthBind));
|
|
92006
92264
|
set.AddFunction(array_length);
|
|
92007
92265
|
|
|
92008
92266
|
set.AddFunction(ScalarFunction("strlen", {LogicalType::VARCHAR}, LogicalType::BIGINT,
|
|
@@ -94751,34 +95009,36 @@ static unique_ptr<FunctionData> RegexExtractBind(ClientContext &context, ScalarF
|
|
|
94751
95009
|
void RegexpFun::RegisterFunction(BuiltinFunctions &set) {
|
|
94752
95010
|
ScalarFunctionSet regexp_full_match("regexp_full_match");
|
|
94753
95011
|
regexp_full_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::BOOLEAN,
|
|
94754
|
-
RegexpMatchesFunction<RegexFullMatch>, false, RegexpMatchesBind,
|
|
95012
|
+
RegexpMatchesFunction<RegexFullMatch>, false, false, RegexpMatchesBind,
|
|
94755
95013
|
nullptr, nullptr, RegexInitLocalState));
|
|
94756
95014
|
regexp_full_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
|
|
94757
95015
|
LogicalType::BOOLEAN, RegexpMatchesFunction<RegexFullMatch>, false,
|
|
94758
|
-
RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
|
|
95016
|
+
false, RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
|
|
94759
95017
|
|
|
94760
95018
|
ScalarFunctionSet regexp_partial_match("regexp_matches");
|
|
94761
95019
|
regexp_partial_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::BOOLEAN,
|
|
94762
|
-
RegexpMatchesFunction<RegexPartialMatch>, false,
|
|
94763
|
-
nullptr, nullptr, RegexInitLocalState));
|
|
95020
|
+
RegexpMatchesFunction<RegexPartialMatch>, false, false,
|
|
95021
|
+
RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
|
|
94764
95022
|
regexp_partial_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
|
|
94765
95023
|
LogicalType::BOOLEAN, RegexpMatchesFunction<RegexPartialMatch>,
|
|
94766
|
-
false, RegexpMatchesBind, nullptr, nullptr,
|
|
95024
|
+
false, false, RegexpMatchesBind, nullptr, nullptr,
|
|
95025
|
+
RegexInitLocalState));
|
|
94767
95026
|
|
|
94768
95027
|
ScalarFunctionSet regexp_replace("regexp_replace");
|
|
94769
95028
|
regexp_replace.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
|
|
94770
|
-
LogicalType::VARCHAR, RegexReplaceFunction, false,
|
|
95029
|
+
LogicalType::VARCHAR, RegexReplaceFunction, false, false,
|
|
95030
|
+
RegexReplaceBind));
|
|
94771
95031
|
regexp_replace.AddFunction(
|
|
94772
95032
|
ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
|
|
94773
|
-
LogicalType::VARCHAR, RegexReplaceFunction, false, RegexReplaceBind));
|
|
95033
|
+
LogicalType::VARCHAR, RegexReplaceFunction, false, false, RegexReplaceBind));
|
|
94774
95034
|
|
|
94775
95035
|
ScalarFunctionSet regexp_extract("regexp_extract");
|
|
94776
95036
|
regexp_extract.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::VARCHAR,
|
|
94777
|
-
RegexExtractFunction, false, RegexExtractBind, nullptr, nullptr,
|
|
95037
|
+
RegexExtractFunction, false, false, RegexExtractBind, nullptr, nullptr,
|
|
94778
95038
|
RegexExtractInitLocalState));
|
|
94779
95039
|
regexp_extract.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::INTEGER},
|
|
94780
|
-
LogicalType::VARCHAR, RegexExtractFunction, false,
|
|
94781
|
-
nullptr, nullptr, RegexExtractInitLocalState));
|
|
95040
|
+
LogicalType::VARCHAR, RegexExtractFunction, false, false,
|
|
95041
|
+
RegexExtractBind, nullptr, nullptr, RegexExtractInitLocalState));
|
|
94782
95042
|
|
|
94783
95043
|
set.AddFunction(regexp_full_match);
|
|
94784
95044
|
set.AddFunction(regexp_partial_match);
|
|
@@ -95471,10 +95731,10 @@ static unique_ptr<BaseStatistics> SubstringPropagateStats(ClientContext &context
|
|
|
95471
95731
|
void SubstringFun::RegisterFunction(BuiltinFunctions &set) {
|
|
95472
95732
|
ScalarFunctionSet substr("substring");
|
|
95473
95733
|
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT, LogicalType::BIGINT},
|
|
95474
|
-
LogicalType::VARCHAR, SubstringFunction, false, nullptr, nullptr,
|
|
95734
|
+
LogicalType::VARCHAR, SubstringFunction, false, false, nullptr, nullptr,
|
|
95475
95735
|
SubstringPropagateStats));
|
|
95476
95736
|
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT}, LogicalType::VARCHAR,
|
|
95477
|
-
SubstringFunction, false, nullptr, nullptr, SubstringPropagateStats));
|
|
95737
|
+
SubstringFunction, false, false, nullptr, nullptr, SubstringPropagateStats));
|
|
95478
95738
|
set.AddFunction(substr);
|
|
95479
95739
|
substr.name = "substr";
|
|
95480
95740
|
set.AddFunction(substr);
|
|
@@ -96467,7 +96727,7 @@ static void GenerateUUIDFunction(DataChunk &args, ExpressionState &state, Vector
|
|
|
96467
96727
|
}
|
|
96468
96728
|
|
|
96469
96729
|
void UUIDFun::RegisterFunction(BuiltinFunctions &set) {
|
|
96470
|
-
ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, true, UUIDRandomBind);
|
|
96730
|
+
ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, false, true, UUIDRandomBind);
|
|
96471
96731
|
// generate a random uuid
|
|
96472
96732
|
set.AddFunction({"uuid", "gen_random_uuid"}, uuid_function);
|
|
96473
96733
|
}
|
|
@@ -96480,18 +96740,19 @@ namespace duckdb {
|
|
|
96480
96740
|
ScalarFunction::ScalarFunction(string name, vector<LogicalType> arguments, LogicalType return_type,
|
|
96481
96741
|
scalar_function_t function, bool has_side_effects, bind_scalar_function_t bind,
|
|
96482
96742
|
dependency_function_t dependency, function_statistics_t statistics,
|
|
96483
|
-
init_local_state_t init_local_state, LogicalType varargs)
|
|
96484
|
-
: BaseScalarFunction(move(name), move(arguments), move(return_type), has_side_effects, move(varargs)
|
|
96743
|
+
init_local_state_t init_local_state, LogicalType varargs, bool propagate_null_values)
|
|
96744
|
+
: BaseScalarFunction(move(name), move(arguments), move(return_type), has_side_effects, move(varargs),
|
|
96745
|
+
propagate_null_values),
|
|
96485
96746
|
function(move(function)), bind(bind), init_local_state(init_local_state), dependency(dependency),
|
|
96486
96747
|
statistics(statistics) {
|
|
96487
96748
|
}
|
|
96488
96749
|
|
|
96489
96750
|
ScalarFunction::ScalarFunction(vector<LogicalType> arguments, LogicalType return_type, scalar_function_t function,
|
|
96490
|
-
bool has_side_effects, bind_scalar_function_t bind,
|
|
96491
|
-
|
|
96492
|
-
LogicalType varargs)
|
|
96751
|
+
bool propagate_null_values, bool has_side_effects, bind_scalar_function_t bind,
|
|
96752
|
+
dependency_function_t dependency, function_statistics_t statistics,
|
|
96753
|
+
init_local_state_t init_local_state, LogicalType varargs)
|
|
96493
96754
|
: ScalarFunction(string(), move(arguments), move(return_type), move(function), has_side_effects, bind, dependency,
|
|
96494
|
-
statistics, init_local_state, move(varargs)) {
|
|
96755
|
+
statistics, init_local_state, move(varargs), propagate_null_values) {
|
|
96495
96756
|
}
|
|
96496
96757
|
|
|
96497
96758
|
bool ScalarFunction::operator==(const ScalarFunction &rhs) const {
|
|
@@ -119806,7 +120067,11 @@ const vector<ColumnDefinition> &JoinRelation::Columns() {
|
|
|
119806
120067
|
|
|
119807
120068
|
string JoinRelation::ToString(idx_t depth) {
|
|
119808
120069
|
string str = RenderWhitespace(depth);
|
|
119809
|
-
str
|
|
120070
|
+
str += "Join " + JoinTypeToString(join_type);
|
|
120071
|
+
if (condition) {
|
|
120072
|
+
str += " " + condition->GetName();
|
|
120073
|
+
}
|
|
120074
|
+
|
|
119810
120075
|
return str + "\n" + left->ToString(depth + 1) + "\n" + right->ToString(depth + 1);
|
|
119811
120076
|
}
|
|
119812
120077
|
|
|
@@ -119917,6 +120182,7 @@ public:
|
|
|
119917
120182
|
|
|
119918
120183
|
vector<OrderByNode> orders;
|
|
119919
120184
|
shared_ptr<Relation> child;
|
|
120185
|
+
vector<ColumnDefinition> columns;
|
|
119920
120186
|
|
|
119921
120187
|
public:
|
|
119922
120188
|
unique_ptr<QueryNode> GetQueryNode() override;
|
|
@@ -119939,23 +120205,26 @@ public:
|
|
|
119939
120205
|
|
|
119940
120206
|
|
|
119941
120207
|
|
|
120208
|
+
|
|
120209
|
+
|
|
119942
120210
|
namespace duckdb {
|
|
119943
120211
|
|
|
119944
120212
|
OrderRelation::OrderRelation(shared_ptr<Relation> child_p, vector<OrderByNode> orders)
|
|
119945
120213
|
: Relation(child_p->context, RelationType::ORDER_RELATION), orders(move(orders)), child(move(child_p)) {
|
|
119946
120214
|
// bind the expressions
|
|
119947
|
-
|
|
119948
|
-
context.GetContext()->TryBindRelation(*this, dummy_columns);
|
|
120215
|
+
context.GetContext()->TryBindRelation(*this, this->columns);
|
|
119949
120216
|
}
|
|
119950
120217
|
|
|
119951
120218
|
unique_ptr<QueryNode> OrderRelation::GetQueryNode() {
|
|
119952
|
-
auto
|
|
120219
|
+
auto select = make_unique<SelectNode>();
|
|
120220
|
+
select->from_table = child->GetTableRef();
|
|
120221
|
+
select->select_list.push_back(make_unique<StarExpression>());
|
|
119953
120222
|
auto order_node = make_unique<OrderModifier>();
|
|
119954
120223
|
for (idx_t i = 0; i < orders.size(); i++) {
|
|
119955
120224
|
order_node->orders.emplace_back(orders[i].type, orders[i].null_order, orders[i].expression->Copy());
|
|
119956
120225
|
}
|
|
119957
|
-
|
|
119958
|
-
return
|
|
120226
|
+
select->modifiers.push_back(move(order_node));
|
|
120227
|
+
return move(select);
|
|
119959
120228
|
}
|
|
119960
120229
|
|
|
119961
120230
|
string OrderRelation::GetAlias() {
|
|
@@ -119963,7 +120232,7 @@ string OrderRelation::GetAlias() {
|
|
|
119963
120232
|
}
|
|
119964
120233
|
|
|
119965
120234
|
const vector<ColumnDefinition> &OrderRelation::Columns() {
|
|
119966
|
-
return
|
|
120235
|
+
return columns;
|
|
119967
120236
|
}
|
|
119968
120237
|
|
|
119969
120238
|
string OrderRelation::ToString(idx_t depth) {
|
|
@@ -122396,7 +122665,6 @@ public:
|
|
|
122396
122665
|
void VisitExpression(unique_ptr<Expression> *expression) override;
|
|
122397
122666
|
//! Whether the operator has one or more children of type DELIM_GET
|
|
122398
122667
|
bool HasChildDelimGet(LogicalOperator &op);
|
|
122399
|
-
|
|
122400
122668
|
expression_map_t<Expression *> expr_map;
|
|
122401
122669
|
column_binding_map_t<bool> projection_map;
|
|
122402
122670
|
unique_ptr<LogicalOperator> temp_ptr;
|
|
@@ -122405,12 +122673,12 @@ public:
|
|
|
122405
122673
|
void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) {
|
|
122406
122674
|
VisitOperatorChildren(op);
|
|
122407
122675
|
VisitOperatorExpressions(op);
|
|
122408
|
-
// now check if this is a delim join that can be removed
|
|
122409
122676
|
if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN && !HasChildDelimGet(op)) {
|
|
122410
122677
|
auto &delim_join = (LogicalDelimJoin &)op;
|
|
122411
122678
|
auto decs = &delim_join.duplicate_eliminated_columns;
|
|
122412
122679
|
for (auto &cond : delim_join.conditions) {
|
|
122413
|
-
if (cond.comparison != ExpressionType::COMPARE_EQUAL
|
|
122680
|
+
if (cond.comparison != ExpressionType::COMPARE_EQUAL &&
|
|
122681
|
+
cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
|
|
122414
122682
|
continue;
|
|
122415
122683
|
}
|
|
122416
122684
|
auto &colref = (BoundColumnRefExpression &)*cond.right;
|
|
@@ -122424,7 +122692,7 @@ void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) {
|
|
|
122424
122692
|
}
|
|
122425
122693
|
}
|
|
122426
122694
|
// whether we applied an IS NOT NULL filter
|
|
122427
|
-
cond.
|
|
122695
|
+
cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
|
|
122428
122696
|
}
|
|
122429
122697
|
}
|
|
122430
122698
|
// change type if there are no more duplicate-eliminated columns
|
|
@@ -122521,6 +122789,7 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *op_ptr, Deliminat
|
|
|
122521
122789
|
if (join.join_type != JoinType::INNER && join.join_type != JoinType::SEMI) {
|
|
122522
122790
|
return false;
|
|
122523
122791
|
}
|
|
122792
|
+
|
|
122524
122793
|
// get the index (left or right) of the DelimGet side of the join
|
|
122525
122794
|
idx_t delim_idx = OperatorIsDelimGet(*join.children[0]) ? 0 : 1;
|
|
122526
122795
|
D_ASSERT(OperatorIsDelimGet(*join.children[delim_idx]));
|
|
@@ -122537,7 +122806,8 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *op_ptr, Deliminat
|
|
|
122537
122806
|
// check if joining with the DelimGet is redundant, and collect relevant column information
|
|
122538
122807
|
vector<Expression *> nulls_are_not_equal_exprs;
|
|
122539
122808
|
for (auto &cond : join.conditions) {
|
|
122540
|
-
if (cond.comparison != ExpressionType::COMPARE_EQUAL
|
|
122809
|
+
if (cond.comparison != ExpressionType::COMPARE_EQUAL &&
|
|
122810
|
+
cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
|
|
122541
122811
|
// non-equality join condition
|
|
122542
122812
|
return false;
|
|
122543
122813
|
}
|
|
@@ -122549,7 +122819,7 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *op_ptr, Deliminat
|
|
|
122549
122819
|
return false;
|
|
122550
122820
|
}
|
|
122551
122821
|
updater.expr_map[delim_side] = other_side;
|
|
122552
|
-
if (
|
|
122822
|
+
if (cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
|
|
122553
122823
|
nulls_are_not_equal_exprs.push_back(other_side);
|
|
122554
122824
|
}
|
|
122555
122825
|
}
|
|
@@ -125838,15 +126108,8 @@ JoinOrderOptimizer::GenerateJoins(vector<unique_ptr<LogicalOperator>> &extracted
|
|
|
125838
126108
|
bool invert = !JoinRelationSet::IsSubset(left.first, f->left_set);
|
|
125839
126109
|
cond.left = !invert ? move(comparison.left) : move(comparison.right);
|
|
125840
126110
|
cond.right = !invert ? move(comparison.right) : move(comparison.left);
|
|
125841
|
-
|
|
125842
|
-
|
|
125843
|
-
cond.null_values_are_equal = true;
|
|
125844
|
-
} else if (condition->type == ExpressionType::COMPARE_DISTINCT_FROM) {
|
|
125845
|
-
cond.comparison = condition->type;
|
|
125846
|
-
cond.null_values_are_equal = true;
|
|
125847
|
-
} else {
|
|
125848
|
-
cond.comparison = condition->type;
|
|
125849
|
-
}
|
|
126111
|
+
cond.comparison = condition->type;
|
|
126112
|
+
|
|
125850
126113
|
if (invert) {
|
|
125851
126114
|
// reverse comparison expression if we reverse the order of the children
|
|
125852
126115
|
cond.comparison = FlipComparisionExpression(cond.comparison);
|
|
@@ -127517,7 +127780,8 @@ unique_ptr<LogicalOperator> FilterPushdown::PushdownMarkJoin(unique_ptr<LogicalO
|
|
|
127517
127780
|
// the filter is NOT(marker), check the join conditions
|
|
127518
127781
|
bool all_null_values_are_equal = true;
|
|
127519
127782
|
for (auto &cond : comp_join.conditions) {
|
|
127520
|
-
if (
|
|
127783
|
+
if (cond.comparison != ExpressionType::COMPARE_DISTINCT_FROM &&
|
|
127784
|
+
cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
|
|
127521
127785
|
all_null_values_are_equal = false;
|
|
127522
127786
|
break;
|
|
127523
127787
|
}
|
|
@@ -130180,7 +130444,9 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq
|
|
|
130180
130444
|
auto stats_left = PropagateExpression(condition.left);
|
|
130181
130445
|
auto stats_right = PropagateExpression(condition.right);
|
|
130182
130446
|
if (stats_left && stats_right) {
|
|
130183
|
-
if (condition.
|
|
130447
|
+
if ((condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM ||
|
|
130448
|
+
condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM) &&
|
|
130449
|
+
stats_left->CanHaveNull() && stats_right->CanHaveNull()) {
|
|
130184
130450
|
// null values are equal in this join, and both sides can have null values
|
|
130185
130451
|
// nothing to do here
|
|
130186
130452
|
continue;
|
|
@@ -130268,7 +130534,8 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq
|
|
|
130268
130534
|
// anti joins have inverse statistics propagation
|
|
130269
130535
|
// (i.e. if we have an anti join on i: [0, 100] and j: [0, 25], the resulting stats are i:[25,100])
|
|
130270
130536
|
// for now we don't handle anti joins
|
|
130271
|
-
if (condition.
|
|
130537
|
+
if (condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM ||
|
|
130538
|
+
condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
|
|
130272
130539
|
// skip update when null values are equal (for now?)
|
|
130273
130540
|
continue;
|
|
130274
130541
|
}
|
|
@@ -151401,10 +151668,16 @@ BindResult BindContext::BindColumn(ColumnRefExpression &colref, idx_t depth) {
|
|
|
151401
151668
|
}
|
|
151402
151669
|
|
|
151403
151670
|
string BindContext::BindColumn(PositionalReferenceExpression &ref, string &table_name, string &column_name) {
|
|
151404
|
-
idx_t current_position = ref.index - 1;
|
|
151405
151671
|
idx_t total_columns = 0;
|
|
151672
|
+
idx_t current_position = ref.index - 1;
|
|
151406
151673
|
for (auto &entry : bindings_list) {
|
|
151407
151674
|
idx_t entry_column_count = entry.second->names.size();
|
|
151675
|
+
if (ref.index == 0) {
|
|
151676
|
+
// this is a row id
|
|
151677
|
+
table_name = entry.first;
|
|
151678
|
+
column_name = "rowid";
|
|
151679
|
+
return string();
|
|
151680
|
+
}
|
|
151408
151681
|
if (current_position < entry_column_count) {
|
|
151409
151682
|
table_name = entry.first;
|
|
151410
151683
|
column_name = entry.second->names[current_position];
|
|
@@ -154778,7 +155051,7 @@ namespace duckdb {
|
|
|
154778
155051
|
//! The FlattenDependentJoins class is responsible for pushing the dependent join down into the plan to create a
|
|
154779
155052
|
//! flattened subquery
|
|
154780
155053
|
struct FlattenDependentJoins {
|
|
154781
|
-
FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated);
|
|
155054
|
+
FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated, bool any_join = false);
|
|
154782
155055
|
|
|
154783
155056
|
//! Detects which Logical Operators have correlated expressions that they are dependent upon, filling the
|
|
154784
155057
|
//! has_correlated_expressions map.
|
|
@@ -154797,8 +155070,11 @@ struct FlattenDependentJoins {
|
|
|
154797
155070
|
const vector<CorrelatedColumnInfo> &correlated_columns;
|
|
154798
155071
|
vector<LogicalType> delim_types;
|
|
154799
155072
|
|
|
155073
|
+
bool any_join;
|
|
155074
|
+
|
|
154800
155075
|
private:
|
|
154801
|
-
unique_ptr<LogicalOperator> PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan
|
|
155076
|
+
unique_ptr<LogicalOperator> PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan,
|
|
155077
|
+
bool &parent_propagate_null_values);
|
|
154802
155078
|
};
|
|
154803
155079
|
|
|
154804
155080
|
} // namespace duckdb
|
|
@@ -154944,8 +155220,7 @@ static void CreateDelimJoinConditions(LogicalDelimJoin &delim_join, vector<Corre
|
|
|
154944
155220
|
JoinCondition cond;
|
|
154945
155221
|
cond.left = make_unique<BoundColumnRefExpression>(col.name, col.type, col.binding);
|
|
154946
155222
|
cond.right = make_unique<BoundColumnRefExpression>(col.name, col.type, bindings[base_offset + i]);
|
|
154947
|
-
cond.comparison = ExpressionType::
|
|
154948
|
-
cond.null_values_are_equal = true;
|
|
155223
|
+
cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
|
|
154949
155224
|
delim_join.conditions.push_back(move(cond));
|
|
154950
155225
|
}
|
|
154951
155226
|
}
|
|
@@ -155036,7 +155311,7 @@ static unique_ptr<Expression> PlanCorrelatedSubquery(Binder &binder, BoundSubque
|
|
|
155036
155311
|
// LHS
|
|
155037
155312
|
delim_join->AddChild(move(root));
|
|
155038
155313
|
// RHS
|
|
155039
|
-
FlattenDependentJoins flatten(binder, correlated_columns);
|
|
155314
|
+
FlattenDependentJoins flatten(binder, correlated_columns, true);
|
|
155040
155315
|
flatten.DetectCorrelatedExpressions(plan.get());
|
|
155041
155316
|
auto dependent_join = flatten.PushDownDependentJoin(move(plan));
|
|
155042
155317
|
|
|
@@ -158922,6 +159197,10 @@ bool BoundAggregateExpression::Equals(const BaseExpression *other_p) const {
|
|
|
158922
159197
|
return true;
|
|
158923
159198
|
}
|
|
158924
159199
|
|
|
159200
|
+
bool BoundAggregateExpression::PropagatesNullValues() const {
|
|
159201
|
+
return !function.propagates_null_values ? false : Expression::PropagatesNullValues();
|
|
159202
|
+
}
|
|
159203
|
+
|
|
158925
159204
|
unique_ptr<Expression> BoundAggregateExpression::Copy() {
|
|
158926
159205
|
vector<unique_ptr<Expression>> new_children;
|
|
158927
159206
|
for (auto &child : children) {
|
|
@@ -159233,6 +159512,7 @@ bool BoundComparisonExpression::Equals(const BaseExpression *other_p) const {
|
|
|
159233
159512
|
if (!Expression::Equals(right.get(), other->right.get())) {
|
|
159234
159513
|
return false;
|
|
159235
159514
|
}
|
|
159515
|
+
|
|
159236
159516
|
return true;
|
|
159237
159517
|
}
|
|
159238
159518
|
|
|
@@ -159272,6 +159552,10 @@ bool BoundConjunctionExpression::Equals(const BaseExpression *other_p) const {
|
|
|
159272
159552
|
return ExpressionUtil::SetEquals(children, other->children);
|
|
159273
159553
|
}
|
|
159274
159554
|
|
|
159555
|
+
bool BoundConjunctionExpression::PropagatesNullValues() const {
|
|
159556
|
+
return false;
|
|
159557
|
+
}
|
|
159558
|
+
|
|
159275
159559
|
unique_ptr<Expression> BoundConjunctionExpression::Copy() {
|
|
159276
159560
|
auto copy = make_unique<BoundConjunctionExpression>(type);
|
|
159277
159561
|
for (auto &expr : children) {
|
|
@@ -159347,6 +159631,9 @@ string BoundFunctionExpression::ToString() const {
|
|
|
159347
159631
|
return FunctionExpression::ToString<BoundFunctionExpression, Expression>(*this, string(), function.name,
|
|
159348
159632
|
is_operator);
|
|
159349
159633
|
}
|
|
159634
|
+
bool BoundFunctionExpression::PropagatesNullValues() const {
|
|
159635
|
+
return !function.propagates_null_values ? false : Expression::PropagatesNullValues();
|
|
159636
|
+
}
|
|
159350
159637
|
|
|
159351
159638
|
hash_t BoundFunctionExpression::Hash() const {
|
|
159352
159639
|
hash_t result = Expression::Hash();
|
|
@@ -159536,6 +159823,11 @@ unique_ptr<Expression> BoundSubqueryExpression::Copy() {
|
|
|
159536
159823
|
throw SerializationException("Cannot copy BoundSubqueryExpression");
|
|
159537
159824
|
}
|
|
159538
159825
|
|
|
159826
|
+
bool BoundSubqueryExpression::PropagatesNullValues() const {
|
|
159827
|
+
// TODO this can be optimized further by checking the actual subquery node
|
|
159828
|
+
return false;
|
|
159829
|
+
}
|
|
159830
|
+
|
|
159539
159831
|
} // namespace duckdb
|
|
159540
159832
|
|
|
159541
159833
|
|
|
@@ -159745,6 +160037,21 @@ bool Expression::HasSideEffects() const {
|
|
|
159745
160037
|
return has_side_effects;
|
|
159746
160038
|
}
|
|
159747
160039
|
|
|
160040
|
+
bool Expression::PropagatesNullValues() const {
|
|
160041
|
+
if (type == ExpressionType::OPERATOR_IS_NULL || type == ExpressionType::OPERATOR_IS_NOT_NULL ||
|
|
160042
|
+
type == ExpressionType::COMPARE_NOT_DISTINCT_FROM || type == ExpressionType::COMPARE_DISTINCT_FROM ||
|
|
160043
|
+
type == ExpressionType::CONJUNCTION_OR || type == ExpressionType::CONJUNCTION_AND) {
|
|
160044
|
+
return false;
|
|
160045
|
+
}
|
|
160046
|
+
bool propagate_null_values = true;
|
|
160047
|
+
ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) {
|
|
160048
|
+
if (!child.PropagatesNullValues()) {
|
|
160049
|
+
propagate_null_values = false;
|
|
160050
|
+
}
|
|
160051
|
+
});
|
|
160052
|
+
return propagate_null_values;
|
|
160053
|
+
}
|
|
160054
|
+
|
|
159748
160055
|
bool Expression::IsFoldable() const {
|
|
159749
160056
|
bool is_foldable = true;
|
|
159750
160057
|
ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) {
|
|
@@ -161250,7 +161557,8 @@ string IsNotNullFilter::ToString(const string &column_name) {
|
|
|
161250
161557
|
namespace duckdb {
|
|
161251
161558
|
|
|
161252
161559
|
unique_ptr<Expression> JoinCondition::CreateExpression(JoinCondition cond) {
|
|
161253
|
-
|
|
161560
|
+
auto bound_comparison = make_unique<BoundComparisonExpression>(cond.comparison, move(cond.left), move(cond.right));
|
|
161561
|
+
return move(bound_comparison);
|
|
161254
161562
|
}
|
|
161255
161563
|
|
|
161256
161564
|
JoinSide JoinSide::CombineJoinSide(JoinSide left, JoinSide right) {
|
|
@@ -162513,8 +162821,9 @@ public:
|
|
|
162513
162821
|
|
|
162514
162822
|
namespace duckdb {
|
|
162515
162823
|
|
|
162516
|
-
FlattenDependentJoins::FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated
|
|
162517
|
-
|
|
162824
|
+
FlattenDependentJoins::FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated,
|
|
162825
|
+
bool any_join)
|
|
162826
|
+
: binder(binder), correlated_columns(correlated), any_join(any_join) {
|
|
162518
162827
|
for (idx_t i = 0; i < correlated_columns.size(); i++) {
|
|
162519
162828
|
auto &col = correlated_columns[i];
|
|
162520
162829
|
correlated_map[col.binding] = i;
|
|
@@ -162543,7 +162852,8 @@ bool FlattenDependentJoins::DetectCorrelatedExpressions(LogicalOperator *op) {
|
|
|
162543
162852
|
}
|
|
162544
162853
|
|
|
162545
162854
|
unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoin(unique_ptr<LogicalOperator> plan) {
|
|
162546
|
-
|
|
162855
|
+
bool propagate_null_values = true;
|
|
162856
|
+
auto result = PushDownDependentJoinInternal(move(plan), propagate_null_values);
|
|
162547
162857
|
if (!replacement_map.empty()) {
|
|
162548
162858
|
// check if we have to replace any COUNT aggregates into "CASE WHEN X IS NULL THEN 0 ELSE COUNT END"
|
|
162549
162859
|
RewriteCountAggregates aggr(replacement_map);
|
|
@@ -162552,7 +162862,23 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoin(unique_
|
|
|
162552
162862
|
return result;
|
|
162553
162863
|
}
|
|
162554
162864
|
|
|
162555
|
-
|
|
162865
|
+
bool SubqueryDependentFilter(Expression *expr) {
|
|
162866
|
+
if (expr->expression_class == ExpressionClass::BOUND_CONJUNCTION &&
|
|
162867
|
+
expr->GetExpressionType() == ExpressionType::CONJUNCTION_AND) {
|
|
162868
|
+
auto bound_conjuction = (BoundConjunctionExpression *)expr;
|
|
162869
|
+
for (auto &child : bound_conjuction->children) {
|
|
162870
|
+
if (SubqueryDependentFilter(child.get())) {
|
|
162871
|
+
return true;
|
|
162872
|
+
}
|
|
162873
|
+
}
|
|
162874
|
+
}
|
|
162875
|
+
if (expr->expression_class == ExpressionClass::BOUND_SUBQUERY) {
|
|
162876
|
+
return true;
|
|
162877
|
+
}
|
|
162878
|
+
return false;
|
|
162879
|
+
}
|
|
162880
|
+
unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan,
|
|
162881
|
+
bool &parent_propagate_null_values) {
|
|
162556
162882
|
// first check if the logical operator has correlated expressions
|
|
162557
162883
|
auto entry = has_correlated_expressions.find(plan.get());
|
|
162558
162884
|
D_ASSERT(entry != has_correlated_expressions.end());
|
|
@@ -162573,7 +162899,11 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162573
162899
|
case LogicalOperatorType::LOGICAL_FILTER: {
|
|
162574
162900
|
// filter
|
|
162575
162901
|
// first we flatten the dependent join in the child of the filter
|
|
162576
|
-
|
|
162902
|
+
for (auto &expr : plan->expressions) {
|
|
162903
|
+
any_join |= SubqueryDependentFilter(expr.get());
|
|
162904
|
+
}
|
|
162905
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162906
|
+
|
|
162577
162907
|
// then we replace any correlated expressions with the corresponding entry in the correlated_map
|
|
162578
162908
|
RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
|
|
162579
162909
|
rewriter.VisitOperator(*plan);
|
|
@@ -162582,7 +162912,11 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162582
162912
|
case LogicalOperatorType::LOGICAL_PROJECTION: {
|
|
162583
162913
|
// projection
|
|
162584
162914
|
// first we flatten the dependent join in the child of the projection
|
|
162585
|
-
|
|
162915
|
+
for (auto &expr : plan->expressions) {
|
|
162916
|
+
parent_propagate_null_values &= expr->PropagatesNullValues();
|
|
162917
|
+
}
|
|
162918
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162919
|
+
|
|
162586
162920
|
// then we replace any correlated expressions with the corresponding entry in the correlated_map
|
|
162587
162921
|
RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
|
|
162588
162922
|
rewriter.VisitOperator(*plan);
|
|
@@ -162603,7 +162937,10 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162603
162937
|
auto &aggr = (LogicalAggregate &)*plan;
|
|
162604
162938
|
// aggregate and group by
|
|
162605
162939
|
// first we flatten the dependent join in the child of the projection
|
|
162606
|
-
|
|
162940
|
+
for (auto &expr : plan->expressions) {
|
|
162941
|
+
parent_propagate_null_values &= expr->PropagatesNullValues();
|
|
162942
|
+
}
|
|
162943
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162607
162944
|
// then we replace any correlated expressions with the corresponding entry in the correlated_map
|
|
162608
162945
|
RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
|
|
162609
162946
|
rewriter.VisitOperator(*plan);
|
|
@@ -162620,11 +162957,18 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162620
162957
|
// we have to perform a LEFT OUTER JOIN between the result of this aggregate and the delim scan
|
|
162621
162958
|
// FIXME: this does not always have to be a LEFT OUTER JOIN, depending on whether aggr.expressions return
|
|
162622
162959
|
// NULL or a value
|
|
162623
|
-
|
|
162960
|
+
unique_ptr<LogicalComparisonJoin> join = make_unique<LogicalComparisonJoin>(JoinType::INNER);
|
|
162961
|
+
for (auto &aggr_exp : aggr.expressions) {
|
|
162962
|
+
auto b_aggr_exp = (BoundAggregateExpression *)aggr_exp.get();
|
|
162963
|
+
if (!b_aggr_exp->PropagatesNullValues() || any_join || !parent_propagate_null_values) {
|
|
162964
|
+
join = make_unique<LogicalComparisonJoin>(JoinType::LEFT);
|
|
162965
|
+
break;
|
|
162966
|
+
}
|
|
162967
|
+
}
|
|
162624
162968
|
auto left_index = binder.GenerateTableIndex();
|
|
162625
162969
|
auto delim_scan = make_unique<LogicalDelimGet>(left_index, delim_types);
|
|
162626
|
-
|
|
162627
|
-
|
|
162970
|
+
join->children.push_back(move(delim_scan));
|
|
162971
|
+
join->children.push_back(move(plan));
|
|
162628
162972
|
for (idx_t i = 0; i < correlated_columns.size(); i++) {
|
|
162629
162973
|
JoinCondition cond;
|
|
162630
162974
|
cond.left =
|
|
@@ -162632,9 +162976,8 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162632
162976
|
cond.right = make_unique<BoundColumnRefExpression>(
|
|
162633
162977
|
correlated_columns[i].type,
|
|
162634
162978
|
ColumnBinding(aggr.group_index, (aggr.groups.size() - correlated_columns.size()) + i));
|
|
162635
|
-
cond.comparison = ExpressionType::
|
|
162636
|
-
cond
|
|
162637
|
-
left_outer_join->conditions.push_back(move(cond));
|
|
162979
|
+
cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
|
|
162980
|
+
join->conditions.push_back(move(cond));
|
|
162638
162981
|
}
|
|
162639
162982
|
// for any COUNT aggregate we replace references to the column with: CASE WHEN COUNT(*) IS NULL THEN 0
|
|
162640
162983
|
// ELSE COUNT(*) END
|
|
@@ -162652,7 +162995,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162652
162995
|
base_binding.table_index = left_index;
|
|
162653
162996
|
this->delim_offset = base_binding.column_index = 0;
|
|
162654
162997
|
this->data_offset = 0;
|
|
162655
|
-
return move(
|
|
162998
|
+
return move(join);
|
|
162656
162999
|
} else {
|
|
162657
163000
|
// update the delim_index
|
|
162658
163001
|
base_binding.table_index = aggr.group_index;
|
|
@@ -162668,20 +163011,20 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162668
163011
|
bool right_has_correlation = has_correlated_expressions.find(plan->children[1].get())->second;
|
|
162669
163012
|
if (!right_has_correlation) {
|
|
162670
163013
|
// only left has correlation: push into left
|
|
162671
|
-
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
|
|
163014
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162672
163015
|
return plan;
|
|
162673
163016
|
}
|
|
162674
163017
|
if (!left_has_correlation) {
|
|
162675
163018
|
// only right has correlation: push into right
|
|
162676
|
-
plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
|
|
163019
|
+
plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
|
|
162677
163020
|
return plan;
|
|
162678
163021
|
}
|
|
162679
163022
|
// both sides have correlation
|
|
162680
163023
|
// turn into an inner join
|
|
162681
163024
|
auto join = make_unique<LogicalComparisonJoin>(JoinType::INNER);
|
|
162682
|
-
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
|
|
163025
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162683
163026
|
auto left_binding = this->base_binding;
|
|
162684
|
-
plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
|
|
163027
|
+
plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
|
|
162685
163028
|
// add the correlated columns to the join conditions
|
|
162686
163029
|
for (idx_t i = 0; i < correlated_columns.size(); i++) {
|
|
162687
163030
|
JoinCondition cond;
|
|
@@ -162689,8 +163032,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162689
163032
|
correlated_columns[i].type, ColumnBinding(left_binding.table_index, left_binding.column_index + i));
|
|
162690
163033
|
cond.right = make_unique<BoundColumnRefExpression>(
|
|
162691
163034
|
correlated_columns[i].type, ColumnBinding(base_binding.table_index, base_binding.column_index + i));
|
|
162692
|
-
cond.comparison = ExpressionType::
|
|
162693
|
-
cond.null_values_are_equal = true;
|
|
163035
|
+
cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
|
|
162694
163036
|
join->conditions.push_back(move(cond));
|
|
162695
163037
|
}
|
|
162696
163038
|
join->children.push_back(move(plan->children[0]));
|
|
@@ -162709,26 +163051,30 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162709
163051
|
// inner join
|
|
162710
163052
|
if (!right_has_correlation) {
|
|
162711
163053
|
// only left has correlation: push into left
|
|
162712
|
-
plan->children[0] =
|
|
163054
|
+
plan->children[0] =
|
|
163055
|
+
PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162713
163056
|
return plan;
|
|
162714
163057
|
}
|
|
162715
163058
|
if (!left_has_correlation) {
|
|
162716
163059
|
// only right has correlation: push into right
|
|
162717
|
-
plan->children[1] =
|
|
163060
|
+
plan->children[1] =
|
|
163061
|
+
PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
|
|
162718
163062
|
return plan;
|
|
162719
163063
|
}
|
|
162720
163064
|
} else if (join.join_type == JoinType::LEFT) {
|
|
162721
163065
|
// left outer join
|
|
162722
163066
|
if (!right_has_correlation) {
|
|
162723
163067
|
// only left has correlation: push into left
|
|
162724
|
-
plan->children[0] =
|
|
163068
|
+
plan->children[0] =
|
|
163069
|
+
PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162725
163070
|
return plan;
|
|
162726
163071
|
}
|
|
162727
163072
|
} else if (join.join_type == JoinType::RIGHT) {
|
|
162728
163073
|
// left outer join
|
|
162729
163074
|
if (!left_has_correlation) {
|
|
162730
163075
|
// only right has correlation: push into right
|
|
162731
|
-
plan->children[1] =
|
|
163076
|
+
plan->children[1] =
|
|
163077
|
+
PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
|
|
162732
163078
|
return plan;
|
|
162733
163079
|
}
|
|
162734
163080
|
} else if (join.join_type == JoinType::MARK) {
|
|
@@ -162736,7 +163082,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162736
163082
|
throw Exception("MARK join with correlation in RHS not supported");
|
|
162737
163083
|
}
|
|
162738
163084
|
// push the child into the LHS
|
|
162739
|
-
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
|
|
163085
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162740
163086
|
// rewrite expressions in the join conditions
|
|
162741
163087
|
RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
|
|
162742
163088
|
rewriter.VisitOperator(*plan);
|
|
@@ -162746,9 +163092,9 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162746
163092
|
}
|
|
162747
163093
|
// both sides have correlation
|
|
162748
163094
|
// push into both sides
|
|
162749
|
-
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
|
|
163095
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162750
163096
|
auto left_binding = this->base_binding;
|
|
162751
|
-
plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
|
|
163097
|
+
plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
|
|
162752
163098
|
auto right_binding = this->base_binding;
|
|
162753
163099
|
// NOTE: for OUTER JOINS it matters what the BASE BINDING is after the join
|
|
162754
163100
|
// for the LEFT OUTER JOIN, we want the LEFT side to be the base binding after we push
|
|
@@ -162769,8 +163115,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162769
163115
|
JoinCondition cond;
|
|
162770
163116
|
cond.left = move(left);
|
|
162771
163117
|
cond.right = move(right);
|
|
162772
|
-
cond.comparison = ExpressionType::
|
|
162773
|
-
cond.null_values_are_equal = true;
|
|
163118
|
+
cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
|
|
162774
163119
|
|
|
162775
163120
|
auto &comparison_join = (LogicalComparisonJoin &)join;
|
|
162776
163121
|
comparison_join.conditions.push_back(move(cond));
|
|
@@ -162796,7 +163141,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162796
163141
|
if (limit.limit) {
|
|
162797
163142
|
throw ParserException("Non-constant limit not supported in correlated subquery");
|
|
162798
163143
|
}
|
|
162799
|
-
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
|
|
163144
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162800
163145
|
if (limit.limit_val == 0) {
|
|
162801
163146
|
// limit = 0 means we return zero columns here
|
|
162802
163147
|
return plan;
|
|
@@ -162811,7 +163156,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162811
163156
|
case LogicalOperatorType::LOGICAL_WINDOW: {
|
|
162812
163157
|
auto &window = (LogicalWindow &)*plan;
|
|
162813
163158
|
// push into children
|
|
162814
|
-
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
|
|
163159
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162815
163160
|
// add the correlated columns to the PARTITION BY clauses in the Window
|
|
162816
163161
|
for (auto &expr : window.expressions) {
|
|
162817
163162
|
D_ASSERT(expr->GetExpressionClass() == ExpressionClass::BOUND_WINDOW);
|
|
@@ -162843,7 +163188,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
|
|
|
162843
163188
|
case LogicalOperatorType::LOGICAL_EXPRESSION_GET: {
|
|
162844
163189
|
// expression get
|
|
162845
163190
|
// first we flatten the dependent join in the child
|
|
162846
|
-
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
|
|
163191
|
+
plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
|
|
162847
163192
|
// then we replace any correlated expressions with the corresponding entry in the correlated_map
|
|
162848
163193
|
RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
|
|
162849
163194
|
rewriter.VisitOperator(*plan);
|