duckdb 0.3.3-dev1350.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/src/duckdb.cpp CHANGED
@@ -26517,6 +26517,7 @@ static void TemplatedMatch(DataChunk &columns, VectorData col_data[], const RowL
26517
26517
  switch (predicates[col_no]) {
26518
26518
  case ExpressionType::COMPARE_EQUAL:
26519
26519
  case ExpressionType::COMPARE_NOT_DISTINCT_FROM:
26520
+ case ExpressionType::COMPARE_DISTINCT_FROM:
26520
26521
  TemplatedMatchOp<Equals, NO_MATCH_SEL>(vec, col, layout, rows, sel, count, col_no, no_match,
26521
26522
  no_match_count);
26522
26523
  break;
@@ -47524,7 +47525,7 @@ namespace duckdb {
47524
47525
  //! JoinCondition represents a left-right comparison join condition
47525
47526
  struct JoinCondition {
47526
47527
  public:
47527
- JoinCondition() : null_values_are_equal(false) {
47528
+ JoinCondition() {
47528
47529
  }
47529
47530
 
47530
47531
  //! Turns the JoinCondition into an expression; note that this destroys the JoinCondition as the expression inherits
@@ -47535,17 +47536,14 @@ public:
47535
47536
  unique_ptr<Expression> left;
47536
47537
  unique_ptr<Expression> right;
47537
47538
  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
47539
  };
47542
47540
 
47543
47541
  class JoinSide {
47544
47542
  public:
47545
- enum join_value : uint8_t { NONE, LEFT, RIGHT, BOTH };
47543
+ enum JoinValue : uint8_t { NONE, LEFT, RIGHT, BOTH };
47546
47544
 
47547
47545
  JoinSide() = default;
47548
- constexpr JoinSide(join_value val) : value(val) { // NOLINT: Allow implicit conversion from `join_value`
47546
+ constexpr JoinSide(JoinValue val) : value(val) { // NOLINT: Allow implicit conversion from `join_value`
47549
47547
  }
47550
47548
 
47551
47549
  bool operator==(JoinSide a) const {
@@ -47564,7 +47562,7 @@ public:
47564
47562
  unordered_set<idx_t> &right_bindings);
47565
47563
 
47566
47564
  private:
47567
- join_value value;
47565
+ JoinValue value;
47568
47566
  };
47569
47567
 
47570
47568
  } // namespace duckdb
@@ -50972,7 +50970,8 @@ JoinHashTable::JoinHashTable(BufferManager &buffer_manager, const vector<JoinCon
50972
50970
  D_ASSERT(condition.left->return_type == condition.right->return_type);
50973
50971
  auto type = condition.left->return_type;
50974
50972
  if (condition.comparison == ExpressionType::COMPARE_EQUAL ||
50975
- condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
50973
+ condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM ||
50974
+ condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM) {
50976
50975
  // all equality conditions should be at the front
50977
50976
  // all other conditions at the back
50978
50977
  // this assert checks that
@@ -50981,10 +50980,8 @@ JoinHashTable::JoinHashTable(BufferManager &buffer_manager, const vector<JoinCon
50981
50980
  }
50982
50981
 
50983
50982
  predicates.push_back(condition.comparison);
50984
- null_values_are_equal.push_back(condition.null_values_are_equal ||
50983
+ null_values_are_equal.push_back(condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM ||
50985
50984
  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
50985
 
50989
50986
  condition_types.push_back(type);
50990
50987
  }
@@ -68056,7 +68053,7 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
68056
68053
  }
68057
68054
  // with equality condition and null values not equal
68058
68055
  for (auto &&condition : op.conditions) {
68059
- if (condition.comparison != ExpressionType::COMPARE_EQUAL || condition.null_values_are_equal) {
68056
+ if (condition.comparison != ExpressionType::COMPARE_EQUAL) {
68060
68057
  return;
68061
68058
  }
68062
68059
  }
@@ -68177,10 +68174,6 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalComparison
68177
68174
  default:
68178
68175
  throw NotImplementedException("Unimplemented comparison join");
68179
68176
  }
68180
- if (cond.null_values_are_equal) {
68181
- D_ASSERT(cond.comparison == ExpressionType::COMPARE_EQUAL ||
68182
- cond.comparison == ExpressionType::COMPARE_DISTINCT_FROM);
68183
- }
68184
68177
  }
68185
68178
 
68186
68179
  unique_ptr<PhysicalOperator> plan;
@@ -70592,10 +70585,9 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalSetOperati
70592
70585
  // create equality condition for all columns
70593
70586
  for (idx_t i = 0; i < types.size(); i++) {
70594
70587
  JoinCondition cond;
70595
- cond.comparison = ExpressionType::COMPARE_EQUAL;
70596
70588
  cond.left = make_unique<BoundReferenceExpression>(types[i], i);
70597
70589
  cond.right = make_unique<BoundReferenceExpression>(types[i], i);
70598
- cond.null_values_are_equal = true;
70590
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
70599
70591
  conditions.push_back(move(cond));
70600
70592
  }
70601
70593
  // EXCEPT is ANTI join
@@ -72485,22 +72477,22 @@ AggregateFunction GetAverageAggregate(PhysicalType type) {
72485
72477
  switch (type) {
72486
72478
  case PhysicalType::INT16:
72487
72479
  return AggregateFunction::UnaryAggregate<AvgState<int64_t>, int16_t, double, IntegerAverageOperation>(
72488
- LogicalType::SMALLINT, LogicalType::DOUBLE);
72480
+ LogicalType::SMALLINT, LogicalType::DOUBLE, true);
72489
72481
  case PhysicalType::INT32: {
72490
72482
  auto function =
72491
72483
  AggregateFunction::UnaryAggregate<AvgState<hugeint_t>, int32_t, double, IntegerAverageOperationHugeint>(
72492
- LogicalType::INTEGER, LogicalType::DOUBLE);
72484
+ LogicalType::INTEGER, LogicalType::DOUBLE, true);
72493
72485
  return function;
72494
72486
  }
72495
72487
  case PhysicalType::INT64: {
72496
72488
  auto function =
72497
72489
  AggregateFunction::UnaryAggregate<AvgState<hugeint_t>, int64_t, double, IntegerAverageOperationHugeint>(
72498
- LogicalType::BIGINT, LogicalType::DOUBLE);
72490
+ LogicalType::BIGINT, LogicalType::DOUBLE, true);
72499
72491
  return function;
72500
72492
  }
72501
72493
  case PhysicalType::INT128:
72502
72494
  return AggregateFunction::UnaryAggregate<AvgState<hugeint_t>, hugeint_t, double, HugeintAverageOperation>(
72503
- LogicalType::HUGEINT, LogicalType::DOUBLE);
72495
+ LogicalType::HUGEINT, LogicalType::DOUBLE, true);
72504
72496
  default:
72505
72497
  throw InternalException("Unimplemented average aggregate");
72506
72498
  }
@@ -72520,18 +72512,18 @@ unique_ptr<FunctionData> BindDecimalAvg(ClientContext &context, AggregateFunctio
72520
72512
  void AvgFun::RegisterFunction(BuiltinFunctions &set) {
72521
72513
  AggregateFunctionSet avg("avg");
72522
72514
  avg.AddFunction(AggregateFunction({LogicalTypeId::DECIMAL}, LogicalTypeId::DECIMAL, nullptr, nullptr, nullptr,
72523
- nullptr, nullptr, nullptr, BindDecimalAvg));
72515
+ nullptr, nullptr, true, nullptr, BindDecimalAvg));
72524
72516
  avg.AddFunction(GetAverageAggregate(PhysicalType::INT16));
72525
72517
  avg.AddFunction(GetAverageAggregate(PhysicalType::INT32));
72526
72518
  avg.AddFunction(GetAverageAggregate(PhysicalType::INT64));
72527
72519
  avg.AddFunction(GetAverageAggregate(PhysicalType::INT128));
72528
72520
  avg.AddFunction(AggregateFunction::UnaryAggregate<AvgState<double>, double, double, NumericAverageOperation>(
72529
- LogicalType::DOUBLE, LogicalType::DOUBLE));
72521
+ LogicalType::DOUBLE, LogicalType::DOUBLE, true));
72530
72522
  set.AddFunction(avg);
72531
72523
 
72532
72524
  AggregateFunctionSet favg("favg");
72533
72525
  favg.AddFunction(AggregateFunction::UnaryAggregate<KahanAvgState, double, double, KahanAverageOperation>(
72534
- LogicalType::DOUBLE, LogicalType::DOUBLE));
72526
+ LogicalType::DOUBLE, LogicalType::DOUBLE, true));
72535
72527
  set.AddFunction(favg);
72536
72528
  }
72537
72529
 
@@ -74460,24 +74452,24 @@ static AggregateFunction GetUnaryAggregate(LogicalType type) {
74460
74452
  case LogicalTypeId::TIMESTAMP_TZ:
74461
74453
  case LogicalTypeId::TIME_TZ:
74462
74454
  case LogicalTypeId::BIGINT:
74463
- 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);
74464
74456
  case LogicalTypeId::UTINYINT:
74465
- 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);
74466
74458
  case LogicalTypeId::USMALLINT:
74467
- 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);
74468
74460
  case LogicalTypeId::UINTEGER:
74469
- 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);
74470
74462
  case LogicalTypeId::UBIGINT:
74471
- 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);
74472
74464
  case LogicalTypeId::HUGEINT:
74473
74465
  case LogicalTypeId::UUID:
74474
- 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);
74475
74467
  case LogicalTypeId::FLOAT:
74476
- return AggregateFunction::UnaryAggregate<MinMaxState<float>, float, float, OP>(type, type);
74468
+ return AggregateFunction::UnaryAggregate<MinMaxState<float>, float, float, OP>(type, type, true);
74477
74469
  case LogicalTypeId::DOUBLE:
74478
- return AggregateFunction::UnaryAggregate<MinMaxState<double>, double, double, OP>(type, type);
74470
+ return AggregateFunction::UnaryAggregate<MinMaxState<double>, double, double, OP>(type, type, true);
74479
74471
  case LogicalTypeId::INTERVAL:
74480
- 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);
74481
74473
  default:
74482
74474
  throw InternalException("Unimplemented type for min/max aggregate");
74483
74475
  }
@@ -74958,7 +74950,7 @@ static void AddMinMaxOperator(AggregateFunctionSet &set) {
74958
74950
  AggregateFunction::UnaryAggregateDestructor<MinMaxState<string_t>, string_t, string_t, OP_STRING>(
74959
74951
  type.id(), type.id()));
74960
74952
  } else if (type.id() == LogicalTypeId::DECIMAL) {
74961
- set.AddFunction(AggregateFunction({type}, type, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
74953
+ set.AddFunction(AggregateFunction({type}, type, nullptr, nullptr, nullptr, nullptr, nullptr, false, nullptr,
74962
74954
  BindDecimalMinMax<OP>));
74963
74955
  } else if (type.id() == LogicalTypeId::LIST || type.id() == LogicalTypeId::MAP ||
74964
74956
  type.id() == LogicalTypeId::STRUCT) {
@@ -75387,13 +75379,13 @@ unique_ptr<BaseStatistics> SumPropagateStats(ClientContext &context, BoundAggreg
75387
75379
  case PhysicalType::INT32:
75388
75380
  expr.function =
75389
75381
  AggregateFunction::UnaryAggregate<SumState<int64_t>, int32_t, hugeint_t, IntegerSumOperation>(
75390
- LogicalType::INTEGER, LogicalType::HUGEINT);
75382
+ LogicalType::INTEGER, LogicalType::HUGEINT, true);
75391
75383
  expr.function.name = "sum";
75392
75384
  break;
75393
75385
  case PhysicalType::INT64:
75394
75386
  expr.function =
75395
75387
  AggregateFunction::UnaryAggregate<SumState<int64_t>, int64_t, hugeint_t, IntegerSumOperation>(
75396
- LogicalType::BIGINT, LogicalType::HUGEINT);
75388
+ LogicalType::BIGINT, LogicalType::HUGEINT, true);
75397
75389
  expr.function.name = "sum";
75398
75390
  break;
75399
75391
  default:
@@ -75407,24 +75399,24 @@ AggregateFunction SumFun::GetSumAggregate(PhysicalType type) {
75407
75399
  switch (type) {
75408
75400
  case PhysicalType::INT16:
75409
75401
  return AggregateFunction::UnaryAggregate<SumState<int64_t>, int16_t, hugeint_t, IntegerSumOperation>(
75410
- LogicalType::SMALLINT, LogicalType::HUGEINT);
75402
+ LogicalType::SMALLINT, LogicalType::HUGEINT, true);
75411
75403
  case PhysicalType::INT32: {
75412
75404
  auto function =
75413
75405
  AggregateFunction::UnaryAggregate<SumState<hugeint_t>, int32_t, hugeint_t, SumToHugeintOperation>(
75414
- LogicalType::INTEGER, LogicalType::HUGEINT);
75406
+ LogicalType::INTEGER, LogicalType::HUGEINT, true);
75415
75407
  function.statistics = SumPropagateStats;
75416
75408
  return function;
75417
75409
  }
75418
75410
  case PhysicalType::INT64: {
75419
75411
  auto function =
75420
75412
  AggregateFunction::UnaryAggregate<SumState<hugeint_t>, int64_t, hugeint_t, SumToHugeintOperation>(
75421
- LogicalType::BIGINT, LogicalType::HUGEINT);
75413
+ LogicalType::BIGINT, LogicalType::HUGEINT, true);
75422
75414
  function.statistics = SumPropagateStats;
75423
75415
  return function;
75424
75416
  }
75425
75417
  case PhysicalType::INT128:
75426
75418
  return AggregateFunction::UnaryAggregate<SumState<hugeint_t>, hugeint_t, hugeint_t, HugeintSumOperation>(
75427
- LogicalType::HUGEINT, LogicalType::HUGEINT);
75419
+ LogicalType::HUGEINT, LogicalType::HUGEINT, true);
75428
75420
  default:
75429
75421
  throw InternalException("Unimplemented sum aggregate");
75430
75422
  }
@@ -75444,20 +75436,20 @@ void SumFun::RegisterFunction(BuiltinFunctions &set) {
75444
75436
  AggregateFunctionSet sum("sum");
75445
75437
  // decimal
75446
75438
  sum.AddFunction(AggregateFunction({LogicalTypeId::DECIMAL}, LogicalTypeId::DECIMAL, nullptr, nullptr, nullptr,
75447
- nullptr, nullptr, nullptr, BindDecimalSum));
75439
+ nullptr, nullptr, true, nullptr, BindDecimalSum));
75448
75440
  sum.AddFunction(GetSumAggregate(PhysicalType::INT16));
75449
75441
  sum.AddFunction(GetSumAggregate(PhysicalType::INT32));
75450
75442
  sum.AddFunction(GetSumAggregate(PhysicalType::INT64));
75451
75443
  sum.AddFunction(GetSumAggregate(PhysicalType::INT128));
75452
75444
  sum.AddFunction(AggregateFunction::UnaryAggregate<SumState<double>, double, double, NumericSumOperation>(
75453
- LogicalType::DOUBLE, LogicalType::DOUBLE));
75445
+ LogicalType::DOUBLE, LogicalType::DOUBLE, true));
75454
75446
 
75455
75447
  set.AddFunction(sum);
75456
75448
 
75457
75449
  // fsum
75458
75450
  AggregateFunctionSet fsum("fsum");
75459
75451
  fsum.AddFunction(AggregateFunction::UnaryAggregate<KahanSumState, double, double, KahanSumOperation>(
75460
- LogicalType::DOUBLE, LogicalType::DOUBLE));
75452
+ LogicalType::DOUBLE, LogicalType::DOUBLE, true));
75461
75453
 
75462
75454
  set.AddFunction(fsum);
75463
75455
 
@@ -80122,9 +80114,9 @@ bool SimpleNamedParameterFunction::HasNamedParameters() {
80122
80114
  }
80123
80115
 
80124
80116
  BaseScalarFunction::BaseScalarFunction(string name_p, vector<LogicalType> arguments_p, LogicalType return_type_p,
80125
- bool has_side_effects, LogicalType varargs_p)
80117
+ bool has_side_effects, LogicalType varargs_p, bool propagates_null_values_p)
80126
80118
  : SimpleFunction(move(name_p), move(arguments_p), move(varargs_p)), return_type(move(return_type_p)),
80127
- has_side_effects(has_side_effects) {
80119
+ has_side_effects(has_side_effects), propagates_null_values(propagates_null_values_p) {
80128
80120
  }
80129
80121
 
80130
80122
  BaseScalarFunction::~BaseScalarFunction() {
@@ -81192,8 +81184,8 @@ void CurrentDateFun::RegisterFunction(BuiltinFunctions &set) {
81192
81184
  }
81193
81185
 
81194
81186
  void CurrentTimestampFun::RegisterFunction(BuiltinFunctions &set) {
81195
- set.AddFunction({"now", "current_timestamp"},
81196
- ScalarFunction({}, LogicalType::TIMESTAMP, CurrentTimestampFunction, false, BindCurrentTime));
81187
+ set.AddFunction({"now", "current_timestamp"}, ScalarFunction({}, LogicalType::TIMESTAMP, CurrentTimestampFunction,
81188
+ false, false, BindCurrentTime));
81197
81189
  }
81198
81190
 
81199
81191
  } // namespace duckdb
@@ -82840,9 +82832,9 @@ void AddGenericDatePartOperator(BuiltinFunctions &set, const string &name, scala
82840
82832
  scalar_function_t ts_func, scalar_function_t interval_func,
82841
82833
  function_statistics_t date_stats, function_statistics_t ts_stats) {
82842
82834
  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,
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,
82846
82838
  nullptr, nullptr, ts_stats));
82847
82839
  operator_set.AddFunction(ScalarFunction({LogicalType::INTERVAL}, LogicalType::BIGINT, move(interval_func)));
82848
82840
  set.AddFunction(operator_set);
@@ -82861,13 +82853,13 @@ void AddGenericTimePartOperator(BuiltinFunctions &set, const string &name, scala
82861
82853
  function_statistics_t date_stats, function_statistics_t ts_stats,
82862
82854
  function_statistics_t time_stats) {
82863
82855
  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,
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,
82867
82859
  nullptr, nullptr, ts_stats));
82868
82860
  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));
82861
+ operator_set.AddFunction(ScalarFunction({LogicalType::TIME}, LogicalType::BIGINT, move(time_func), false, false,
82862
+ nullptr, nullptr, time_stats));
82871
82863
  set.AddFunction(operator_set);
82872
82864
  }
82873
82865
 
@@ -83066,7 +83058,7 @@ struct StructDatePart {
83066
83058
  static ScalarFunction GetFunction(const LogicalType &temporal_type) {
83067
83059
  auto part_type = LogicalType::LIST(LogicalType::VARCHAR);
83068
83060
  auto result_type = LogicalType::STRUCT({});
83069
- 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);
83070
83062
  }
83071
83063
  };
83072
83064
 
@@ -84846,16 +84838,16 @@ void StrfTimeFun::RegisterFunction(BuiltinFunctions &set) {
84846
84838
  ScalarFunctionSet strftime("strftime");
84847
84839
 
84848
84840
  strftime.AddFunction(ScalarFunction({LogicalType::DATE, LogicalType::VARCHAR}, LogicalType::VARCHAR,
84849
- StrfTimeFunctionDate<false>, false, StrfTimeBindFunction<false>));
84841
+ StrfTimeFunctionDate<false>, false, false, StrfTimeBindFunction<false>));
84850
84842
 
84851
84843
  strftime.AddFunction(ScalarFunction({LogicalType::TIMESTAMP, LogicalType::VARCHAR}, LogicalType::VARCHAR,
84852
- StrfTimeFunctionTimestamp<false>, false, StrfTimeBindFunction<false>));
84844
+ StrfTimeFunctionTimestamp<false>, false, false, StrfTimeBindFunction<false>));
84853
84845
 
84854
84846
  strftime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::DATE}, LogicalType::VARCHAR,
84855
- StrfTimeFunctionDate<true>, false, StrfTimeBindFunction<true>));
84847
+ StrfTimeFunctionDate<true>, false, false, StrfTimeBindFunction<true>));
84856
84848
 
84857
84849
  strftime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP}, LogicalType::VARCHAR,
84858
- StrfTimeFunctionTimestamp<true>, false, StrfTimeBindFunction<true>));
84850
+ StrfTimeFunctionTimestamp<true>, false, false, StrfTimeBindFunction<true>));
84859
84851
 
84860
84852
  set.AddFunction(strftime);
84861
84853
  }
@@ -85418,7 +85410,7 @@ void StrpTimeFun::RegisterFunction(BuiltinFunctions &set) {
85418
85410
  ScalarFunctionSet strptime("strptime");
85419
85411
 
85420
85412
  strptime.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::TIMESTAMP,
85421
- StrpTimeFunction, false, StrpTimeBindFunction));
85413
+ StrpTimeFunction, false, false, StrpTimeBindFunction));
85422
85414
 
85423
85415
  set.AddFunction(strptime);
85424
85416
  }
@@ -86068,22 +86060,23 @@ static void LeastGreatestFunction(DataChunk &args, ExpressionState &state, Vecto
86068
86060
 
86069
86061
  template <typename T, class OP>
86070
86062
  ScalarFunction GetLeastGreatestFunction(const LogicalType &type) {
86071
- return ScalarFunction({type}, type, LeastGreatestFunction<T, OP>, false, nullptr, nullptr, nullptr, nullptr, type);
86063
+ return ScalarFunction({type}, type, LeastGreatestFunction<T, OP>, true, false, nullptr, nullptr, nullptr, nullptr,
86064
+ type);
86072
86065
  }
86073
86066
 
86074
86067
  template <class OP>
86075
86068
  static void RegisterLeastGreatest(BuiltinFunctions &set, const string &fun_name) {
86076
86069
  ScalarFunctionSet fun_set(fun_name);
86077
86070
  fun_set.AddFunction(ScalarFunction({LogicalType::BIGINT}, LogicalType::BIGINT, LeastGreatestFunction<int64_t, OP>,
86078
- false, nullptr, nullptr, nullptr, nullptr, LogicalType::BIGINT));
86071
+ true, false, nullptr, nullptr, nullptr, nullptr, LogicalType::BIGINT));
86079
86072
  fun_set.AddFunction(ScalarFunction({LogicalType::HUGEINT}, LogicalType::HUGEINT,
86080
- LeastGreatestFunction<hugeint_t, OP>, false, nullptr, nullptr, nullptr, nullptr,
86081
- LogicalType::HUGEINT));
86073
+ LeastGreatestFunction<hugeint_t, OP>, true, false, nullptr, nullptr, nullptr,
86074
+ nullptr, LogicalType::HUGEINT));
86082
86075
  fun_set.AddFunction(ScalarFunction({LogicalType::DOUBLE}, LogicalType::DOUBLE, LeastGreatestFunction<double, OP>,
86083
- false, nullptr, nullptr, nullptr, nullptr, LogicalType::DOUBLE));
86076
+ true, false, nullptr, nullptr, nullptr, nullptr, LogicalType::DOUBLE));
86084
86077
  fun_set.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR,
86085
- LeastGreatestFunction<string_t, OP, true>, false, nullptr, nullptr, nullptr,
86086
- nullptr, LogicalType::VARCHAR));
86078
+ LeastGreatestFunction<string_t, OP, true>, true, false, nullptr, nullptr,
86079
+ nullptr, nullptr, LogicalType::VARCHAR));
86087
86080
 
86088
86081
  fun_set.AddFunction(GetLeastGreatestFunction<timestamp_t, OP>(LogicalType::TIMESTAMP));
86089
86082
  fun_set.AddFunction(GetLeastGreatestFunction<time_t, OP>(LogicalType::TIME));
@@ -86378,7 +86371,7 @@ static unique_ptr<FunctionData> ArraySliceBind(ClientContext &context, ScalarFun
86378
86371
  void ArraySliceFun::RegisterFunction(BuiltinFunctions &set) {
86379
86372
  // the arguments and return types are actually set in the binder function
86380
86373
  ScalarFunction fun({LogicalType::ANY, LogicalType::BIGINT, LogicalType::BIGINT}, LogicalType::ANY,
86381
- ArraySliceFunction, false, ArraySliceBind);
86374
+ ArraySliceFunction, false, false, ArraySliceBind);
86382
86375
  fun.varargs = LogicalType::ANY;
86383
86376
  set.AddFunction({"array_slice", "list_slice"}, fun);
86384
86377
  }
@@ -86594,13 +86587,13 @@ static unique_ptr<FunctionData> ListPositionBind(ClientContext &context, ScalarF
86594
86587
  ScalarFunction ListContainsFun::GetFunction() {
86595
86588
  return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::ANY}, // argument list
86596
86589
  LogicalType::BOOLEAN, // return type
86597
- ListContainsFunction, false, ListContainsBind, nullptr);
86590
+ ListContainsFunction, false, false, ListContainsBind, nullptr);
86598
86591
  }
86599
86592
 
86600
86593
  ScalarFunction ListPositionFun::GetFunction() {
86601
86594
  return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::ANY}, // argument list
86602
86595
  LogicalType::INTEGER, // return type
86603
- ListPositionFunction, false, ListPositionBind, nullptr);
86596
+ ListPositionFunction, false, false, ListPositionBind, nullptr);
86604
86597
  }
86605
86598
 
86606
86599
  void ListContainsFun::RegisterFunction(BuiltinFunctions &set) {
@@ -86776,7 +86769,7 @@ static unique_ptr<BaseStatistics> ListFlattenStats(ClientContext &context, Bound
86776
86769
 
86777
86770
  void ListFlattenFun::RegisterFunction(BuiltinFunctions &set) {
86778
86771
  ScalarFunction fun({LogicalType::LIST(LogicalType::LIST(LogicalType::ANY))}, LogicalType::LIST(LogicalType::ANY),
86779
- ListFlattenFunction, false, ListFlattenBind, nullptr, ListFlattenStats);
86772
+ ListFlattenFunction, false, false, ListFlattenBind, nullptr, ListFlattenStats);
86780
86773
  set.AddFunction({"flatten"}, fun);
86781
86774
  }
86782
86775
 
@@ -87129,8 +87122,8 @@ static unique_ptr<BaseStatistics> ListConcatStats(ClientContext &context, BoundF
87129
87122
  ScalarFunction ListConcatFun::GetFunction() {
87130
87123
  // the arguments and return types are actually set in the binder function
87131
87124
  return ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::LIST(LogicalType::ANY)},
87132
- LogicalType::LIST(LogicalType::ANY), ListConcatFunction, false, ListConcatBind, nullptr,
87133
- ListConcatStats);
87125
+ LogicalType::LIST(LogicalType::ANY), ListConcatFunction, false, false, ListConcatBind,
87126
+ nullptr, ListConcatStats);
87134
87127
  }
87135
87128
 
87136
87129
  void ListConcatFun::RegisterFunction(BuiltinFunctions &set) {
@@ -87368,10 +87361,10 @@ static unique_ptr<BaseStatistics> ListExtractStats(ClientContext &context, Bound
87368
87361
  void ListExtractFun::RegisterFunction(BuiltinFunctions &set) {
87369
87362
  // the arguments and return types are actually set in the binder function
87370
87363
  ScalarFunction lfun({LogicalType::LIST(LogicalType::ANY), LogicalType::BIGINT}, LogicalType::ANY,
87371
- ListExtractFunction, false, ListExtractBind, nullptr, ListExtractStats);
87364
+ ListExtractFunction, false, false, ListExtractBind, nullptr, ListExtractStats);
87372
87365
 
87373
87366
  ScalarFunction sfun({LogicalType::VARCHAR, LogicalType::INTEGER}, LogicalType::VARCHAR, ListExtractFunction, false,
87374
- nullptr);
87367
+ false, nullptr);
87375
87368
 
87376
87369
  ScalarFunctionSet list_extract("list_extract");
87377
87370
  list_extract.AddFunction(lfun);
@@ -88230,7 +88223,7 @@ void AbsFun::RegisterFunction(BuiltinFunctions &set) {
88230
88223
  ScalarFunctionSet abs("abs");
88231
88224
  for (auto &type : LogicalType::Numeric()) {
88232
88225
  if (type.id() == LogicalTypeId::DECIMAL) {
88233
- abs.AddFunction(ScalarFunction({type}, type, nullptr, false, DecimalUnaryOpBind<AbsOperator>));
88226
+ abs.AddFunction(ScalarFunction({type}, type, nullptr, false, false, DecimalUnaryOpBind<AbsOperator>));
88234
88227
  } else {
88235
88228
  abs.AddFunction(ScalarFunction({type}, type, ScalarFunction::GetScalarUnaryFunction<AbsOperator>(type)));
88236
88229
  }
@@ -88404,7 +88397,7 @@ void CeilFun::RegisterFunction(BuiltinFunctions &set) {
88404
88397
  default:
88405
88398
  throw InternalException("Unimplemented numeric type for function \"ceil\"");
88406
88399
  }
88407
- ceil.AddFunction(ScalarFunction({type}, type, func, false, bind_func));
88400
+ ceil.AddFunction(ScalarFunction({type}, type, func, false, false, bind_func));
88408
88401
  }
88409
88402
 
88410
88403
  set.AddFunction(ceil);
@@ -88460,7 +88453,7 @@ void FloorFun::RegisterFunction(BuiltinFunctions &set) {
88460
88453
  default:
88461
88454
  throw InternalException("Unimplemented numeric type for function \"floor\"");
88462
88455
  }
88463
- floor.AddFunction(ScalarFunction({type}, type, func, false, bind_func));
88456
+ floor.AddFunction(ScalarFunction({type}, type, func, false, false, bind_func));
88464
88457
  }
88465
88458
  set.AddFunction(floor);
88466
88459
  }
@@ -88667,8 +88660,9 @@ void RoundFun::RegisterFunction(BuiltinFunctions &set) {
88667
88660
  default:
88668
88661
  throw InternalException("Unimplemented numeric type for function \"floor\"");
88669
88662
  }
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));
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));
88672
88666
  }
88673
88667
  set.AddFunction(round);
88674
88668
  }
@@ -90267,23 +90261,23 @@ void MultiplyFun::RegisterFunction(BuiltinFunctions &set) {
90267
90261
  ScalarFunctionSet functions("*");
90268
90262
  for (auto &type : LogicalType::Numeric()) {
90269
90263
  if (type.id() == LogicalTypeId::DECIMAL) {
90270
- functions.AddFunction(ScalarFunction({type, type}, type, nullptr, false, BindDecimalMultiply));
90264
+ functions.AddFunction(ScalarFunction({type, type}, type, nullptr, true, false, BindDecimalMultiply));
90271
90265
  } else if (TypeIsIntegral(type.InternalType()) && type.id() != LogicalTypeId::HUGEINT) {
90272
90266
  functions.AddFunction(ScalarFunction(
90273
- {type, type}, type, GetScalarIntegerFunction<MultiplyOperatorOverflowCheck>(type.InternalType()), false,
90274
- nullptr, nullptr,
90267
+ {type, type}, type, GetScalarIntegerFunction<MultiplyOperatorOverflowCheck>(type.InternalType()), true,
90268
+ false, nullptr, nullptr,
90275
90269
  PropagateNumericStats<TryMultiplyOperator, MultiplyPropagateStatistics, MultiplyOperator>));
90276
90270
  } else {
90277
- functions.AddFunction(
90278
- ScalarFunction({type, type}, type, GetScalarBinaryFunction<MultiplyOperator>(type.InternalType())));
90271
+ functions.AddFunction(ScalarFunction({type, type}, type,
90272
+ GetScalarBinaryFunction<MultiplyOperator>(type.InternalType()), true));
90279
90273
  }
90280
90274
  }
90281
90275
  functions.AddFunction(
90282
90276
  ScalarFunction({LogicalType::INTERVAL, LogicalType::BIGINT}, LogicalType::INTERVAL,
90283
- ScalarFunction::BinaryFunction<interval_t, int64_t, interval_t, MultiplyOperator>));
90277
+ ScalarFunction::BinaryFunction<interval_t, int64_t, interval_t, MultiplyOperator>, true));
90284
90278
  functions.AddFunction(
90285
90279
  ScalarFunction({LogicalType::BIGINT, LogicalType::INTERVAL}, LogicalType::INTERVAL,
90286
- ScalarFunction::BinaryFunction<int64_t, interval_t, interval_t, MultiplyOperator>));
90280
+ ScalarFunction::BinaryFunction<int64_t, interval_t, interval_t, MultiplyOperator>, true));
90287
90281
  set.AddFunction(functions);
90288
90282
  }
90289
90283
 
@@ -91521,7 +91515,7 @@ void LowerFun::RegisterFunction(BuiltinFunctions &set) {
91521
91515
  void UpperFun::RegisterFunction(BuiltinFunctions &set) {
91522
91516
  set.AddFunction({"upper", "ucase"},
91523
91517
  ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR, CaseConvertFunction<true>, false,
91524
- nullptr, nullptr, CaseConvertPropagateStats<true>));
91518
+ false, nullptr, nullptr, CaseConvertPropagateStats<true>));
91525
91519
  }
91526
91520
 
91527
91521
  } // namespace duckdb
@@ -92251,11 +92245,11 @@ static unique_ptr<FunctionData> ListLengthBind(ClientContext &context, ScalarFun
92251
92245
  void LengthFun::RegisterFunction(BuiltinFunctions &set) {
92252
92246
  ScalarFunction array_length_unary = ScalarFunction(
92253
92247
  {LogicalType::LIST(LogicalType::ANY)}, LogicalType::BIGINT,
92254
- ScalarFunction::UnaryFunction<list_entry_t, int64_t, ArrayLengthOperator>, false, ListLengthBind);
92248
+ ScalarFunction::UnaryFunction<list_entry_t, int64_t, ArrayLengthOperator>, false, false, ListLengthBind);
92255
92249
  ScalarFunctionSet length("length");
92256
92250
  length.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::BIGINT,
92257
92251
  ScalarFunction::UnaryFunction<string_t, int64_t, StringLengthOperator>, false,
92258
- nullptr, nullptr, LengthPropagateStats));
92252
+ false, nullptr, nullptr, LengthPropagateStats));
92259
92253
  length.AddFunction(array_length_unary);
92260
92254
  set.AddFunction(length);
92261
92255
  length.name = "len";
@@ -92266,7 +92260,7 @@ void LengthFun::RegisterFunction(BuiltinFunctions &set) {
92266
92260
  array_length.AddFunction(
92267
92261
  ScalarFunction({LogicalType::LIST(LogicalType::ANY), LogicalType::BIGINT}, LogicalType::BIGINT,
92268
92262
  ScalarFunction::BinaryFunction<list_entry_t, int64_t, int64_t, ArrayLengthBinaryOperator>, false,
92269
- ListLengthBind));
92263
+ false, ListLengthBind));
92270
92264
  set.AddFunction(array_length);
92271
92265
 
92272
92266
  set.AddFunction(ScalarFunction("strlen", {LogicalType::VARCHAR}, LogicalType::BIGINT,
@@ -95015,34 +95009,36 @@ static unique_ptr<FunctionData> RegexExtractBind(ClientContext &context, ScalarF
95015
95009
  void RegexpFun::RegisterFunction(BuiltinFunctions &set) {
95016
95010
  ScalarFunctionSet regexp_full_match("regexp_full_match");
95017
95011
  regexp_full_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::BOOLEAN,
95018
- RegexpMatchesFunction<RegexFullMatch>, false, RegexpMatchesBind,
95012
+ RegexpMatchesFunction<RegexFullMatch>, false, false, RegexpMatchesBind,
95019
95013
  nullptr, nullptr, RegexInitLocalState));
95020
95014
  regexp_full_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
95021
95015
  LogicalType::BOOLEAN, RegexpMatchesFunction<RegexFullMatch>, false,
95022
- RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
95016
+ false, RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
95023
95017
 
95024
95018
  ScalarFunctionSet regexp_partial_match("regexp_matches");
95025
95019
  regexp_partial_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::BOOLEAN,
95026
- RegexpMatchesFunction<RegexPartialMatch>, false, RegexpMatchesBind,
95027
- nullptr, nullptr, RegexInitLocalState));
95020
+ RegexpMatchesFunction<RegexPartialMatch>, false, false,
95021
+ RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
95028
95022
  regexp_partial_match.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
95029
95023
  LogicalType::BOOLEAN, RegexpMatchesFunction<RegexPartialMatch>,
95030
- false, RegexpMatchesBind, nullptr, nullptr, RegexInitLocalState));
95024
+ false, false, RegexpMatchesBind, nullptr, nullptr,
95025
+ RegexInitLocalState));
95031
95026
 
95032
95027
  ScalarFunctionSet regexp_replace("regexp_replace");
95033
95028
  regexp_replace.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
95034
- LogicalType::VARCHAR, RegexReplaceFunction, false, RegexReplaceBind));
95029
+ LogicalType::VARCHAR, RegexReplaceFunction, false, false,
95030
+ RegexReplaceBind));
95035
95031
  regexp_replace.AddFunction(
95036
95032
  ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR},
95037
- LogicalType::VARCHAR, RegexReplaceFunction, false, RegexReplaceBind));
95033
+ LogicalType::VARCHAR, RegexReplaceFunction, false, false, RegexReplaceBind));
95038
95034
 
95039
95035
  ScalarFunctionSet regexp_extract("regexp_extract");
95040
95036
  regexp_extract.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::VARCHAR,
95041
- RegexExtractFunction, false, RegexExtractBind, nullptr, nullptr,
95037
+ RegexExtractFunction, false, false, RegexExtractBind, nullptr, nullptr,
95042
95038
  RegexExtractInitLocalState));
95043
95039
  regexp_extract.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::INTEGER},
95044
- LogicalType::VARCHAR, RegexExtractFunction, false, RegexExtractBind,
95045
- nullptr, nullptr, RegexExtractInitLocalState));
95040
+ LogicalType::VARCHAR, RegexExtractFunction, false, false,
95041
+ RegexExtractBind, nullptr, nullptr, RegexExtractInitLocalState));
95046
95042
 
95047
95043
  set.AddFunction(regexp_full_match);
95048
95044
  set.AddFunction(regexp_partial_match);
@@ -95735,10 +95731,10 @@ static unique_ptr<BaseStatistics> SubstringPropagateStats(ClientContext &context
95735
95731
  void SubstringFun::RegisterFunction(BuiltinFunctions &set) {
95736
95732
  ScalarFunctionSet substr("substring");
95737
95733
  substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT, LogicalType::BIGINT},
95738
- LogicalType::VARCHAR, SubstringFunction, false, nullptr, nullptr,
95734
+ LogicalType::VARCHAR, SubstringFunction, false, false, nullptr, nullptr,
95739
95735
  SubstringPropagateStats));
95740
95736
  substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT}, LogicalType::VARCHAR,
95741
- SubstringFunction, false, nullptr, nullptr, SubstringPropagateStats));
95737
+ SubstringFunction, false, false, nullptr, nullptr, SubstringPropagateStats));
95742
95738
  set.AddFunction(substr);
95743
95739
  substr.name = "substr";
95744
95740
  set.AddFunction(substr);
@@ -96731,7 +96727,7 @@ static void GenerateUUIDFunction(DataChunk &args, ExpressionState &state, Vector
96731
96727
  }
96732
96728
 
96733
96729
  void UUIDFun::RegisterFunction(BuiltinFunctions &set) {
96734
- ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, true, UUIDRandomBind);
96730
+ ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, false, true, UUIDRandomBind);
96735
96731
  // generate a random uuid
96736
96732
  set.AddFunction({"uuid", "gen_random_uuid"}, uuid_function);
96737
96733
  }
@@ -96744,18 +96740,19 @@ namespace duckdb {
96744
96740
  ScalarFunction::ScalarFunction(string name, vector<LogicalType> arguments, LogicalType return_type,
96745
96741
  scalar_function_t function, bool has_side_effects, bind_scalar_function_t bind,
96746
96742
  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)),
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),
96749
96746
  function(move(function)), bind(bind), init_local_state(init_local_state), dependency(dependency),
96750
96747
  statistics(statistics) {
96751
96748
  }
96752
96749
 
96753
96750
  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)
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)
96757
96754
  : ScalarFunction(string(), move(arguments), move(return_type), move(function), has_side_effects, bind, dependency,
96758
- statistics, init_local_state, move(varargs)) {
96755
+ statistics, init_local_state, move(varargs), propagate_null_values) {
96759
96756
  }
96760
96757
 
96761
96758
  bool ScalarFunction::operator==(const ScalarFunction &rhs) const {
@@ -120070,7 +120067,11 @@ const vector<ColumnDefinition> &JoinRelation::Columns() {
120070
120067
 
120071
120068
  string JoinRelation::ToString(idx_t depth) {
120072
120069
  string str = RenderWhitespace(depth);
120073
- str = "Join " + JoinTypeToString(join_type);
120070
+ str += "Join " + JoinTypeToString(join_type);
120071
+ if (condition) {
120072
+ str += " " + condition->GetName();
120073
+ }
120074
+
120074
120075
  return str + "\n" + left->ToString(depth + 1) + "\n" + right->ToString(depth + 1);
120075
120076
  }
120076
120077
 
@@ -120181,6 +120182,7 @@ public:
120181
120182
 
120182
120183
  vector<OrderByNode> orders;
120183
120184
  shared_ptr<Relation> child;
120185
+ vector<ColumnDefinition> columns;
120184
120186
 
120185
120187
  public:
120186
120188
  unique_ptr<QueryNode> GetQueryNode() override;
@@ -120203,23 +120205,26 @@ public:
120203
120205
 
120204
120206
 
120205
120207
 
120208
+
120209
+
120206
120210
  namespace duckdb {
120207
120211
 
120208
120212
  OrderRelation::OrderRelation(shared_ptr<Relation> child_p, vector<OrderByNode> orders)
120209
120213
  : Relation(child_p->context, RelationType::ORDER_RELATION), orders(move(orders)), child(move(child_p)) {
120210
120214
  // bind the expressions
120211
- vector<ColumnDefinition> dummy_columns;
120212
- context.GetContext()->TryBindRelation(*this, dummy_columns);
120215
+ context.GetContext()->TryBindRelation(*this, this->columns);
120213
120216
  }
120214
120217
 
120215
120218
  unique_ptr<QueryNode> OrderRelation::GetQueryNode() {
120216
- auto child_node = child->GetQueryNode();
120219
+ auto select = make_unique<SelectNode>();
120220
+ select->from_table = child->GetTableRef();
120221
+ select->select_list.push_back(make_unique<StarExpression>());
120217
120222
  auto order_node = make_unique<OrderModifier>();
120218
120223
  for (idx_t i = 0; i < orders.size(); i++) {
120219
120224
  order_node->orders.emplace_back(orders[i].type, orders[i].null_order, orders[i].expression->Copy());
120220
120225
  }
120221
- child_node->modifiers.push_back(move(order_node));
120222
- return child_node;
120226
+ select->modifiers.push_back(move(order_node));
120227
+ return move(select);
120223
120228
  }
120224
120229
 
120225
120230
  string OrderRelation::GetAlias() {
@@ -120227,7 +120232,7 @@ string OrderRelation::GetAlias() {
120227
120232
  }
120228
120233
 
120229
120234
  const vector<ColumnDefinition> &OrderRelation::Columns() {
120230
- return child->Columns();
120235
+ return columns;
120231
120236
  }
120232
120237
 
120233
120238
  string OrderRelation::ToString(idx_t depth) {
@@ -122660,7 +122665,6 @@ public:
122660
122665
  void VisitExpression(unique_ptr<Expression> *expression) override;
122661
122666
  //! Whether the operator has one or more children of type DELIM_GET
122662
122667
  bool HasChildDelimGet(LogicalOperator &op);
122663
-
122664
122668
  expression_map_t<Expression *> expr_map;
122665
122669
  column_binding_map_t<bool> projection_map;
122666
122670
  unique_ptr<LogicalOperator> temp_ptr;
@@ -122669,12 +122673,12 @@ public:
122669
122673
  void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) {
122670
122674
  VisitOperatorChildren(op);
122671
122675
  VisitOperatorExpressions(op);
122672
- // now check if this is a delim join that can be removed
122673
122676
  if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN && !HasChildDelimGet(op)) {
122674
122677
  auto &delim_join = (LogicalDelimJoin &)op;
122675
122678
  auto decs = &delim_join.duplicate_eliminated_columns;
122676
122679
  for (auto &cond : delim_join.conditions) {
122677
- if (cond.comparison != ExpressionType::COMPARE_EQUAL) {
122680
+ if (cond.comparison != ExpressionType::COMPARE_EQUAL &&
122681
+ cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
122678
122682
  continue;
122679
122683
  }
122680
122684
  auto &colref = (BoundColumnRefExpression &)*cond.right;
@@ -122688,7 +122692,7 @@ void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) {
122688
122692
  }
122689
122693
  }
122690
122694
  // whether we applied an IS NOT NULL filter
122691
- cond.null_values_are_equal = true; // projection_map[colref.binding];
122695
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
122692
122696
  }
122693
122697
  }
122694
122698
  // change type if there are no more duplicate-eliminated columns
@@ -122785,6 +122789,7 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *op_ptr, Deliminat
122785
122789
  if (join.join_type != JoinType::INNER && join.join_type != JoinType::SEMI) {
122786
122790
  return false;
122787
122791
  }
122792
+
122788
122793
  // get the index (left or right) of the DelimGet side of the join
122789
122794
  idx_t delim_idx = OperatorIsDelimGet(*join.children[0]) ? 0 : 1;
122790
122795
  D_ASSERT(OperatorIsDelimGet(*join.children[delim_idx]));
@@ -122801,7 +122806,8 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *op_ptr, Deliminat
122801
122806
  // check if joining with the DelimGet is redundant, and collect relevant column information
122802
122807
  vector<Expression *> nulls_are_not_equal_exprs;
122803
122808
  for (auto &cond : join.conditions) {
122804
- if (cond.comparison != ExpressionType::COMPARE_EQUAL) {
122809
+ if (cond.comparison != ExpressionType::COMPARE_EQUAL &&
122810
+ cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
122805
122811
  // non-equality join condition
122806
122812
  return false;
122807
122813
  }
@@ -122813,7 +122819,7 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *op_ptr, Deliminat
122813
122819
  return false;
122814
122820
  }
122815
122821
  updater.expr_map[delim_side] = other_side;
122816
- if (!cond.null_values_are_equal) {
122822
+ if (cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
122817
122823
  nulls_are_not_equal_exprs.push_back(other_side);
122818
122824
  }
122819
122825
  }
@@ -126102,15 +126108,8 @@ JoinOrderOptimizer::GenerateJoins(vector<unique_ptr<LogicalOperator>> &extracted
126102
126108
  bool invert = !JoinRelationSet::IsSubset(left.first, f->left_set);
126103
126109
  cond.left = !invert ? move(comparison.left) : move(comparison.right);
126104
126110
  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
- }
126111
+ cond.comparison = condition->type;
126112
+
126114
126113
  if (invert) {
126115
126114
  // reverse comparison expression if we reverse the order of the children
126116
126115
  cond.comparison = FlipComparisionExpression(cond.comparison);
@@ -127781,7 +127780,8 @@ unique_ptr<LogicalOperator> FilterPushdown::PushdownMarkJoin(unique_ptr<LogicalO
127781
127780
  // the filter is NOT(marker), check the join conditions
127782
127781
  bool all_null_values_are_equal = true;
127783
127782
  for (auto &cond : comp_join.conditions) {
127784
- if (!cond.null_values_are_equal) {
127783
+ if (cond.comparison != ExpressionType::COMPARE_DISTINCT_FROM &&
127784
+ cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
127785
127785
  all_null_values_are_equal = false;
127786
127786
  break;
127787
127787
  }
@@ -130444,7 +130444,9 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq
130444
130444
  auto stats_left = PropagateExpression(condition.left);
130445
130445
  auto stats_right = PropagateExpression(condition.right);
130446
130446
  if (stats_left && stats_right) {
130447
- if (condition.null_values_are_equal && stats_left->CanHaveNull() && stats_right->CanHaveNull()) {
130447
+ if ((condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM ||
130448
+ condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM) &&
130449
+ stats_left->CanHaveNull() && stats_right->CanHaveNull()) {
130448
130450
  // null values are equal in this join, and both sides can have null values
130449
130451
  // nothing to do here
130450
130452
  continue;
@@ -130532,7 +130534,8 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq
130532
130534
  // anti joins have inverse statistics propagation
130533
130535
  // (i.e. if we have an anti join on i: [0, 100] and j: [0, 25], the resulting stats are i:[25,100])
130534
130536
  // for now we don't handle anti joins
130535
- if (condition.null_values_are_equal) {
130537
+ if (condition.comparison == ExpressionType::COMPARE_DISTINCT_FROM ||
130538
+ condition.comparison == ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
130536
130539
  // skip update when null values are equal (for now?)
130537
130540
  continue;
130538
130541
  }
@@ -151665,10 +151668,16 @@ BindResult BindContext::BindColumn(ColumnRefExpression &colref, idx_t depth) {
151665
151668
  }
151666
151669
 
151667
151670
  string BindContext::BindColumn(PositionalReferenceExpression &ref, string &table_name, string &column_name) {
151668
- idx_t current_position = ref.index - 1;
151669
151671
  idx_t total_columns = 0;
151672
+ idx_t current_position = ref.index - 1;
151670
151673
  for (auto &entry : bindings_list) {
151671
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
+ }
151672
151681
  if (current_position < entry_column_count) {
151673
151682
  table_name = entry.first;
151674
151683
  column_name = entry.second->names[current_position];
@@ -155042,7 +155051,7 @@ namespace duckdb {
155042
155051
  //! The FlattenDependentJoins class is responsible for pushing the dependent join down into the plan to create a
155043
155052
  //! flattened subquery
155044
155053
  struct FlattenDependentJoins {
155045
- FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated);
155054
+ FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated, bool any_join = false);
155046
155055
 
155047
155056
  //! Detects which Logical Operators have correlated expressions that they are dependent upon, filling the
155048
155057
  //! has_correlated_expressions map.
@@ -155061,8 +155070,11 @@ struct FlattenDependentJoins {
155061
155070
  const vector<CorrelatedColumnInfo> &correlated_columns;
155062
155071
  vector<LogicalType> delim_types;
155063
155072
 
155073
+ bool any_join;
155074
+
155064
155075
  private:
155065
- unique_ptr<LogicalOperator> PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan);
155076
+ unique_ptr<LogicalOperator> PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan,
155077
+ bool &parent_propagate_null_values);
155066
155078
  };
155067
155079
 
155068
155080
  } // namespace duckdb
@@ -155208,8 +155220,7 @@ static void CreateDelimJoinConditions(LogicalDelimJoin &delim_join, vector<Corre
155208
155220
  JoinCondition cond;
155209
155221
  cond.left = make_unique<BoundColumnRefExpression>(col.name, col.type, col.binding);
155210
155222
  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;
155223
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
155213
155224
  delim_join.conditions.push_back(move(cond));
155214
155225
  }
155215
155226
  }
@@ -155300,7 +155311,7 @@ static unique_ptr<Expression> PlanCorrelatedSubquery(Binder &binder, BoundSubque
155300
155311
  // LHS
155301
155312
  delim_join->AddChild(move(root));
155302
155313
  // RHS
155303
- FlattenDependentJoins flatten(binder, correlated_columns);
155314
+ FlattenDependentJoins flatten(binder, correlated_columns, true);
155304
155315
  flatten.DetectCorrelatedExpressions(plan.get());
155305
155316
  auto dependent_join = flatten.PushDownDependentJoin(move(plan));
155306
155317
 
@@ -159186,6 +159197,10 @@ bool BoundAggregateExpression::Equals(const BaseExpression *other_p) const {
159186
159197
  return true;
159187
159198
  }
159188
159199
 
159200
+ bool BoundAggregateExpression::PropagatesNullValues() const {
159201
+ return !function.propagates_null_values ? false : Expression::PropagatesNullValues();
159202
+ }
159203
+
159189
159204
  unique_ptr<Expression> BoundAggregateExpression::Copy() {
159190
159205
  vector<unique_ptr<Expression>> new_children;
159191
159206
  for (auto &child : children) {
@@ -159497,6 +159512,7 @@ bool BoundComparisonExpression::Equals(const BaseExpression *other_p) const {
159497
159512
  if (!Expression::Equals(right.get(), other->right.get())) {
159498
159513
  return false;
159499
159514
  }
159515
+
159500
159516
  return true;
159501
159517
  }
159502
159518
 
@@ -159536,6 +159552,10 @@ bool BoundConjunctionExpression::Equals(const BaseExpression *other_p) const {
159536
159552
  return ExpressionUtil::SetEquals(children, other->children);
159537
159553
  }
159538
159554
 
159555
+ bool BoundConjunctionExpression::PropagatesNullValues() const {
159556
+ return false;
159557
+ }
159558
+
159539
159559
  unique_ptr<Expression> BoundConjunctionExpression::Copy() {
159540
159560
  auto copy = make_unique<BoundConjunctionExpression>(type);
159541
159561
  for (auto &expr : children) {
@@ -159611,6 +159631,9 @@ string BoundFunctionExpression::ToString() const {
159611
159631
  return FunctionExpression::ToString<BoundFunctionExpression, Expression>(*this, string(), function.name,
159612
159632
  is_operator);
159613
159633
  }
159634
+ bool BoundFunctionExpression::PropagatesNullValues() const {
159635
+ return !function.propagates_null_values ? false : Expression::PropagatesNullValues();
159636
+ }
159614
159637
 
159615
159638
  hash_t BoundFunctionExpression::Hash() const {
159616
159639
  hash_t result = Expression::Hash();
@@ -159800,6 +159823,11 @@ unique_ptr<Expression> BoundSubqueryExpression::Copy() {
159800
159823
  throw SerializationException("Cannot copy BoundSubqueryExpression");
159801
159824
  }
159802
159825
 
159826
+ bool BoundSubqueryExpression::PropagatesNullValues() const {
159827
+ // TODO this can be optimized further by checking the actual subquery node
159828
+ return false;
159829
+ }
159830
+
159803
159831
  } // namespace duckdb
159804
159832
 
159805
159833
 
@@ -160009,6 +160037,21 @@ bool Expression::HasSideEffects() const {
160009
160037
  return has_side_effects;
160010
160038
  }
160011
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
+
160012
160055
  bool Expression::IsFoldable() const {
160013
160056
  bool is_foldable = true;
160014
160057
  ExpressionIterator::EnumerateChildren(*this, [&](const Expression &child) {
@@ -161514,7 +161557,8 @@ string IsNotNullFilter::ToString(const string &column_name) {
161514
161557
  namespace duckdb {
161515
161558
 
161516
161559
  unique_ptr<Expression> JoinCondition::CreateExpression(JoinCondition cond) {
161517
- return make_unique<BoundComparisonExpression>(cond.comparison, move(cond.left), move(cond.right));
161560
+ auto bound_comparison = make_unique<BoundComparisonExpression>(cond.comparison, move(cond.left), move(cond.right));
161561
+ return move(bound_comparison);
161518
161562
  }
161519
161563
 
161520
161564
  JoinSide JoinSide::CombineJoinSide(JoinSide left, JoinSide right) {
@@ -162777,8 +162821,9 @@ public:
162777
162821
 
162778
162822
  namespace duckdb {
162779
162823
 
162780
- FlattenDependentJoins::FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated)
162781
- : binder(binder), correlated_columns(correlated) {
162824
+ FlattenDependentJoins::FlattenDependentJoins(Binder &binder, const vector<CorrelatedColumnInfo> &correlated,
162825
+ bool any_join)
162826
+ : binder(binder), correlated_columns(correlated), any_join(any_join) {
162782
162827
  for (idx_t i = 0; i < correlated_columns.size(); i++) {
162783
162828
  auto &col = correlated_columns[i];
162784
162829
  correlated_map[col.binding] = i;
@@ -162807,7 +162852,8 @@ bool FlattenDependentJoins::DetectCorrelatedExpressions(LogicalOperator *op) {
162807
162852
  }
162808
162853
 
162809
162854
  unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoin(unique_ptr<LogicalOperator> plan) {
162810
- auto result = PushDownDependentJoinInternal(move(plan));
162855
+ bool propagate_null_values = true;
162856
+ auto result = PushDownDependentJoinInternal(move(plan), propagate_null_values);
162811
162857
  if (!replacement_map.empty()) {
162812
162858
  // check if we have to replace any COUNT aggregates into "CASE WHEN X IS NULL THEN 0 ELSE COUNT END"
162813
162859
  RewriteCountAggregates aggr(replacement_map);
@@ -162816,7 +162862,23 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoin(unique_
162816
162862
  return result;
162817
162863
  }
162818
162864
 
162819
- unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal(unique_ptr<LogicalOperator> plan) {
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) {
162820
162882
  // first check if the logical operator has correlated expressions
162821
162883
  auto entry = has_correlated_expressions.find(plan.get());
162822
162884
  D_ASSERT(entry != has_correlated_expressions.end());
@@ -162837,7 +162899,11 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162837
162899
  case LogicalOperatorType::LOGICAL_FILTER: {
162838
162900
  // filter
162839
162901
  // first we flatten the dependent join in the child of the filter
162840
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
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
+
162841
162907
  // then we replace any correlated expressions with the corresponding entry in the correlated_map
162842
162908
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
162843
162909
  rewriter.VisitOperator(*plan);
@@ -162846,7 +162912,11 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162846
162912
  case LogicalOperatorType::LOGICAL_PROJECTION: {
162847
162913
  // projection
162848
162914
  // first we flatten the dependent join in the child of the projection
162849
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
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
+
162850
162920
  // then we replace any correlated expressions with the corresponding entry in the correlated_map
162851
162921
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
162852
162922
  rewriter.VisitOperator(*plan);
@@ -162867,7 +162937,10 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162867
162937
  auto &aggr = (LogicalAggregate &)*plan;
162868
162938
  // aggregate and group by
162869
162939
  // first we flatten the dependent join in the child of the projection
162870
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
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);
162871
162944
  // then we replace any correlated expressions with the corresponding entry in the correlated_map
162872
162945
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
162873
162946
  rewriter.VisitOperator(*plan);
@@ -162884,11 +162957,18 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162884
162957
  // we have to perform a LEFT OUTER JOIN between the result of this aggregate and the delim scan
162885
162958
  // FIXME: this does not always have to be a LEFT OUTER JOIN, depending on whether aggr.expressions return
162886
162959
  // NULL or a value
162887
- auto left_outer_join = make_unique<LogicalComparisonJoin>(JoinType::LEFT);
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
+ }
162888
162968
  auto left_index = binder.GenerateTableIndex();
162889
162969
  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));
162970
+ join->children.push_back(move(delim_scan));
162971
+ join->children.push_back(move(plan));
162892
162972
  for (idx_t i = 0; i < correlated_columns.size(); i++) {
162893
162973
  JoinCondition cond;
162894
162974
  cond.left =
@@ -162896,9 +162976,8 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162896
162976
  cond.right = make_unique<BoundColumnRefExpression>(
162897
162977
  correlated_columns[i].type,
162898
162978
  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));
162979
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
162980
+ join->conditions.push_back(move(cond));
162902
162981
  }
162903
162982
  // for any COUNT aggregate we replace references to the column with: CASE WHEN COUNT(*) IS NULL THEN 0
162904
162983
  // ELSE COUNT(*) END
@@ -162916,7 +162995,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162916
162995
  base_binding.table_index = left_index;
162917
162996
  this->delim_offset = base_binding.column_index = 0;
162918
162997
  this->data_offset = 0;
162919
- return move(left_outer_join);
162998
+ return move(join);
162920
162999
  } else {
162921
163000
  // update the delim_index
162922
163001
  base_binding.table_index = aggr.group_index;
@@ -162932,20 +163011,20 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162932
163011
  bool right_has_correlation = has_correlated_expressions.find(plan->children[1].get())->second;
162933
163012
  if (!right_has_correlation) {
162934
163013
  // only left has correlation: push into left
162935
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163014
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162936
163015
  return plan;
162937
163016
  }
162938
163017
  if (!left_has_correlation) {
162939
163018
  // only right has correlation: push into right
162940
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163019
+ plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
162941
163020
  return plan;
162942
163021
  }
162943
163022
  // both sides have correlation
162944
163023
  // turn into an inner join
162945
163024
  auto join = make_unique<LogicalComparisonJoin>(JoinType::INNER);
162946
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163025
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162947
163026
  auto left_binding = this->base_binding;
162948
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163027
+ plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
162949
163028
  // add the correlated columns to the join conditions
162950
163029
  for (idx_t i = 0; i < correlated_columns.size(); i++) {
162951
163030
  JoinCondition cond;
@@ -162953,8 +163032,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162953
163032
  correlated_columns[i].type, ColumnBinding(left_binding.table_index, left_binding.column_index + i));
162954
163033
  cond.right = make_unique<BoundColumnRefExpression>(
162955
163034
  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;
163035
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
162958
163036
  join->conditions.push_back(move(cond));
162959
163037
  }
162960
163038
  join->children.push_back(move(plan->children[0]));
@@ -162973,26 +163051,30 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
162973
163051
  // inner join
162974
163052
  if (!right_has_correlation) {
162975
163053
  // only left has correlation: push into left
162976
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163054
+ plan->children[0] =
163055
+ PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162977
163056
  return plan;
162978
163057
  }
162979
163058
  if (!left_has_correlation) {
162980
163059
  // only right has correlation: push into right
162981
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163060
+ plan->children[1] =
163061
+ PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
162982
163062
  return plan;
162983
163063
  }
162984
163064
  } else if (join.join_type == JoinType::LEFT) {
162985
163065
  // left outer join
162986
163066
  if (!right_has_correlation) {
162987
163067
  // only left has correlation: push into left
162988
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163068
+ plan->children[0] =
163069
+ PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
162989
163070
  return plan;
162990
163071
  }
162991
163072
  } else if (join.join_type == JoinType::RIGHT) {
162992
163073
  // left outer join
162993
163074
  if (!left_has_correlation) {
162994
163075
  // only right has correlation: push into right
162995
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163076
+ plan->children[1] =
163077
+ PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
162996
163078
  return plan;
162997
163079
  }
162998
163080
  } else if (join.join_type == JoinType::MARK) {
@@ -163000,7 +163082,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163000
163082
  throw Exception("MARK join with correlation in RHS not supported");
163001
163083
  }
163002
163084
  // push the child into the LHS
163003
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163085
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163004
163086
  // rewrite expressions in the join conditions
163005
163087
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
163006
163088
  rewriter.VisitOperator(*plan);
@@ -163010,9 +163092,9 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163010
163092
  }
163011
163093
  // both sides have correlation
163012
163094
  // push into both sides
163013
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163095
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163014
163096
  auto left_binding = this->base_binding;
163015
- plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]));
163097
+ plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values);
163016
163098
  auto right_binding = this->base_binding;
163017
163099
  // NOTE: for OUTER JOINS it matters what the BASE BINDING is after the join
163018
163100
  // for the LEFT OUTER JOIN, we want the LEFT side to be the base binding after we push
@@ -163033,8 +163115,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163033
163115
  JoinCondition cond;
163034
163116
  cond.left = move(left);
163035
163117
  cond.right = move(right);
163036
- cond.comparison = ExpressionType::COMPARE_EQUAL;
163037
- cond.null_values_are_equal = true;
163118
+ cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM;
163038
163119
 
163039
163120
  auto &comparison_join = (LogicalComparisonJoin &)join;
163040
163121
  comparison_join.conditions.push_back(move(cond));
@@ -163060,7 +163141,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163060
163141
  if (limit.limit) {
163061
163142
  throw ParserException("Non-constant limit not supported in correlated subquery");
163062
163143
  }
163063
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163144
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163064
163145
  if (limit.limit_val == 0) {
163065
163146
  // limit = 0 means we return zero columns here
163066
163147
  return plan;
@@ -163075,7 +163156,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163075
163156
  case LogicalOperatorType::LOGICAL_WINDOW: {
163076
163157
  auto &window = (LogicalWindow &)*plan;
163077
163158
  // push into children
163078
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163159
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163079
163160
  // add the correlated columns to the PARTITION BY clauses in the Window
163080
163161
  for (auto &expr : window.expressions) {
163081
163162
  D_ASSERT(expr->GetExpressionClass() == ExpressionClass::BOUND_WINDOW);
@@ -163107,7 +163188,7 @@ unique_ptr<LogicalOperator> FlattenDependentJoins::PushDownDependentJoinInternal
163107
163188
  case LogicalOperatorType::LOGICAL_EXPRESSION_GET: {
163108
163189
  // expression get
163109
163190
  // first we flatten the dependent join in the child
163110
- plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]));
163191
+ plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values);
163111
163192
  // then we replace any correlated expressions with the corresponding entry in the correlated_map
163112
163193
  RewriteCorrelatedExpressions rewriter(base_binding, correlated_map);
163113
163194
  rewriter.VisitOperator(*plan);