duckdb 0.3.3-dev1350.0 → 0.3.3-dev1379.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/src/duckdb.cpp CHANGED
@@ -4276,7 +4276,19 @@ void CatalogSet::CleanupEntry(CatalogEntry *catalog_entry) {
4276
4276
  // delete the entry from the dependency manager, if it is not deleted yet
4277
4277
  catalog_entry->catalog->dependency_manager->EraseObject(catalog_entry);
4278
4278
  }
4279
- catalog_entry->parent->child = move(catalog_entry->child);
4279
+ auto parent = catalog_entry->parent;
4280
+ parent->child = move(catalog_entry->child);
4281
+ if (parent->deleted && !parent->child && !parent->parent) {
4282
+ auto mapping_entry = mapping.find(parent->name);
4283
+ D_ASSERT(mapping_entry != mapping.end());
4284
+ auto index = mapping_entry->second->index;
4285
+ auto entry = entries.find(index);
4286
+ D_ASSERT(entry != entries.end());
4287
+ if (entry->second.get() == parent) {
4288
+ mapping.erase(mapping_entry);
4289
+ entries.erase(entry);
4290
+ }
4291
+ }
4280
4292
  }
4281
4293
  }
4282
4294
 
@@ -26517,6 +26529,7 @@ static void TemplatedMatch(DataChunk &columns, VectorData col_data[], const RowL
26517
26529
  switch (predicates[col_no]) {
26518
26530
  case ExpressionType::COMPARE_EQUAL:
26519
26531
  case ExpressionType::COMPARE_NOT_DISTINCT_FROM:
26532
+ case ExpressionType::COMPARE_DISTINCT_FROM:
26520
26533
  TemplatedMatchOp<Equals, NO_MATCH_SEL>(vec, col, layout, rows, sel, count, col_no, no_match,
26521
26534
  no_match_count);
26522
26535
  break;
@@ -47524,7 +47537,7 @@ namespace duckdb {
47524
47537
  //! JoinCondition represents a left-right comparison join condition
47525
47538
  struct JoinCondition {
47526
47539
  public:
47527
- JoinCondition() : null_values_are_equal(false) {
47540
+ JoinCondition() {
47528
47541
  }
47529
47542
 
47530
47543
  //! Turns the JoinCondition into an expression; note that this destroys the JoinCondition as the expression inherits
@@ -47535,17 +47548,14 @@ public:
47535
47548
  unique_ptr<Expression> left;
47536
47549
  unique_ptr<Expression> right;
47537
47550
  ExpressionType comparison;
47538
- //! NULL values are equal for just THIS JoinCondition (instead of the entire join).
47539
- //! This is only supported by the HashJoin and can only be used in equality comparisons.
47540
- bool null_values_are_equal = false;
47541
47551
  };
47542
47552
 
47543
47553
  class JoinSide {
47544
47554
  public:
47545
- enum join_value : uint8_t { NONE, LEFT, RIGHT, BOTH };
47555
+ enum JoinValue : uint8_t { NONE, LEFT, RIGHT, BOTH };
47546
47556
 
47547
47557
  JoinSide() = default;
47548
- constexpr JoinSide(join_value val) : value(val) { // NOLINT: Allow implicit conversion from `join_value`
47558
+ constexpr JoinSide(JoinValue val) : value(val) { // NOLINT: Allow implicit conversion from `join_value`
47549
47559
  }
47550
47560
 
47551
47561
  bool operator==(JoinSide a) const {
@@ -47564,7 +47574,7 @@ public:
47564
47574
  unordered_set<idx_t> &right_bindings);
47565
47575
 
47566
47576
  private:
47567
- join_value value;
47577
+ JoinValue value;
47568
47578
  };
47569
47579
 
47570
47580
  } // namespace duckdb
@@ -50972,7 +50982,8 @@ JoinHashTable::JoinHashTable(BufferManager &buffer_manager, const vector<JoinCon
50972
50982
  D_ASSERT(condition.left->return_type == condition.right->return_type);
50973
50983
  auto type = condition.left->return_type;
50974
50984
  if (condition.comparison == ExpressionType::COMPARE_EQUAL ||
50975
- condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
50985
+ condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM ||
50986
+ condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM) {
50976
50987
  // all equality conditions should be at the front
50977
50988
  // all other conditions at the back
50978
50989
  // this assert checks that
@@ -50981,10 +50992,8 @@ JoinHashTable::JoinHashTable(BufferManager &buffer_manager, const vector<JoinCon
50981
50992
  }
50982
50993
 
50983
50994
  predicates.push_back(condition.comparison);
50984
- null_values_are_equal.push_back(condition.null_values_are_equal ||
50995
+ null_values_are_equal.push_back(condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM ||
50985
50996
  condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM);
50986
- D_ASSERT(!condition.null_values_are_equal ||
50987
- (condition.null_values_are_equal && condition.comparison == ExpressionType::COMPARE_EQUAL));
50988
50997
 
50989
50998
  condition_types.push_back(type);
50990
50999
  }
@@ -68056,7 +68065,7 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
68056
68065
  }
68057
68066
  // with equality condition and null values not equal
68058
68067
  for (auto &&condition : op.conditions) {
68059
- if (condition.comparison != ExpressionType::COMPARE_EQUAL || condition.null_values_are_equal) {
68068
+ if (condition.comparison != ExpressionType::COMPARE_EQUAL) {
68060
68069
  return;
68061
68070
  }
68062
68071
  }
@@ -68177,10 +68186,6 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalComparison
68177
68186
  default:
68178
68187
  throw NotImplementedException("Unimplemented comparison join");
68179
68188
  }
68180
- if (cond.null_values_are_equal) {
68181
- D_ASSERT(cond.comparison == ExpressionType::COMPARE_EQUAL ||
68182
- cond.comparison == ExpressionType::COMPARE_DISTINCT_FROM);
68183
- }
68184
68189
  }
68185
68190
 
68186
68191
  unique_ptr<PhysicalOperator> plan;
@@ -70592,10 +70597,9 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalSetOperati
70592
70597
  // create equality condition for all columns
70593
70598
  for (idx_t i = 0; i < types.size(); i++) {
70594
70599
  JoinCondition cond;
70595
- cond.comparison = ExpressionType::COMPARE_EQUAL;
70596
70600
  cond.left = make_unique<BoundReferenceExpression>(types[i], i);
70597
70601
  cond.right = make_unique<BoundReferenceExpression>(types[i], i);
70598
- cond.null_values_are_equal = true;
70602
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
70599
70603
  conditions.push_back(move(cond));
70600
70604
  }
70601
70605
  // EXCEPT is ANTI join
@@ -72485,22 +72489,22 @@ AggregateFunction GetAverageAggregate(PhysicalType type) {
72485
72489
  switch (type) {
72486
72490
  case PhysicalType::INT16:
72487
72491
  return AggregateFunction::UnaryAggregate<AvgState<int64_t>, int16_t, double, IntegerAverageOperation>(
72488
- LogicalType::SMALLINT, LogicalType::DOUBLE);
72492
+ LogicalType::SMALLINT, LogicalType::DOUBLE, true);
72489
72493
  case PhysicalType::INT32: {
72490
72494
  auto function =
72491
72495
  AggregateFunction::UnaryAggregate<AvgState<hugeint_t>, int32_t, double, IntegerAverageOperationHugeint>(
72492
- LogicalType::INTEGER, LogicalType::DOUBLE);
72496
+ LogicalType::INTEGER, LogicalType::DOUBLE, true);
72493
72497
  return function;
72494
72498
  }
72495
72499
  case PhysicalType::INT64: {
72496
72500
  auto function =
72497
72501
  AggregateFunction::UnaryAggregate<AvgState<hugeint_t>, int64_t, double, IntegerAverageOperationHugeint>(
72498
- LogicalType::BIGINT, LogicalType::DOUBLE);
72502
+ LogicalType::BIGINT, LogicalType::DOUBLE, true);
72499
72503
  return function;
72500
72504
  }
72501
72505
  case PhysicalType::INT128:
72502
72506
  return AggregateFunction::UnaryAggregate<AvgState<hugeint_t>, hugeint_t, double, HugeintAverageOperation>(
72503
- LogicalType::HUGEINT, LogicalType::DOUBLE);
72507
+ LogicalType::HUGEINT, LogicalType::DOUBLE, true);
72504
72508
  default:
72505
72509
  throw InternalException("Unimplemented average aggregate");
72506
72510
  }
@@ -72520,18 +72524,18 @@ unique_ptr<FunctionData> BindDecimalAvg(ClientContext &context, AggregateFunctio
72520
72524
  void AvgFun::RegisterFunction(BuiltinFunctions &set) {
72521
72525
  AggregateFunctionSet avg("avg");
72522
72526
  avg.AddFunction(AggregateFunction({LogicalTypeId::DECIMAL}, LogicalTypeId::DECIMAL, nullptr, nullptr, nullptr,
72523
- nullptr, nullptr, nullptr, BindDecimalAvg));
72527
+ nullptr, nullptr, true, nullptr, BindDecimalAvg));
72524
72528
  avg.AddFunction(GetAverageAggregate(PhysicalType::INT16));
72525
72529
  avg.AddFunction(GetAverageAggregate(PhysicalType::INT32));
72526
72530
  avg.AddFunction(GetAverageAggregate(PhysicalType::INT64));
72527
72531
  avg.AddFunction(GetAverageAggregate(PhysicalType::INT128));
72528
72532
  avg.AddFunction(AggregateFunction::UnaryAggregate<AvgState<double>, double, double, NumericAverageOperation>(
72529
- LogicalType::DOUBLE, LogicalType::DOUBLE));
72533
+ LogicalType::DOUBLE, LogicalType::DOUBLE, true));
72530
72534
  set.AddFunction(avg);
72531
72535
 
72532
72536
  AggregateFunctionSet favg("favg");
72533
72537
  favg.AddFunction(AggregateFunction::UnaryAggregate<KahanAvgState, double, double, KahanAverageOperation>(
72534
- LogicalType::DOUBLE, LogicalType::DOUBLE));
72538
+ LogicalType::DOUBLE, LogicalType::DOUBLE, true));
72535
72539
  set.AddFunction(favg);
72536
72540
  }
72537
72541
 
@@ -74460,24 +74464,24 @@ static AggregateFunction GetUnaryAggregate(LogicalType type) {
74460
74464
  case LogicalTypeId::TIMESTAMP_TZ:
74461
74465
  case LogicalTypeId::TIME_TZ:
74462
74466
  case LogicalTypeId::BIGINT:
74463
- return AggregateFunction::UnaryAggregate<MinMaxState<int64_t>, int64_t, int64_t, OP>(type, type);
74467
+ return AggregateFunction::UnaryAggregate<MinMaxState<int64_t>, int64_t, int64_t, OP>(type, type, true);
74464
74468
  case LogicalTypeId::UTINYINT:
74465
- return AggregateFunction::UnaryAggregate<MinMaxState<uint8_t>, uint8_t, uint8_t, OP>(type, type);
74469
+ return AggregateFunction::UnaryAggregate<MinMaxState<uint8_t>, uint8_t, uint8_t, OP>(type, type, true);
74466
74470
  case LogicalTypeId::USMALLINT:
74467
- return AggregateFunction::UnaryAggregate<MinMaxState<uint16_t>, uint16_t, uint16_t, OP>(type, type);
74471
+ return AggregateFunction::UnaryAggregate<MinMaxState<uint16_t>, uint16_t, uint16_t, OP>(type, type, true);
74468
74472
  case LogicalTypeId::UINTEGER:
74469
- return AggregateFunction::UnaryAggregate<MinMaxState<uint32_t>, uint32_t, uint32_t, OP>(type, type);
74473
+ return AggregateFunction::UnaryAggregate<MinMaxState<uint32_t>, uint32_t, uint32_t, OP>(type, type, true);
74470
74474
  case LogicalTypeId::UBIGINT:
74471
- return AggregateFunction::UnaryAggregate<MinMaxState<uint64_t>, uint64_t, uint64_t, OP>(type, type);
74475
+ return AggregateFunction::UnaryAggregate<MinMaxState<uint64_t>, uint64_t, uint64_t, OP>(type, type, true);
74472
74476
  case LogicalTypeId::HUGEINT:
74473
74477
  case LogicalTypeId::UUID:
74474
- return AggregateFunction::UnaryAggregate<MinMaxState<hugeint_t>, hugeint_t, hugeint_t, OP>(type, type);
74478
+ return AggregateFunction::UnaryAggregate<MinMaxState<hugeint_t>, hugeint_t, hugeint_t, OP>(type, type, true);
74475
74479
  case LogicalTypeId::FLOAT:
74476
- return AggregateFunction::UnaryAggregate<MinMaxState<float>, float, float, OP>(type, type);
74480
+ return AggregateFunction::UnaryAggregate<MinMaxState<float>, float, float, OP>(type, type, true);
74477
74481
  case LogicalTypeId::DOUBLE:
74478
- return AggregateFunction::UnaryAggregate<MinMaxState<double>, double, double, OP>(type, type);
74482
+ return AggregateFunction::UnaryAggregate<MinMaxState<double>, double, double, OP>(type, type, true);
74479
74483
  case LogicalTypeId::INTERVAL:
74480
- return AggregateFunction::UnaryAggregate<MinMaxState<interval_t>, interval_t, interval_t, OP>(type, type);
74484
+ return AggregateFunction::UnaryAggregate<MinMaxState<interval_t>, interval_t, interval_t, OP>(type, type, true);
74481
74485
  default:
74482
74486
  throw InternalException("Unimplemented type for min/max aggregate");
74483
74487
  }
@@ -74958,7 +74962,7 @@ static void AddMinMaxOperator(AggregateFunctionSet &set) {
74958
74962
  AggregateFunction::UnaryAggregateDestructor<MinMaxState<string_t>, string_t, string_t, OP_STRING>(
74959
74963
  type.id(), type.id()));
74960
74964
  } else if (type.id() == LogicalTypeId::DECIMAL) {
74961
- set.AddFunction(AggregateFunction({type}, type, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
74965
+ set.AddFunction(AggregateFunction({type}, type, nullptr, nullptr, nullptr, nullptr, nullptr, false, nullptr,
74962
74966
  BindDecimalMinMax<OP>));
74963
74967
  } else if (type.id() == LogicalTypeId::LIST || type.id() == LogicalTypeId::MAP ||
74964
74968
  type.id() == LogicalTypeId::STRUCT) {
@@ -75387,13 +75391,13 @@ unique_ptr<BaseStatistics> SumPropagateStats(ClientContext &context, BoundAggreg
75387
75391
  case PhysicalType::INT32:
75388
75392
  expr.function =
75389
75393
  AggregateFunction::UnaryAggregate<SumState<int64_t>, int32_t, hugeint_t, IntegerSumOperation>(
75390
- LogicalType::INTEGER, LogicalType::HUGEINT);
75394
+ LogicalType::INTEGER, LogicalType::HUGEINT, true);
75391
75395
  expr.function.name = "sum";
75392
75396
  break;
75393
75397
  case PhysicalType::INT64:
75394
75398
  expr.function =
75395
75399
  AggregateFunction::UnaryAggregate<SumState<int64_t>, int64_t, hugeint_t, IntegerSumOperation>(
75396
- LogicalType::BIGINT, LogicalType::HUGEINT);
75400
+ LogicalType::BIGINT, LogicalType::HUGEINT, true);
75397
75401
  expr.function.name = "sum";
75398
75402
  break;
75399
75403
  default:
@@ -75407,24 +75411,24 @@ AggregateFunction SumFun::GetSumAggregate(PhysicalType type) {
75407
75411
  switch (type) {
75408
75412
  case PhysicalType::INT16:
75409
75413
  return AggregateFunction::UnaryAggregate<SumState<int64_t>, int16_t, hugeint_t, IntegerSumOperation>(
75410
- LogicalType::SMALLINT, LogicalType::HUGEINT);
75414
+ LogicalType::SMALLINT, LogicalType::HUGEINT, true);
75411
75415
  case PhysicalType::INT32: {
75412
75416
  auto function =
75413
75417
  AggregateFunction::UnaryAggregate<SumState<hugeint_t>, int32_t, hugeint_t, SumToHugeintOperation>(
75414
- LogicalType::INTEGER, LogicalType::HUGEINT);
75418
+ LogicalType::INTEGER, LogicalType::HUGEINT, true);
75415
75419
  function.statistics = SumPropagateStats;
75416
75420
  return function;
75417
75421
  }
75418
75422
  case PhysicalType::INT64: {
75419
75423
  auto function =
75420
75424
  AggregateFunction::UnaryAggregate<SumState<hugeint_t>, int64_t, hugeint_t, SumToHugeintOperation>(
75421
- LogicalType::BIGINT, LogicalType::HUGEINT);
75425
+ LogicalType::BIGINT, LogicalType::HUGEINT, true);
75422
75426
  function.statistics = SumPropagateStats;
75423
75427
  return function;
75424
75428
  }
75425
75429
  case PhysicalType::INT128:
75426
75430
  return AggregateFunction::UnaryAggregate<SumState<hugeint_t>, hugeint_t, hugeint_t, HugeintSumOperation>(
75427
- LogicalType::HUGEINT, LogicalType::HUGEINT);
75431
+ LogicalType::HUGEINT, LogicalType::HUGEINT, true);
75428
75432
  default:
75429
75433
  throw InternalException("Unimplemented sum aggregate");
75430
75434
  }
@@ -75444,20 +75448,20 @@ void SumFun::RegisterFunction(BuiltinFunctions &set) {
75444
75448
  AggregateFunctionSet sum("sum");
75445
75449
  // decimal
75446
75450
  sum.AddFunction(AggregateFunction({LogicalTypeId::DECIMAL}, LogicalTypeId::DECIMAL, nullptr, nullptr, nullptr,
75447
- nullptr, nullptr, nullptr, BindDecimalSum));
75451
+ nullptr, nullptr, true, nullptr, BindDecimalSum));
75448
75452
  sum.AddFunction(GetSumAggregate(PhysicalType::INT16));
75449
75453
  sum.AddFunction(GetSumAggregate(PhysicalType::INT32));
75450
75454
  sum.AddFunction(GetSumAggregate(PhysicalType::INT64));
75451
75455
  sum.AddFunction(GetSumAggregate(PhysicalType::INT128));
75452
75456
  sum.AddFunction(AggregateFunction::UnaryAggregate<SumState<double>, double, double, NumericSumOperation>(
75453
- LogicalType::DOUBLE, LogicalType::DOUBLE));
75457
+ LogicalType::DOUBLE, LogicalType::DOUBLE, true));
75454
75458
 
75455
75459
  set.AddFunction(sum);
75456
75460
 
75457
75461
  // fsum
75458
75462
  AggregateFunctionSet fsum("fsum");
75459
75463
  fsum.AddFunction(AggregateFunction::UnaryAggregate<KahanSumState, double, double, KahanSumOperation>(
75460
- LogicalType::DOUBLE, LogicalType::DOUBLE));
75464
+ LogicalType::DOUBLE, LogicalType::DOUBLE, true));
75461
75465
 
75462
75466
  set.AddFunction(fsum);
75463
75467
 
@@ -80122,9 +80126,9 @@ bool SimpleNamedParameterFunction::HasNamedParameters() {
80122
80126
  }
80123
80127
 
80124
80128
  BaseScalarFunction::BaseScalarFunction(string name_p, vector<LogicalType> arguments_p, LogicalType return_type_p,
80125
- bool has_side_effects, LogicalType varargs_p)
80129
+ bool has_side_effects, LogicalType varargs_p, bool propagates_null_values_p)
80126
80130
  : SimpleFunction(move(name_p), move(arguments_p), move(varargs_p)), return_type(move(return_type_p)),
80127
- has_side_effects(has_side_effects) {
80131
+ has_side_effects(has_side_effects), propagates_null_values(propagates_null_values_p) {
80128
80132
  }
80129
80133
 
80130
80134
  BaseScalarFunction::~BaseScalarFunction() {
@@ -81192,8 +81196,8 @@ void CurrentDateFun::RegisterFunction(BuiltinFunctions &set) {
81192
81196
  }
81193
81197
 
81194
81198
  void CurrentTimestampFun::RegisterFunction(BuiltinFunctions &set) {
81195
- set.AddFunction({"now", "current_timestamp"},
81196
- ScalarFunction({}, LogicalType::TIMESTAMP, CurrentTimestampFunction, false, BindCurrentTime));
81199
+ set.AddFunction({"now", "current_timestamp"}, ScalarFunction({}, LogicalType::TIMESTAMP, CurrentTimestampFunction,
81200
+ false, false, BindCurrentTime));
81197
81201
  }
81198
81202
 
81199
81203
  } // namespace duckdb
@@ -82840,9 +82844,9 @@ void AddGenericDatePartOperator(BuiltinFunctions &set, const string &name, scala
82840
82844
  scalar_function_t ts_func, scalar_function_t interval_func,
82841
82845
  function_statistics_t date_stats, function_statistics_t ts_stats) {
82842
82846
  ScalarFunctionSet operator_set(name);
82843
- operator_set.AddFunction(
82844
- ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, move(date_func), false, nullptr, nullptr, date_stats));
82845
- operator_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), false,
82847
+ operator_set.AddFunction(ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, move(date_func), false, false,
82848
+ nullptr, nullptr, date_stats));
82849
+ operator_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), false, false,
82846
82850
  nullptr, nullptr, ts_stats));
82847
82851
  operator_set.AddFunction(ScalarFunction({LogicalType::INTERVAL}, LogicalType::BIGINT, move(interval_func)));
82848
82852
  set.AddFunction(operator_set);
@@ -82861,13 +82865,13 @@ void AddGenericTimePartOperator(BuiltinFunctions &set, const string &name, scala
82861
82865
  function_statistics_t date_stats, function_statistics_t ts_stats,
82862
82866
  function_statistics_t time_stats) {
82863
82867
  ScalarFunctionSet operator_set(name);
82864
- operator_set.AddFunction(
82865
- ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, move(date_func), false, nullptr, nullptr, date_stats));
82866
- operator_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), false,
82868
+ operator_set.AddFunction(ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, move(date_func), false, false,
82869
+ nullptr, nullptr, date_stats));
82870
+ operator_set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), false, false,
82867
82871
  nullptr, nullptr, ts_stats));
82868
82872
  operator_set.AddFunction(ScalarFunction({LogicalType::INTERVAL}, LogicalType::BIGINT, move(interval_func)));
82869
- operator_set.AddFunction(
82870
- ScalarFunction({LogicalType::TIME}, LogicalType::BIGINT, move(time_func), false, nullptr, nullptr, time_stats));
82873
+ operator_set.AddFunction(ScalarFunction({LogicalType::TIME}, LogicalType::BIGINT, move(time_func), false, false,
82874
+ nullptr, nullptr, time_stats));
82871
82875
  set.AddFunction(operator_set);
82872
82876
  }
82873
82877
 
@@ -83066,7 +83070,7 @@ struct StructDatePart {
83066
83070
  static ScalarFunction GetFunction(const LogicalType &temporal_type) {
83067
83071
  auto part_type = LogicalType::LIST(LogicalType::VARCHAR);
83068
83072
  auto result_type = LogicalType::STRUCT({});
83069
- return ScalarFunction({part_type, temporal_type}, result_type, Function<INPUT_TYPE>, false, Bind);
83073
+ return ScalarFunction({part_type, temporal_type}, result_type, Function<INPUT_TYPE>, false, false, Bind);
83070
83074
  }
83071
83075
  };
83072
83076
 
@@ -84846,16 +84850,16 @@ void StrfTimeFun::RegisterFunction(BuiltinFunctions &set) {
84846
84850
  ScalarFunctionSet strftime("strftime");
84847
84851
 
84848
84852
  strftime.AddFunction(ScalarFunction({LogicalType::DATE, LogicalType::VARCHAR}, LogicalType::VARCHAR,
84849
- StrfTimeFunctionDate<false>, false, StrfTimeBindFunction<false>));
84853
+ StrfTimeFunctionDate<false>, false, false, StrfTimeBindFunction<false>));
84850
84854
 
84851
84855
  strftime.AddFunction(ScalarFunction({LogicalType::TIMESTAMP, LogicalType::VARCHAR}, LogicalType::VARCHAR,
84852
- StrfTimeFunctionTimestamp<false>, false, StrfTimeBindFunction<false>));
84856
+ StrfTimeFunctionTimestamp<false>, false, false, StrfTimeBindFunction<false>));
84853
84857
 
84854
84858
  strftime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::DATE}, LogicalType::VARCHAR,
84855
- StrfTimeFunctionDate<true>, false, StrfTimeBindFunction<true>));
84859
+ StrfTimeFunctionDate<true>, false, false, StrfTimeBindFunction<true>));
84856
84860
 
84857
84861
  strftime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP}, LogicalType::VARCHAR,
84858
- StrfTimeFunctionTimestamp<true>, false, StrfTimeBindFunction<true>));
84862
+ StrfTimeFunctionTimestamp<true>, false, false, StrfTimeBindFunction<true>));
84859
84863
 
84860
84864
  set.AddFunction(strftime);
84861
84865
  }
@@ -85418,7 +85422,7 @@ void StrpTimeFun::RegisterFunction(BuiltinFunctions &set) {
85418
85422
  ScalarFunctionSet strptime("strptime");
85419
85423
 
85420
85424
  strptime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::TIMESTAMP,
85421
- StrpTimeFunction, false, StrpTimeBindFunction));
85425
+ StrpTimeFunction, false, false, StrpTimeBindFunction));
85422
85426
 
85423
85427
  set.AddFunction(strptime);
85424
85428
  }
@@ -86068,22 +86072,23 @@ static void LeastGreatestFunction(DataChunk &args, ExpressionState &state, Vecto
86068
86072
 
86069
86073
  template <typename T, class OP>
86070
86074
  ScalarFunction GetLeastGreatestFunction(const LogicalType &type) {
86071
- return ScalarFunction({type}, type, LeastGreatestFunction<T, OP>, false, nullptr, nullptr, nullptr, nullptr, type);
86075
+ return ScalarFunction({type}, type, LeastGreatestFunction<T, OP>, true, false, nullptr, nullptr, nullptr, nullptr,
86076
+ type);
86072
86077
  }
86073
86078
 
86074
86079
  template <class OP>
86075
86080
  static void RegisterLeastGreatest(BuiltinFunctions &set, const string &fun_name) {
86076
86081
  ScalarFunctionSet fun_set(fun_name);
86077
86082
  fun_set.AddFunction(ScalarFunction({LogicalType::BIGINT}, LogicalType::BIGINT, LeastGreatestFunction<int64_t, OP>,
86078
- false, nullptr, nullptr, nullptr, nullptr, LogicalType::BIGINT));
86083
+ true, false, nullptr, nullptr, nullptr, nullptr, LogicalType::BIGINT));
86079
86084
  fun_set.AddFunction(ScalarFunction({LogicalType::HUGEINT}, LogicalType::HUGEINT,
86080
- LeastGreatestFunction<hugeint_t, OP>, false, nullptr, nullptr, nullptr, nullptr,
86081
- LogicalType::HUGEINT));
86085
+ LeastGreatestFunction<hugeint_t, OP>, true, false, nullptr, nullptr, nullptr,
86086
+ nullptr, LogicalType::HUGEINT));
86082
86087
  fun_set.AddFunction(ScalarFunction({LogicalType::DOUBLE}, LogicalType::DOUBLE, LeastGreatestFunction<double, OP>,
86083
- false, nullptr, nullptr, nullptr, nullptr, LogicalType::DOUBLE));
86088
+ true, false, nullptr, nullptr, nullptr, nullptr, LogicalType::DOUBLE));
86084
86089
  fun_set.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR,
86085
- LeastGreatestFunction<string_t, OP, true>, false, nullptr, nullptr, nullptr,
86086
- nullptr, LogicalType::VARCHAR));
86090
+ LeastGreatestFunction<string_t, OP, true>, true, false, nullptr, nullptr,
86091
+ nullptr, nullptr, LogicalType::VARCHAR));
86087
86092
 
86088
86093
  fun_set.AddFunction(GetLeastGreatestFunction<timestamp_t, OP>(LogicalType::TIMESTAMP));
86089
86094
  fun_set.AddFunction(GetLeastGreatestFunction<time_t, OP>(LogicalType::TIME));
@@ -86378,7 +86383,7 @@ static unique_ptr<FunctionData> ArraySliceBind(ClientContext &context, ScalarFun
86378
86383
  void ArraySliceFun::RegisterFunction(BuiltinFunctions &set) {
86379
86384
  // the arguments and return types are actually set in the binder function
86380
86385
  ScalarFunction fun({LogicalType::ANY, LogicalType::BIGINT, LogicalType::BIGINT}, LogicalType::ANY,
86381
- ArraySliceFunction, false, ArraySliceBind);
86386
+ ArraySliceFunction, false, false, ArraySliceBind);
86382
86387
  fun.varargs = LogicalType::ANY;
86383
86388
  set.AddFunction({"array_slice", "list_slice"}, fun);
86384
86389
  }
@@ -86594,13 +86599,13 @@ static unique_ptr<FunctionData> ListPositionBind(ClientContext &context, ScalarF
86594
86599
  ScalarFunction ListContainsFun::GetFunction() {
86595
86600
  return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::ANY}, // argument list
86596
86601
  LogicalType::BOOLEAN, // return type
86597
- ListContainsFunction, false, ListContainsBind, nullptr);
86602
+ ListContainsFunction, false, false, ListContainsBind, nullptr);
86598
86603
  }
86599
86604
 
86600
86605
  ScalarFunction ListPositionFun::GetFunction() {
86601
86606
  return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::ANY}, // argument list
86602
86607
  LogicalType::INTEGER, // return type
86603
- ListPositionFunction, false, ListPositionBind, nullptr);
86608
+ ListPositionFunction, false, false, ListPositionBind, nullptr);
86604
86609
  }
86605
86610
 
86606
86611
  void ListContainsFun::RegisterFunction(BuiltinFunctions &set) {
@@ -86776,7 +86781,7 @@ static unique_ptr<BaseStatistics> ListFlattenStats(ClientContext &context, Bound
86776
86781
 
86777
86782
  void ListFlattenFun::RegisterFunction(BuiltinFunctions &set) {
86778
86783
  ScalarFunction fun({LogicalType::LIST(LogicalType::LIST(LogicalType::ANY))}, LogicalType::LIST(LogicalType::ANY),
86779
- ListFlattenFunction, false, ListFlattenBind, nullptr, ListFlattenStats);
86784
+ ListFlattenFunction, false, false, ListFlattenBind, nullptr, ListFlattenStats);
86780
86785
  set.AddFunction({"flatten"}, fun);
86781
86786
  }
86782
86787
 
@@ -86994,7 +86999,7 @@ static unique_ptr<FunctionData> ListAggregateBind(ClientContext &context, Scalar
86994
86999
 
86995
87000
  ScalarFunction ListAggregateFun::GetFunction() {
86996
87001
  return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::VARCHAR}, LogicalType::ANY,
86997
- ListAggregateFunction, false, ListAggregateBind, nullptr, nullptr, nullptr);
87002
+ ListAggregateFunction, false, false, ListAggregateBind, nullptr, nullptr, nullptr);
86998
87003
  }
86999
87004
 
87000
87005
  void ListAggregateFun::RegisterFunction(BuiltinFunctions &set) {
@@ -87129,8 +87134,8 @@ static unique_ptr<BaseStatistics> ListConcatStats(ClientContext &context, BoundF
87129
87134
  ScalarFunction ListConcatFun::GetFunction() {
87130
87135
  // the arguments and return types are actually set in the binder function
87131
87136
  return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::LIST(LogicalType::ANY)},
87132
- LogicalType::LIST(LogicalType::ANY), ListConcatFunction, false, ListConcatBind, nullptr,
87133
- ListConcatStats);
87137
+ LogicalType::LIST(LogicalType::ANY), ListConcatFunction, false, false, ListConcatBind,
87138
+ nullptr, ListConcatStats);
87134
87139
  }
87135
87140
 
87136
87141
  void ListConcatFun::RegisterFunction(BuiltinFunctions &set) {
@@ -87368,10 +87373,10 @@ static unique_ptr<BaseStatistics> ListExtractStats(ClientContext &context, Bound
87368
87373
  void ListExtractFun::RegisterFunction(BuiltinFunctions &set) {
87369
87374
  // the arguments and return types are actually set in the binder function
87370
87375
  ScalarFunction lfun({LogicalType::LIST(LogicalType::ANY), LogicalType::BIGINT}, LogicalType::ANY,
87371
- ListExtractFunction, false, ListExtractBind, nullptr, ListExtractStats);
87376
+ ListExtractFunction, false, false, ListExtractBind, nullptr, ListExtractStats);
87372
87377
 
87373
87378
  ScalarFunction sfun({LogicalType::VARCHAR, LogicalType::INTEGER}, LogicalType::VARCHAR, ListExtractFunction, false,
87374
- nullptr);
87379
+ false, nullptr);
87375
87380
 
87376
87381
  ScalarFunctionSet list_extract("list_extract");
87377
87382
  list_extract.AddFunction(lfun);
@@ -88230,7 +88235,7 @@ void AbsFun::RegisterFunction(BuiltinFunctions &set) {
88230
88235
  ScalarFunctionSet abs("abs");
88231
88236
  for (auto &type : LogicalType::Numeric()) {
88232
88237
  if (type.id() == LogicalTypeId::DECIMAL) {
88233
- abs.AddFunction(ScalarFunction({type}, type, nullptr, false, DecimalUnaryOpBind<AbsOperator>));
88238
+ abs.AddFunction(ScalarFunction({type}, type, nullptr, false, false, DecimalUnaryOpBind<AbsOperator>));
88234
88239
  } else {
88235
88240
  abs.AddFunction(ScalarFunction({type}, type, ScalarFunction::GetScalarUnaryFunction<AbsOperator>(type)));
88236
88241
  }
@@ -88404,7 +88409,7 @@ void CeilFun::RegisterFunction(BuiltinFunctions &set) {
88404
88409
  default:
88405
88410
  throw InternalException("Unimplemented numeric type for function \"ceil\"");
88406
88411
  }
88407
- ceil.AddFunction(ScalarFunction({type}, type, func, false, bind_func));
88412
+ ceil.AddFunction(ScalarFunction({type}, type, func, false, false, bind_func));
88408
88413
  }
88409
88414
 
88410
88415
  set.AddFunction(ceil);
@@ -88460,7 +88465,7 @@ void FloorFun::RegisterFunction(BuiltinFunctions &set) {
88460
88465
  default:
88461
88466
  throw InternalException("Unimplemented numeric type for function \"floor\"");
88462
88467
  }
88463
- floor.AddFunction(ScalarFunction({type}, type, func, false, bind_func));
88468
+ floor.AddFunction(ScalarFunction({type}, type, func, false, false, bind_func));
88464
88469
  }
88465
88470
  set.AddFunction(floor);
88466
88471
  }
@@ -88667,8 +88672,9 @@ void RoundFun::RegisterFunction(BuiltinFunctions &set) {
88667
88672
  default:
88668
88673
  throw InternalException("Unimplemented numeric type for function \"floor\"");
88669
88674
  }
88670
- round.AddFunction(ScalarFunction({type}, type, round_func, false, bind_func));
88671
- round.AddFunction(ScalarFunction({type, LogicalType::INTEGER}, type, round_prec_func, false, bind_prec_func));
88675
+ round.AddFunction(ScalarFunction({type}, type, round_func, false, false, bind_func));
88676
+ round.AddFunction(
88677
+ ScalarFunction({type, LogicalType::INTEGER}, type, round_prec_func, false, false, bind_prec_func));
88672
88678
  }
88673
88679
  set.AddFunction(round);
88674
88680
  }
@@ -90267,23 +90273,23 @@ void MultiplyFun::RegisterFunction(BuiltinFunctions &set) {
90267
90273
  ScalarFunctionSet functions("*");
90268
90274
  for (auto &type : LogicalType::Numeric()) {
90269
90275
  if (type.id() == LogicalTypeId::DECIMAL) {
90270
- functions.AddFunction(ScalarFunction({type, type}, type, nullptr, false, BindDecimalMultiply));
90276
+ functions.AddFunction(ScalarFunction({type, type}, type, nullptr, true, false, BindDecimalMultiply));
90271
90277
  } else if (TypeIsIntegral(type.InternalType()) && type.id() != LogicalTypeId::HUGEINT) {
90272
90278
  functions.AddFunction(ScalarFunction(
90273
- {type, type}, type, GetScalarIntegerFunction<MultiplyOperatorOverflowCheck>(type.InternalType()), false,
90274
- nullptr, nullptr,
90279
+ {type, type}, type, GetScalarIntegerFunction<MultiplyOperatorOverflowCheck>(type.InternalType()), true,
90280
+ false, nullptr, nullptr,
90275
90281
  PropagateNumericStats<TryMultiplyOperator, MultiplyPropagateStatistics, MultiplyOperator>));
90276
90282
  } else {
90277
- functions.AddFunction(
90278
- ScalarFunction({type, type}, type, GetScalarBinaryFunction<MultiplyOperator>(type.InternalType())));
90283
+ functions.AddFunction(ScalarFunction({type, type}, type,
90284
+ GetScalarBinaryFunction<MultiplyOperator>(type.InternalType()), true));
90279
90285
  }
90280
90286
  }
90281
90287
  functions.AddFunction(
90282
90288
  ScalarFunction({LogicalType::INTERVAL, LogicalType::BIGINT}, LogicalType::INTERVAL,
90283
- ScalarFunction::BinaryFunction<interval_t, int64_t, interval_t, MultiplyOperator>));
90289
+ ScalarFunction::BinaryFunction<interval_t, int64_t, interval_t, MultiplyOperator>, true));
90284
90290
  functions.AddFunction(
90285
90291
  ScalarFunction({LogicalType::BIGINT, LogicalType::INTERVAL}, LogicalType::INTERVAL,
90286
- ScalarFunction::BinaryFunction<int64_t, interval_t, interval_t, MultiplyOperator>));
90292
+ ScalarFunction::BinaryFunction<int64_t, interval_t, interval_t, MultiplyOperator>, true));
90287
90293
  set.AddFunction(functions);
90288
90294
  }
90289
90295
 
@@ -91521,7 +91527,7 @@ void LowerFun::RegisterFunction(BuiltinFunctions &set) {
91521
91527
  void UpperFun::RegisterFunction(BuiltinFunctions &set) {
91522
91528
  set.AddFunction({"upper", "ucase"},
91523
91529
  ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR, CaseConvertFunction<true>, false,
91524
- nullptr, nullptr, CaseConvertPropagateStats<true>));
91530
+ false, nullptr, nullptr, CaseConvertPropagateStats<true>));
91525
91531
  }
91526
91532
 
91527
91533
  } // namespace duckdb
@@ -92251,11 +92257,11 @@ static unique_ptr<FunctionData> ListLengthBind(ClientContext &context, ScalarFun
92251
92257
  void LengthFun::RegisterFunction(BuiltinFunctions &set) {
92252
92258
  ScalarFunction array_length_unary = ScalarFunction(
92253
92259
  {LogicalType::LIST(LogicalType::ANY)}, LogicalType::BIGINT,
92254
- ScalarFunction::UnaryFunction<list_entry_t, int64_t, ArrayLengthOperator>, false, ListLengthBind);
92260
+ ScalarFunction::UnaryFunction<list_entry_t, int64_t, ArrayLengthOperator>, false, false, ListLengthBind);
92255
92261
  ScalarFunctionSet length("length");
92256
92262
  length.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::BIGINT,
92257
92263
  ScalarFunction::UnaryFunction<string_t, int64_t, StringLengthOperator>, false,
92258
- nullptr, nullptr, LengthPropagateStats));
92264
+ false, nullptr, nullptr, LengthPropagateStats));
92259
92265
  length.AddFunction(array_length_unary);
92260
92266
  set.AddFunction(length);
92261
92267
  length.name = "len";
@@ -92266,7 +92272,7 @@ void LengthFun::RegisterFunction(BuiltinFunctions &set) {
92266
92272
  array_length.AddFunction(
92267
92273
  ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::BIGINT}, LogicalType::BIGINT,
92268
92274
  ScalarFunction::BinaryFunction<list_entry_t, int64_t, int64_t, ArrayLengthBinaryOperator>, false,
92269
- ListLengthBind));
92275
+ false, ListLengthBind));
92270
92276
  set.AddFunction(array_length);
92271
92277
 
92272
92278
  set.AddFunction(ScalarFunction("strlen", {LogicalType::VARCHAR}, LogicalType::BIGINT,
@@ -95015,34 +95021,36 @@ static unique_ptr<FunctionData> RegexExtractBind(ClientContext &context, ScalarF
95015
95021
  void RegexpFun::RegisterFunction(BuiltinFunctions &set) {
95016
95022
  ScalarFunctionSet regexp_full_match("regexp_full_match");
95017
95023
  regexp_full_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::BOOLEAN,
95018
- RegexpMatchesFunction<RegexFullMatch>, false, RegexpMatchesBind,
95024
+ RegexpMatchesFunction<RegexFullMatch>, false, false, RegexpMatchesBind,
95019
95025
  nullptr, nullptr, RegexInitLocalState));
95020
95026
  regexp_full_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
95021
95027
  LogicalType::BOOLEAN, RegexpMatchesFunction<RegexFullMatch>, false,
95022
- RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
95028
+ false, RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
95023
95029
 
95024
95030
  ScalarFunctionSet regexp_partial_match("regexp_matches");
95025
95031
  regexp_partial_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::BOOLEAN,
95026
- RegexpMatchesFunction<RegexPartialMatch>, false, RegexpMatchesBind,
95027
- nullptr, nullptr, RegexInitLocalState));
95032
+ RegexpMatchesFunction<RegexPartialMatch>, false, false,
95033
+ RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
95028
95034
  regexp_partial_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
95029
95035
  LogicalType::BOOLEAN, RegexpMatchesFunction<RegexPartialMatch>,
95030
- false, RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
95036
+ false, false, RegexpMatchesBind, nullptr, nullptr,
95037
+ RegexInitLocalState));
95031
95038
 
95032
95039
  ScalarFunctionSet regexp_replace("regexp_replace");
95033
95040
  regexp_replace.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
95034
- LogicalType::VARCHAR, RegexReplaceFunction, false, RegexReplaceBind));
95041
+ LogicalType::VARCHAR, RegexReplaceFunction, false, false,
95042
+ RegexReplaceBind));
95035
95043
  regexp_replace.AddFunction(
95036
95044
  ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
95037
- LogicalType::VARCHAR, RegexReplaceFunction, false, RegexReplaceBind));
95045
+ LogicalType::VARCHAR, RegexReplaceFunction, false, false, RegexReplaceBind));
95038
95046
 
95039
95047
  ScalarFunctionSet regexp_extract("regexp_extract");
95040
95048
  regexp_extract.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::VARCHAR,
95041
- RegexExtractFunction, false, RegexExtractBind, nullptr, nullptr,
95049
+ RegexExtractFunction, false, false, RegexExtractBind, nullptr, nullptr,
95042
95050
  RegexExtractInitLocalState));
95043
95051
  regexp_extract.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::INTEGER},
95044
- LogicalType::VARCHAR, RegexExtractFunction, false, RegexExtractBind,
95045
- nullptr, nullptr, RegexExtractInitLocalState));
95052
+ LogicalType::VARCHAR, RegexExtractFunction, false, false,
95053
+ RegexExtractBind, nullptr, nullptr, RegexExtractInitLocalState));
95046
95054
 
95047
95055
  set.AddFunction(regexp_full_match);
95048
95056
  set.AddFunction(regexp_partial_match);
@@ -95735,10 +95743,10 @@ static unique_ptr<BaseStatistics> SubstringPropagateStats(ClientContext &context
95735
95743
  void SubstringFun::RegisterFunction(BuiltinFunctions &set) {
95736
95744
  ScalarFunctionSet substr("substring");
95737
95745
  substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT, LogicalType::BIGINT},
95738
- LogicalType::VARCHAR, SubstringFunction, false, nullptr, nullptr,
95746
+ LogicalType::VARCHAR, SubstringFunction, false, false, nullptr, nullptr,
95739
95747
  SubstringPropagateStats));
95740
95748
  substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT}, LogicalType::VARCHAR,
95741
- SubstringFunction, false, nullptr, nullptr, SubstringPropagateStats));
95749
+ SubstringFunction, false, false, nullptr, nullptr, SubstringPropagateStats));
95742
95750
  set.AddFunction(substr);
95743
95751
  substr.name = "substr";
95744
95752
  set.AddFunction(substr);
@@ -96731,7 +96739,7 @@ static void GenerateUUIDFunction(DataChunk &args, ExpressionState &state, Vector
96731
96739
  }
96732
96740
 
96733
96741
  void UUIDFun::RegisterFunction(BuiltinFunctions &set) {
96734
- ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, true, UUIDRandomBind);
96742
+ ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, false, true, UUIDRandomBind);
96735
96743
  // generate a random uuid
96736
96744
  set.AddFunction({"uuid", "gen_random_uuid"}, uuid_function);
96737
96745
  }
@@ -96744,18 +96752,19 @@ namespace duckdb {
96744
96752
  ScalarFunction::ScalarFunction(string name, vector<LogicalType> arguments, LogicalType return_type,
96745
96753
  scalar_function_t function, bool has_side_effects, bind_scalar_function_t bind,
96746
96754
  dependency_function_t dependency, function_statistics_t statistics,
96747
- init_local_state_t init_local_state, LogicalType varargs)
96748
- : BaseScalarFunction(move(name), move(arguments), move(return_type), has_side_effects, move(varargs)),
96755
+ init_local_state_t init_local_state, LogicalType varargs, bool propagate_null_values)
96756
+ : BaseScalarFunction(move(name), move(arguments), move(return_type), has_side_effects, move(varargs),
96757
+ propagate_null_values),
96749
96758
  function(move(function)), bind(bind), init_local_state(init_local_state), dependency(dependency),
96750
96759
  statistics(statistics) {
96751
96760
  }
96752
96761
 
96753
96762
  ScalarFunction::ScalarFunction(vector<LogicalType> arguments, LogicalType return_type, scalar_function_t function,
96754
- bool has_side_effects, bind_scalar_function_t bind, dependency_function_t dependency,
96755
- function_statistics_t statistics, init_local_state_t init_local_state,
96756
- LogicalType varargs)
96763
+ bool propagate_null_values, bool has_side_effects, bind_scalar_function_t bind,
96764
+ dependency_function_t dependency, function_statistics_t statistics,
96765
+ init_local_state_t init_local_state, LogicalType varargs)
96757
96766
  : ScalarFunction(string(), move(arguments), move(return_type), move(function), has_side_effects, bind, dependency,
96758
- statistics, init_local_state, move(varargs)) {
96767
+ statistics, init_local_state, move(varargs), propagate_null_values) {
96759
96768
  }
96760
96769
 
96761
96770
  bool ScalarFunction::operator==(const ScalarFunction &rhs) const {
@@ -120070,7 +120079,11 @@ const vector<ColumnDefinition> &JoinRelation::Columns() {
120070
120079
 
120071
120080
  string JoinRelation::ToString(idx_t depth) {
120072
120081
  string str = RenderWhitespace(depth);
120073
- str = "Join " + JoinTypeToString(join_type);
120082
+ str += "Join " + JoinTypeToString(join_type);
120083
+ if (condition) {
120084
+ str += " " + condition->GetName();
120085
+ }
120086
+
120074
120087
  return str + "\n" + left->ToString(depth + 1) + "\n" + right->ToString(depth + 1);
120075
120088
  }
120076
120089
 
@@ -120181,6 +120194,7 @@ public:
120181
120194
 
120182
120195
  vector<OrderByNode> orders;
120183
120196
  shared_ptr<Relation> child;
120197
+ vector<ColumnDefinition> columns;
120184
120198
 
120185
120199
  public:
120186
120200
  unique_ptr<QueryNode> GetQueryNode() override;
@@ -120203,23 +120217,26 @@ public:
120203
120217
 
120204
120218
 
120205
120219
 
120220
+
120221
+
120206
120222
  namespace duckdb {
120207
120223
 
120208
120224
  OrderRelation::OrderRelation(shared_ptr<Relation> child_p, vector<OrderByNode> orders)
120209
120225
  : Relation(child_p->context, RelationType::ORDER_RELATION), orders(move(orders)), child(move(child_p)) {
120210
120226
  // bind the expressions
120211
- vector<ColumnDefinition> dummy_columns;
120212
- context.GetContext()->TryBindRelation(*this, dummy_columns);
120227
+ context.GetContext()->TryBindRelation(*this, this->columns);
120213
120228
  }
120214
120229
 
120215
120230
  unique_ptr<QueryNode> OrderRelation::GetQueryNode() {
120216
- auto child_node = child->GetQueryNode();
120231
+ auto select = make_unique<SelectNode>();
120232
+ select->from_table = child->GetTableRef();
120233
+ select->select_list.push_back(make_unique<StarExpression>());
120217
120234
  auto order_node = make_unique<OrderModifier>();
120218
120235
  for (idx_t i = 0; i < orders.size(); i++) {
120219
120236
  order_node->orders.emplace_back(orders[i].type, orders[i].null_order, orders[i].expression->Copy());
120220
120237
  }
120221
- child_node->modifiers.push_back(move(order_node));
120222
- return child_node;
120238
+ select->modifiers.push_back(move(order_node));
120239
+ return move(select);
120223
120240
  }
120224
120241
 
120225
120242
  string OrderRelation::GetAlias() {
@@ -120227,7 +120244,7 @@ string OrderRelation::GetAlias() {
120227
120244
  }
120228
120245
 
120229
120246
  const vector<ColumnDefinition> &OrderRelation::Columns() {
120230
- return child->Columns();
120247
+ return columns;
120231
120248
  }
120232
120249
 
120233
120250
  string OrderRelation::ToString(idx_t depth) {
@@ -122660,7 +122677,6 @@ public:
122660
122677
  void VisitExpression(unique_ptr<Expression> *expression) override;
122661
122678
  //! Whether the operator has one or more children of type DELIM_GET
122662
122679
  bool HasChildDelimGet(LogicalOperator &op);
122663
-
122664
122680
  expression_map_t<Expression *> expr_map;
122665
122681
  column_binding_map_t<bool> projection_map;
122666
122682
  unique_ptr<LogicalOperator> temp_ptr;
@@ -122669,12 +122685,12 @@ public:
122669
122685
  void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) {
122670
122686
  VisitOperatorChildren(op);
122671
122687
  VisitOperatorExpressions(op);
122672
- // now check if this is a delim join that can be removed
122673
122688
  if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN && !HasChildDelimGet(op)) {
122674
122689
  auto &delim_join = (LogicalDelimJoin &)op;
122675
122690
  auto decs = &delim_join.duplicate_eliminated_columns;
122676
122691
  for (auto &cond : delim_join.conditions) {
122677
- if (cond.comparison != ExpressionType::COMPARE_EQUAL) {
122692
+ if (cond.comparison != ExpressionType::COMPARE_EQUAL &&
122693
+ cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
122678
122694
  continue;
122679
122695
  }
122680
122696
  auto &colref = (BoundColumnRefExpression &)*cond.right;
@@ -122688,7 +122704,7 @@ void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) {
122688
122704
  }
122689
122705
  }
122690
122706
  // whether we applied an IS NOT NULL filter
122691
- cond.null_values_are_equal = true; // projection_map[colref.binding];
122707
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
122692
122708
  }
122693
122709
  }
122694
122710
  // change type if there are no more duplicate-eliminated columns
@@ -122785,6 +122801,7 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *op_ptr, Deliminat
122785
122801
  if (join.join_type != JoinType::INNER && join.join_type != JoinType::SEMI) {
122786
122802
  return false;
122787
122803
  }
122804
+
122788
122805
  // get the index (left or right) of the DelimGet side of the join
122789
122806
  idx_t delim_idx = OperatorIsDelimGet(*join.children[0]) ? 0 : 1;
122790
122807
  D_ASSERT(OperatorIsDelimGet(*join.children[delim_idx]));
@@ -122801,7 +122818,8 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *op_ptr, Deliminat
122801
122818
  // check if joining with the DelimGet is redundant, and collect relevant column information
122802
122819
  vector<Expression *> nulls_are_not_equal_exprs;
122803
122820
  for (auto &cond : join.conditions) {
122804
- if (cond.comparison != ExpressionType::COMPARE_EQUAL) {
122821
+ if (cond.comparison != ExpressionType::COMPARE_EQUAL &&
122822
+ cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
122805
122823
  // non-equality join condition
122806
122824
  return false;
122807
122825
  }
@@ -122813,7 +122831,7 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *op_ptr, Deliminat
122813
122831
  return false;
122814
122832
  }
122815
122833
  updater.expr_map[delim_side] = other_side;
122816
- if (!cond.null_values_are_equal) {
122834
+ if (cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
122817
122835
  nulls_are_not_equal_exprs.push_back(other_side);
122818
122836
  }
122819
122837
  }
@@ -126102,15 +126120,8 @@ JoinOrderOptimizer::GenerateJoins(vector<unique_ptr<LogicalOperator>> &extracted
126102
126120
  bool invert = !JoinRelationSet::IsSubset(left.first, f->left_set);
126103
126121
  cond.left = !invert ? move(comparison.left) : move(comparison.right);
126104
126122
  cond.right = !invert ? move(comparison.right) : move(comparison.left);
126105
- if (condition->type == ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
126106
- cond.comparison = ExpressionType::COMPARE_EQUAL;
126107
- cond.null_values_are_equal = true;
126108
- } else if (condition->type == ExpressionType::COMPARE_DISTINCT_FROM) {
126109
- cond.comparison = condition->type;
126110
- cond.null_values_are_equal = true;
126111
- } else {
126112
- cond.comparison = condition->type;
126113
- }
126123
+ cond.comparison = condition->type;
126124
+
126114
126125
  if (invert) {
126115
126126
  // reverse comparison expression if we reverse the order of the children
126116
126127
  cond.comparison = FlipComparisionExpression(cond.comparison);
@@ -127781,7 +127792,8 @@ unique_ptr<LogicalOperator> FilterPushdown::PushdownMarkJoin(unique_ptr<LogicalO
127781
127792
  // the filter is NOT(marker), check the join conditions
127782
127793
  bool all_null_values_are_equal = true;
127783
127794
  for (auto &cond : comp_join.conditions) {
127784
- if (!cond.null_values_are_equal) {
127795
+ if (cond.comparison != ExpressionType::COMPARE_DISTINCT_FROM &&
127796
+ cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
127785
127797
  all_null_values_are_equal = false;
127786
127798
  break;
127787
127799
  }
@@ -130444,7 +130456,9 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq
130444
130456
  auto stats_left = PropagateExpression(condition.left);
130445
130457
  auto stats_right = PropagateExpression(condition.right);
130446
130458
  if (stats_left && stats_right) {
130447
- if (condition.null_values_are_equal && stats_left->CanHaveNull() && stats_right->CanHaveNull()) {
130459
+ if ((condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM ||
130460
+ condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM) &&
130461
+ stats_left->CanHaveNull() && stats_right->CanHaveNull()) {
130448
130462
  // null values are equal in this join, and both sides can have null values
130449
130463
  // nothing to do here
130450
130464
  continue;
@@ -130532,7 +130546,8 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq
130532
130546
  // anti joins have inverse statistics propagation
130533
130547
  // (i.e. if we have an anti join on i: [0, 100] and j: [0, 25], the resulting stats are i:[25,100])
130534
130548
  // for now we don't handle anti joins
130535
- if (condition.null_values_are_equal) {
130549
+ if (condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM ||
130550
+ condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
130536
130551
  // skip update when null values are equal (for now?)
130537
130552
  continue;
130538
130553
  }
@@ -151665,10 +151680,16 @@ BindResult BindContext::BindColumn(ColumnRefExpression &colref, idx_t depth) {
151665
151680
  }
151666
151681
 
151667
151682
  string BindContext::BindColumn(PositionalReferenceExpression &ref, string &table_name, string &column_name) {
151668
- idx_t current_position = ref.index - 1;
151669
151683
  idx_t total_columns = 0;
151684
+ idx_t current_position = ref.index - 1;
151670
151685
  for (auto &entry : bindings_list) {
151671
151686
  idx_t entry_column_count = entry.second->names.size();
151687
+ if (ref.index == 0) {
151688
+ // this is a row id
151689
+ table_name = entry.first;
151690
+ column_name = "rowid";
151691
+ return string();
151692
+ }
151672
151693
  if (current_position < entry_column_count) {
151673
151694
  table_name = entry.first;
151674
151695
  column_name = entry.second->names[current_position];
@@ -155042,7 +155063,7 @@ namespace duckdb {
155042
155063
  //! The FlattenDependentJoins class is responsible for pushing the dependent join down into the plan to create a
155043
155064
  //! flattened subquery
155044
155065
  struct FlattenDependentJoins {
155045
- FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated);
155066
+ FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated, bool any_join = false);
155046
155067
 
155047
155068
  //! Detects which Logical Operators have correlated expressions that they are dependent upon, filling the
155048
155069
  //! has_correlated_expressions map.
@@ -155061,8 +155082,11 @@ struct FlattenDependentJoins {
155061
155082
  const vector<CorrelatedColumnInfo> &correlated_columns;
155062
155083
  vector<LogicalType> delim_types;
155063
155084
 
155085
+ bool any_join;
155086
+
155064
155087
  private:
155065
- unique_ptr<LogicalOperator> PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan);
155088
+ unique_ptr<LogicalOperator> PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan,
155089
+ bool &parent_propagate_null_values);
155066
155090
  };
155067
155091
 
155068
155092
  } // namespace duckdb
@@ -155208,8 +155232,7 @@ static void CreateDelimJoinConditions(LogicalDelimJoin &delim_join, vector<Corre
155208
155232
  JoinCondition cond;
155209
155233
  cond.left = make_unique<BoundColumnRefExpression>(col.name, col.type, col.binding);
155210
155234
  cond.right = make_unique<BoundColumnRefExpression>(col.name, col.type, bindings[base_offset + i]);
155211
- cond.comparison = ExpressionType::COMPARE_EQUAL;
155212
- cond.null_values_are_equal = true;
155235
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
155213
155236
  delim_join.conditions.push_back(move(cond));
155214
155237
  }
155215
155238
  }
@@ -155300,7 +155323,7 @@ static unique_ptr<Expression> PlanCorrelatedSubquery(Binder &binder, BoundSubque
155300
155323
  // LHS
155301
155324
  delim_join->AddChild(move(root));
155302
155325
  // RHS
155303
- FlattenDependentJoins flatten(binder, correlated_columns);
155326
+ FlattenDependentJoins flatten(binder, correlated_columns, true);
155304
155327
  flatten.DetectCorrelatedExpressions(plan.get());
155305
155328
  auto dependent_join = flatten.PushDownDependentJoin(move(plan));
155306
155329
 
@@ -159186,6 +159209,10 @@ bool BoundAggregateExpression::Equals(const BaseExpression *other_p) const {
159186
159209
  return true;
159187
159210
  }
159188
159211
 
159212
+ bool BoundAggregateExpression::PropagatesNullValues() const {
159213
+ return !function.propagates_null_values ? false : Expression::PropagatesNullValues();
159214
+ }
159215
+
159189
159216
  unique_ptr<Expression> BoundAggregateExpression::Copy() {
159190
159217
  vector<unique_ptr<Expression>> new_children;
159191
159218
  for (auto &child : children) {
@@ -159497,6 +159524,7 @@ bool BoundComparisonExpression::Equals(const BaseExpression *other_p) const {
159497
159524
  if (!Expression::Equals(right.get(), other->right.get())) {
159498
159525
  return false;
159499
159526
  }
159527
+
159500
159528
  return true;
159501
159529
  }
159502
159530
 
@@ -159536,6 +159564,10 @@ bool BoundConjunctionExpression::Equals(const BaseExpression *other_p) const {
159536
159564
  return ExpressionUtil::SetEquals(children, other->children);
159537
159565
  }
159538
159566
 
159567
+ bool BoundConjunctionExpression::PropagatesNullValues() const {
159568
+ return false;
159569
+ }
159570
+
159539
159571
  unique_ptr<Expression> BoundConjunctionExpression::Copy() {
159540
159572
  auto copy = make_unique<BoundConjunctionExpression>(type);
159541
159573
  for (auto &expr : children) {
@@ -159611,6 +159643,9 @@ string BoundFunctionExpression::ToString() const {
159611
159643
  return FunctionExpression::ToString<BoundFunctionExpression, Expression>(*this, string(), function.name,
159612
159644
  is_operator);
159613
159645
  }
159646
+ bool BoundFunctionExpression::PropagatesNullValues() const {
159647
+ return !function.propagates_null_values ? false : Expression::PropagatesNullValues();
159648
+ }
159614
159649
 
159615
159650
  hash_t BoundFunctionExpression::Hash() const {
159616
159651
  hash_t result = Expression::Hash();
@@ -159800,6 +159835,11 @@ unique_ptr<Expression> BoundSubqueryExpression::Copy() {
159800
159835
  throw SerializationException("Cannot copy BoundSubqueryExpression");
159801
159836
  }
159802
159837
 
159838
+ bool BoundSubqueryExpression::PropagatesNullValues() const {
159839
+ // TODO this can be optimized further by checking the actual subquery node
159840
+ return false;
159841
+ }
159842
+
159803
159843
  } // namespace duckdb
159804
159844
 
159805
159845
 
@@ -160009,6 +160049,21 @@ bool Expression::HasSideEffects() const {
160009
160049
  return has_side_effects;
160010
160050
  }
160011
160051
 
160052
+ bool Expression::PropagatesNullValues() const {
160053
+ if (type == ExpressionType::OPERATOR_IS_NULL || type == ExpressionType::OPERATOR_IS_NOT_NULL ||
160054
+ type == ExpressionType::COMPARE_NOT_DISTINCT_FROM || type == ExpressionType::COMPARE_DISTINCT_FROM ||
160055
+ type == ExpressionType::CONJUNCTION_OR || type == ExpressionType::CONJUNCTION_AND) {
160056
+ return false;
160057
+ }
160058
+ bool propagate_null_values = true;
160059
+ ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) {
160060
+ if (!child.PropagatesNullValues()) {
160061
+ propagate_null_values = false;
160062
+ }
160063
+ });
160064
+ return propagate_null_values;
160065
+ }
160066
+
160012
160067
  bool Expression::IsFoldable() const {
160013
160068
  bool is_foldable = true;
160014
160069
  ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) {
@@ -161514,7 +161569,8 @@ string IsNotNullFilter::ToString(const string &column_name) {
161514
161569
  namespace duckdb {
161515
161570
 
161516
161571
  unique_ptr<Expression> JoinCondition::CreateExpression(JoinCondition cond) {
161517
- return make_unique<BoundComparisonExpression>(cond.comparison, move(cond.left), move(cond.right));
161572
+ auto bound_comparison = make_unique<BoundComparisonExpression>(cond.comparison, move(cond.left), move(cond.right));
161573
+ return move(bound_comparison);
161518
161574
  }
161519
161575
 
161520
161576
  JoinSide JoinSide::CombineJoinSide(JoinSide left, JoinSide right) {
@@ -162777,8 +162833,9 @@ public:
162777
162833
 
162778
162834
  namespace duckdb {
162779
162835
 
162780
- FlattenDependentJoins::FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated)
162781
- : binder(binder), correlated_columns(correlated) {
162836
+ FlattenDependentJoins::FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated,
162837
+ bool any_join)
162838
+ : binder(binder), correlated_columns(correlated), any_join(any_join) {
162782
162839
  for (idx_t i = 0; i < correlated_columns.size(); i++) {
162783
162840
  auto &col = correlated_columns[i];
162784
162841
  correlated_map[col.binding] = i;
@@ -162807,7 +162864,8 @@ bool FlattenDependentJoins::DetectCorrelatedExpressions(LogicalOperator *op) {
162807
162864
  }
162808
162865
 
162809
162866
  unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoin(unique_ptr<LogicalOperator> plan) {
162810
- auto result = PushDownDependentJoinInternal(move(plan));
162867
+ bool propagate_null_values = true;
162868
+ auto result = PushDownDependentJoinInternal(move(plan), propagate_null_values);
162811
162869
  if (!replacement_map.empty()) {
162812
162870
  // check if we have to replace any COUNT aggregates into "CASE WHEN X IS NULL THEN 0 ELSE COUNT END"
162813
162871
  RewriteCountAggregates aggr(replacement_map);
@@ -162816,7 +162874,23 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoin(unique_
162816
162874
  return result;
162817
162875
  }
162818
162876
 
162819
- unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan) {
162877
+ bool SubqueryDependentFilter(Expression *expr) {
162878
+ if (expr->expression_class == ExpressionClass::BOUND_CONJUNCTION &&
162879
+ expr->GetExpressionType() == ExpressionType::CONJUNCTION_AND) {
162880
+ auto bound_conjuction = (BoundConjunctionExpression *)expr;
162881
+ for (auto &child : bound_conjuction->children) {
162882
+ if (SubqueryDependentFilter(child.get())) {
162883
+ return true;
162884
+ }
162885
+ }
162886
+ }
162887
+ if (expr->expression_class == ExpressionClass::BOUND_SUBQUERY) {
162888
+ return true;
162889
+ }
162890
+ return false;
162891
+ }
162892
+ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan,
162893
+ bool &parent_propagate_null_values) {
162820
162894
  // first check if the logical operator has correlated expressions
162821
162895
  auto entry = has_correlated_expressions.find(plan.get());
162822
162896
  D_ASSERT(entry != has_correlated_expressions.end());
@@ -162837,7 +162911,11 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162837
162911
  case LogicalOperatorType::LOGICAL_FILTER: {
162838
162912
  // filter
162839
162913
  // first we flatten the dependent join in the child of the filter
162840
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
162914
+ for (auto &expr : plan->expressions) {
162915
+ any_join |= SubqueryDependentFilter(expr.get());
162916
+ }
162917
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162918
+
162841
162919
  // then we replace any correlated expressions with the corresponding entry in the correlated_map
162842
162920
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
162843
162921
  rewriter.VisitOperator(*plan);
@@ -162846,7 +162924,11 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162846
162924
  case LogicalOperatorType::LOGICAL_PROJECTION: {
162847
162925
  // projection
162848
162926
  // first we flatten the dependent join in the child of the projection
162849
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
162927
+ for (auto &expr : plan->expressions) {
162928
+ parent_propagate_null_values &= expr->PropagatesNullValues();
162929
+ }
162930
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162931
+
162850
162932
  // then we replace any correlated expressions with the corresponding entry in the correlated_map
162851
162933
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
162852
162934
  rewriter.VisitOperator(*plan);
@@ -162867,7 +162949,10 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162867
162949
  auto &aggr = (LogicalAggregate &)*plan;
162868
162950
  // aggregate and group by
162869
162951
  // first we flatten the dependent join in the child of the projection
162870
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
162952
+ for (auto &expr : plan->expressions) {
162953
+ parent_propagate_null_values &= expr->PropagatesNullValues();
162954
+ }
162955
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162871
162956
  // then we replace any correlated expressions with the corresponding entry in the correlated_map
162872
162957
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
162873
162958
  rewriter.VisitOperator(*plan);
@@ -162884,11 +162969,18 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162884
162969
  // we have to perform a LEFT OUTER JOIN between the result of this aggregate and the delim scan
162885
162970
  // FIXME: this does not always have to be a LEFT OUTER JOIN, depending on whether aggr.expressions return
162886
162971
  // NULL or a value
162887
- auto left_outer_join = make_unique<LogicalComparisonJoin>(JoinType::LEFT);
162972
+ unique_ptr<LogicalComparisonJoin> join = make_unique<LogicalComparisonJoin>(JoinType::INNER);
162973
+ for (auto &aggr_exp : aggr.expressions) {
162974
+ auto b_aggr_exp = (BoundAggregateExpression *)aggr_exp.get();
162975
+ if (!b_aggr_exp->PropagatesNullValues() || any_join || !parent_propagate_null_values) {
162976
+ join = make_unique<LogicalComparisonJoin>(JoinType::LEFT);
162977
+ break;
162978
+ }
162979
+ }
162888
162980
  auto left_index = binder.GenerateTableIndex();
162889
162981
  auto delim_scan = make_unique<LogicalDelimGet>(left_index, delim_types);
162890
- left_outer_join->children.push_back(move(delim_scan));
162891
- left_outer_join->children.push_back(move(plan));
162982
+ join->children.push_back(move(delim_scan));
162983
+ join->children.push_back(move(plan));
162892
162984
  for (idx_t i = 0; i < correlated_columns.size(); i++) {
162893
162985
  JoinCondition cond;
162894
162986
  cond.left =
@@ -162896,9 +162988,8 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162896
162988
  cond.right = make_unique<BoundColumnRefExpression>(
162897
162989
  correlated_columns[i].type,
162898
162990
  ColumnBinding(aggr.group_index, (aggr.groups.size() - correlated_columns.size()) + i));
162899
- cond.comparison = ExpressionType::COMPARE_EQUAL;
162900
- cond.null_values_are_equal = true;
162901
- left_outer_join->conditions.push_back(move(cond));
162991
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
162992
+ join->conditions.push_back(move(cond));
162902
162993
  }
162903
162994
  // for any COUNT aggregate we replace references to the column with: CASE WHEN COUNT(*) IS NULL THEN 0
162904
162995
  // ELSE COUNT(*) END
@@ -162916,7 +163007,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162916
163007
  base_binding.table_index = left_index;
162917
163008
  this->delim_offset = base_binding.column_index = 0;
162918
163009
  this->data_offset = 0;
162919
- return move(left_outer_join);
163010
+ return move(join);
162920
163011
  } else {
162921
163012
  // update the delim_index
162922
163013
  base_binding.table_index = aggr.group_index;
@@ -162932,20 +163023,20 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162932
163023
  bool right_has_correlation = has_correlated_expressions.find(plan->children[1].get())->second;
162933
163024
  if (!right_has_correlation) {
162934
163025
  // only left has correlation: push into left
162935
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163026
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162936
163027
  return plan;
162937
163028
  }
162938
163029
  if (!left_has_correlation) {
162939
163030
  // only right has correlation: push into right
162940
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163031
+ plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
162941
163032
  return plan;
162942
163033
  }
162943
163034
  // both sides have correlation
162944
163035
  // turn into an inner join
162945
163036
  auto join = make_unique<LogicalComparisonJoin>(JoinType::INNER);
162946
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163037
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162947
163038
  auto left_binding = this->base_binding;
162948
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163039
+ plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
162949
163040
  // add the correlated columns to the join conditions
162950
163041
  for (idx_t i = 0; i < correlated_columns.size(); i++) {
162951
163042
  JoinCondition cond;
@@ -162953,8 +163044,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162953
163044
  correlated_columns[i].type, ColumnBinding(left_binding.table_index, left_binding.column_index + i));
162954
163045
  cond.right = make_unique<BoundColumnRefExpression>(
162955
163046
  correlated_columns[i].type, ColumnBinding(base_binding.table_index, base_binding.column_index + i));
162956
- cond.comparison = ExpressionType::COMPARE_EQUAL;
162957
- cond.null_values_are_equal = true;
163047
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
162958
163048
  join->conditions.push_back(move(cond));
162959
163049
  }
162960
163050
  join->children.push_back(move(plan->children[0]));
@@ -162973,26 +163063,30 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162973
163063
  // inner join
162974
163064
  if (!right_has_correlation) {
162975
163065
  // only left has correlation: push into left
162976
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163066
+ plan->children[0] =
163067
+ PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162977
163068
  return plan;
162978
163069
  }
162979
163070
  if (!left_has_correlation) {
162980
163071
  // only right has correlation: push into right
162981
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163072
+ plan->children[1] =
163073
+ PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
162982
163074
  return plan;
162983
163075
  }
162984
163076
  } else if (join.join_type == JoinType::LEFT) {
162985
163077
  // left outer join
162986
163078
  if (!right_has_correlation) {
162987
163079
  // only left has correlation: push into left
162988
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163080
+ plan->children[0] =
163081
+ PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162989
163082
  return plan;
162990
163083
  }
162991
163084
  } else if (join.join_type == JoinType::RIGHT) {
162992
163085
  // left outer join
162993
163086
  if (!left_has_correlation) {
162994
163087
  // only right has correlation: push into right
162995
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163088
+ plan->children[1] =
163089
+ PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
162996
163090
  return plan;
162997
163091
  }
162998
163092
  } else if (join.join_type == JoinType::MARK) {
@@ -163000,7 +163094,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163000
163094
  throw Exception("MARK join with correlation in RHS not supported");
163001
163095
  }
163002
163096
  // push the child into the LHS
163003
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163097
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163004
163098
  // rewrite expressions in the join conditions
163005
163099
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
163006
163100
  rewriter.VisitOperator(*plan);
@@ -163010,9 +163104,9 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163010
163104
  }
163011
163105
  // both sides have correlation
163012
163106
  // push into both sides
163013
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163107
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163014
163108
  auto left_binding = this->base_binding;
163015
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163109
+ plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
163016
163110
  auto right_binding = this->base_binding;
163017
163111
  // NOTE: for OUTER JOINS it matters what the BASE BINDING is after the join
163018
163112
  // for the LEFT OUTER JOIN, we want the LEFT side to be the base binding after we push
@@ -163033,8 +163127,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163033
163127
  JoinCondition cond;
163034
163128
  cond.left = move(left);
163035
163129
  cond.right = move(right);
163036
- cond.comparison = ExpressionType::COMPARE_EQUAL;
163037
- cond.null_values_are_equal = true;
163130
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
163038
163131
 
163039
163132
  auto &comparison_join = (LogicalComparisonJoin &)join;
163040
163133
  comparison_join.conditions.push_back(move(cond));
@@ -163060,7 +163153,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163060
163153
  if (limit.limit) {
163061
163154
  throw ParserException("Non-constant limit not supported in correlated subquery");
163062
163155
  }
163063
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163156
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163064
163157
  if (limit.limit_val == 0) {
163065
163158
  // limit = 0 means we return zero columns here
163066
163159
  return plan;
@@ -163075,7 +163168,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163075
163168
  case LogicalOperatorType::LOGICAL_WINDOW: {
163076
163169
  auto &window = (LogicalWindow &)*plan;
163077
163170
  // push into children
163078
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163171
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163079
163172
  // add the correlated columns to the PARTITION BY clauses in the Window
163080
163173
  for (auto &expr : window.expressions) {
163081
163174
  D_ASSERT(expr->GetExpressionClass() == ExpressionClass::BOUND_WINDOW);
@@ -163107,7 +163200,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163107
163200
  case LogicalOperatorType::LOGICAL_EXPRESSION_GET: {
163108
163201
  // expression get
163109
163202
  // first we flatten the dependent join in the child
163110
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163203
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163111
163204
  // then we replace any correlated expressions with the corresponding entry in the correlated_map
163112
163205
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
163113
163206
  rewriter.VisitOperator(*plan);