duckdb 0.4.1-dev723.0 → 0.4.1-dev752.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
@@ -978,8 +978,10 @@ LogicalType Catalog::GetType(ClientContext &context, const string &schema, const
978
978
 
979
979
  void Catalog::Alter(ClientContext &context, AlterInfo *info) {
980
980
  ModifyCatalog();
981
- auto lookup = LookupEntry(context, info->GetCatalogType(), info->schema, info->name);
982
- D_ASSERT(lookup.Found()); // It must have thrown otherwise.
981
+ auto lookup = LookupEntry(context, info->GetCatalogType(), info->schema, info->name, info->if_exists);
982
+ if (!lookup.Found()) {
983
+ return;
984
+ }
983
985
  return lookup.schema->Alter(context, info);
984
986
  }
985
987
 
@@ -20486,7 +20488,7 @@ std::string NumericHelper::ToString(hugeint_t value);
20486
20488
 
20487
20489
  struct DecimalToString {
20488
20490
  template <class SIGNED, class UNSIGNED>
20489
- static int DecimalLength(SIGNED value, uint8_t scale) {
20491
+ static int DecimalLength(SIGNED value, uint8_t width, uint8_t scale) {
20490
20492
  if (scale == 0) {
20491
20493
  // scale is 0: regular number
20492
20494
  return NumericHelper::SignedLength<SIGNED, UNSIGNED>(value);
@@ -20498,11 +20500,13 @@ struct DecimalToString {
20498
20500
  // in that case we print "0.XXX", which is the scale, plus "0." (2 chars)
20499
20501
  // integer length + 1 happens when the number is outside of that range
20500
20502
  // in that case we print the integer number, but with one extra character ('.')
20501
- return MaxValue(scale + 2 + (value < 0 ? 1 : 0), NumericHelper::SignedLength<SIGNED, UNSIGNED>(value) + 1);
20503
+ auto extra_characters = width > scale ? 2 : 1;
20504
+ return MaxValue(scale + extra_characters + (value < 0 ? 1 : 0),
20505
+ NumericHelper::SignedLength<SIGNED, UNSIGNED>(value) + 1);
20502
20506
  }
20503
20507
 
20504
20508
  template <class SIGNED, class UNSIGNED>
20505
- static void FormatDecimal(SIGNED value, uint8_t scale, char *dst, idx_t len) {
20509
+ static void FormatDecimal(SIGNED value, uint8_t width, uint8_t scale, char *dst, idx_t len) {
20506
20510
  char *end = dst + len;
20507
20511
  if (value < 0) {
20508
20512
  value = -value;
@@ -20525,14 +20529,18 @@ struct DecimalToString {
20525
20529
  }
20526
20530
  *--dst = '.';
20527
20531
  // now write the part before the decimal
20528
- dst = NumericHelper::FormatUnsigned<UNSIGNED>(major, dst);
20532
+ D_ASSERT(width > scale || major == 0);
20533
+ if (width > scale) {
20534
+ // there are numbers after the comma
20535
+ dst = NumericHelper::FormatUnsigned<UNSIGNED>(major, dst);
20536
+ }
20529
20537
  }
20530
20538
 
20531
20539
  template <class SIGNED, class UNSIGNED>
20532
- static string_t Format(SIGNED value, uint8_t scale, Vector &vector) {
20533
- int len = DecimalLength<SIGNED, UNSIGNED>(value, scale);
20540
+ static string_t Format(SIGNED value, uint8_t width, uint8_t scale, Vector &vector) {
20541
+ int len = DecimalLength<SIGNED, UNSIGNED>(value, width, scale);
20534
20542
  string_t result = StringVector::EmptyString(vector, len);
20535
- FormatDecimal<SIGNED, UNSIGNED>(value, scale, result.GetDataWriteable(), len);
20543
+ FormatDecimal<SIGNED, UNSIGNED>(value, width, scale, result.GetDataWriteable(), len);
20536
20544
  result.Finalize();
20537
20545
  return result;
20538
20546
  }
@@ -20655,7 +20663,7 @@ struct HugeintToStringCast {
20655
20663
  return result;
20656
20664
  }
20657
20665
 
20658
- static int DecimalLength(hugeint_t value, uint8_t scale) {
20666
+ static int DecimalLength(hugeint_t value, uint8_t width, uint8_t scale) {
20659
20667
  int negative;
20660
20668
  if (value.upper < 0) {
20661
20669
  Hugeint::NegateInPlace(value);
@@ -20674,10 +20682,11 @@ struct HugeintToStringCast {
20674
20682
  // in that case we print "0.XXX", which is the scale, plus "0." (2 chars)
20675
20683
  // integer length + 1 happens when the number is outside of that range
20676
20684
  // in that case we print the integer number, but with one extra character ('.')
20677
- return MaxValue(scale + 2, UnsignedLength(value) + 1) + negative;
20685
+ auto extra_numbers = width > scale ? 2 : 1;
20686
+ return MaxValue(scale + extra_numbers, UnsignedLength(value) + 1) + negative;
20678
20687
  }
20679
20688
 
20680
- static void FormatDecimal(hugeint_t value, uint8_t scale, char *dst, int len) {
20689
+ static void FormatDecimal(hugeint_t value, uint8_t width, uint8_t scale, char *dst, int len) {
20681
20690
  auto endptr = dst + len;
20682
20691
 
20683
20692
  int negative = value.upper < 0;
@@ -20706,16 +20715,19 @@ struct HugeintToStringCast {
20706
20715
  }
20707
20716
  *--dst = '.';
20708
20717
  // now write the part before the decimal
20709
- dst = FormatUnsigned(major, dst);
20718
+ D_ASSERT(width > scale || major == 0);
20719
+ if (width > scale) {
20720
+ dst = FormatUnsigned(major, dst);
20721
+ }
20710
20722
  }
20711
20723
 
20712
- static string_t FormatDecimal(hugeint_t value, uint8_t scale, Vector &vector) {
20713
- int length = DecimalLength(value, scale);
20724
+ static string_t FormatDecimal(hugeint_t value, uint8_t width, uint8_t scale, Vector &vector) {
20725
+ int length = DecimalLength(value, width, scale);
20714
20726
  string_t result = StringVector::EmptyString(vector, length);
20715
20727
 
20716
20728
  auto dst = result.GetDataWriteable();
20717
20729
 
20718
- FormatDecimal(value, scale, dst, length);
20730
+ FormatDecimal(value, width, scale, dst, length);
20719
20731
 
20720
20732
  result.Finalize();
20721
20733
  return result;
@@ -24984,22 +24996,22 @@ bool TryCastToDecimal::Operation(string_t input, hugeint_t &result, string *erro
24984
24996
 
24985
24997
  template <>
24986
24998
  string_t StringCastFromDecimal::Operation(int16_t input, uint8_t width, uint8_t scale, Vector &result) {
24987
- return DecimalToString::Format<int16_t, uint16_t>(input, scale, result);
24999
+ return DecimalToString::Format<int16_t, uint16_t>(input, width, scale, result);
24988
25000
  }
24989
25001
 
24990
25002
  template <>
24991
25003
  string_t StringCastFromDecimal::Operation(int32_t input, uint8_t width, uint8_t scale, Vector &result) {
24992
- return DecimalToString::Format<int32_t, uint32_t>(input, scale, result);
25004
+ return DecimalToString::Format<int32_t, uint32_t>(input, width, scale, result);
24993
25005
  }
24994
25006
 
24995
25007
  template <>
24996
25008
  string_t StringCastFromDecimal::Operation(int64_t input, uint8_t width, uint8_t scale, Vector &result) {
24997
- return DecimalToString::Format<int64_t, uint64_t>(input, scale, result);
25009
+ return DecimalToString::Format<int64_t, uint64_t>(input, width, scale, result);
24998
25010
  }
24999
25011
 
25000
25012
  template <>
25001
25013
  string_t StringCastFromDecimal::Operation(hugeint_t input, uint8_t width, uint8_t scale, Vector &result) {
25002
- return HugeintToStringCast::FormatDecimal(input, scale, result);
25014
+ return HugeintToStringCast::FormatDecimal(input, width, scale, result);
25003
25015
  }
25004
25016
 
25005
25017
  //===--------------------------------------------------------------------===//
@@ -39884,29 +39896,29 @@ date_t Date::GetMondayOfCurrentWeek(date_t date) {
39884
39896
  namespace duckdb {
39885
39897
 
39886
39898
  template <class SIGNED, class UNSIGNED>
39887
- string TemplatedDecimalToString(SIGNED value, uint8_t scale) {
39888
- auto len = DecimalToString::DecimalLength<SIGNED, UNSIGNED>(value, scale);
39899
+ string TemplatedDecimalToString(SIGNED value, uint8_t width, uint8_t scale) {
39900
+ auto len = DecimalToString::DecimalLength<SIGNED, UNSIGNED>(value, width, scale);
39889
39901
  auto data = unique_ptr<char[]>(new char[len + 1]);
39890
- DecimalToString::FormatDecimal<SIGNED, UNSIGNED>(value, scale, data.get(), len);
39902
+ DecimalToString::FormatDecimal<SIGNED, UNSIGNED>(value, width, scale, data.get(), len);
39891
39903
  return string(data.get(), len);
39892
39904
  }
39893
39905
 
39894
- string Decimal::ToString(int16_t value, uint8_t scale) {
39895
- return TemplatedDecimalToString<int16_t, uint16_t>(value, scale);
39906
+ string Decimal::ToString(int16_t value, uint8_t width, uint8_t scale) {
39907
+ return TemplatedDecimalToString<int16_t, uint16_t>(value, width, scale);
39896
39908
  }
39897
39909
 
39898
- string Decimal::ToString(int32_t value, uint8_t scale) {
39899
- return TemplatedDecimalToString<int32_t, uint32_t>(value, scale);
39910
+ string Decimal::ToString(int32_t value, uint8_t width, uint8_t scale) {
39911
+ return TemplatedDecimalToString<int32_t, uint32_t>(value, width, scale);
39900
39912
  }
39901
39913
 
39902
- string Decimal::ToString(int64_t value, uint8_t scale) {
39903
- return TemplatedDecimalToString<int64_t, uint64_t>(value, scale);
39914
+ string Decimal::ToString(int64_t value, uint8_t width, uint8_t scale) {
39915
+ return TemplatedDecimalToString<int64_t, uint64_t>(value, width, scale);
39904
39916
  }
39905
39917
 
39906
- string Decimal::ToString(hugeint_t value, uint8_t scale) {
39907
- auto len = HugeintToStringCast::DecimalLength(value, scale);
39918
+ string Decimal::ToString(hugeint_t value, uint8_t width, uint8_t scale) {
39919
+ auto len = HugeintToStringCast::DecimalLength(value, width, scale);
39908
39920
  auto data = unique_ptr<char[]>(new char[len + 1]);
39909
- HugeintToStringCast::FormatDecimal(value, scale, data.get(), len);
39921
+ HugeintToStringCast::FormatDecimal(value, width, scale, data.get(), len);
39910
39922
  return string(data.get(), len);
39911
39923
  }
39912
39924
 
@@ -44714,16 +44726,17 @@ string Value::ToString() const {
44714
44726
  return duckdb_fmt::format("{}", value_.double_);
44715
44727
  case LogicalTypeId::DECIMAL: {
44716
44728
  auto internal_type = type_.InternalType();
44729
+ auto width = DecimalType::GetWidth(type_);
44717
44730
  auto scale = DecimalType::GetScale(type_);
44718
44731
  if (internal_type == PhysicalType::INT16) {
44719
- return Decimal::ToString(value_.smallint, scale);
44732
+ return Decimal::ToString(value_.smallint, width, scale);
44720
44733
  } else if (internal_type == PhysicalType::INT32) {
44721
- return Decimal::ToString(value_.integer, scale);
44734
+ return Decimal::ToString(value_.integer, width, scale);
44722
44735
  } else if (internal_type == PhysicalType::INT64) {
44723
- return Decimal::ToString(value_.bigint, scale);
44736
+ return Decimal::ToString(value_.bigint, width, scale);
44724
44737
  } else {
44725
44738
  D_ASSERT(internal_type == PhysicalType::INT128);
44726
- return Decimal::ToString(value_.hugeint, scale);
44739
+ return Decimal::ToString(value_.hugeint, width, scale);
44727
44740
  }
44728
44741
  }
44729
44742
  case LogicalTypeId::DATE:
@@ -50705,9 +50718,9 @@ struct DecimalScaleInput {
50705
50718
  DecimalScaleInput(Vector &result_p, FACTOR_TYPE factor_p) : result(result_p), factor(factor_p) {
50706
50719
  }
50707
50720
  DecimalScaleInput(Vector &result_p, LIMIT_TYPE limit_p, FACTOR_TYPE factor_p, string *error_message_p,
50708
- uint8_t source_scale_p)
50721
+ uint8_t source_width_p, uint8_t source_scale_p)
50709
50722
  : result(result_p), limit(limit_p), factor(factor_p), error_message(error_message_p),
50710
- source_scale(source_scale_p) {
50723
+ source_width(source_width_p), source_scale(source_scale_p) {
50711
50724
  }
50712
50725
 
50713
50726
  Vector &result;
@@ -50715,6 +50728,7 @@ struct DecimalScaleInput {
50715
50728
  FACTOR_TYPE factor;
50716
50729
  bool all_converted = true;
50717
50730
  string *error_message;
50731
+ uint8_t source_width;
50718
50732
  uint8_t source_scale;
50719
50733
  };
50720
50734
 
@@ -50731,9 +50745,9 @@ struct DecimalScaleUpCheckOperator {
50731
50745
  static RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) {
50732
50746
  auto data = (DecimalScaleInput<INPUT_TYPE, RESULT_TYPE> *)dataptr;
50733
50747
  if (input >= data->limit || input <= -data->limit) {
50734
- auto error =
50735
- StringUtil::Format("Casting value \"%s\" to type %s failed: value is out of range!",
50736
- Decimal::ToString(input, data->source_scale), data->result.GetType().ToString());
50748
+ auto error = StringUtil::Format("Casting value \"%s\" to type %s failed: value is out of range!",
50749
+ Decimal::ToString(input, data->source_width, data->source_scale),
50750
+ data->result.GetType().ToString());
50737
50751
  return HandleVectorCastError::Operation<RESULT_TYPE>(move(error), mask, idx, data->error_message,
50738
50752
  data->all_converted);
50739
50753
  }
@@ -50759,7 +50773,8 @@ bool TemplatedDecimalScaleUp(Vector &source, Vector &result, idx_t count, string
50759
50773
  } else {
50760
50774
  // type might not fit: check limit
50761
50775
  auto limit = POWERS_SOURCE::POWERS_OF_TEN[target_width];
50762
- DecimalScaleInput<SOURCE, DEST> input(result, limit, multiply_factor, error_message, source_scale);
50776
+ DecimalScaleInput<SOURCE, DEST> input(result, limit, multiply_factor, error_message, source_width,
50777
+ source_scale);
50763
50778
  UnaryExecutor::GenericExecute<SOURCE, DEST, DecimalScaleUpCheckOperator>(source, result, count, &input,
50764
50779
  error_message);
50765
50780
  return input.all_converted;
@@ -50779,9 +50794,9 @@ struct DecimalScaleDownCheckOperator {
50779
50794
  static RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) {
50780
50795
  auto data = (DecimalScaleInput<INPUT_TYPE> *)dataptr;
50781
50796
  if (input >= data->limit || input <= -data->limit) {
50782
- auto error =
50783
- StringUtil::Format("Casting value \"%s\" to type %s failed: value is out of range!",
50784
- Decimal::ToString(input, data->source_scale), data->result.GetType().ToString());
50797
+ auto error = StringUtil::Format("Casting value \"%s\" to type %s failed: value is out of range!",
50798
+ Decimal::ToString(input, data->source_width, data->source_scale),
50799
+ data->result.GetType().ToString());
50785
50800
  return HandleVectorCastError::Operation<RESULT_TYPE>(move(error), mask, idx, data->error_message,
50786
50801
  data->all_converted);
50787
50802
  }
@@ -50807,7 +50822,7 @@ bool TemplatedDecimalScaleDown(Vector &source, Vector &result, idx_t count, stri
50807
50822
  } else {
50808
50823
  // type might not fit: check limit
50809
50824
  auto limit = POWERS_SOURCE::POWERS_OF_TEN[target_width];
50810
- DecimalScaleInput<SOURCE> input(result, limit, divide_factor, error_message, source_scale);
50825
+ DecimalScaleInput<SOURCE> input(result, limit, divide_factor, error_message, source_width, source_scale);
50811
50826
  UnaryExecutor::GenericExecute<SOURCE, DEST, DecimalScaleDownCheckOperator>(source, result, count, &input,
50812
50827
  error_message);
50813
50828
  return input.all_converted;
@@ -55199,8 +55214,8 @@ void ExpressionExecutor::ExecuteExpression(idx_t expr_idx, Vector &result) {
55199
55214
  states[expr_idx]->profiler.EndSample(chunk ? chunk->size() : 0);
55200
55215
  }
55201
55216
 
55202
- Value ExpressionExecutor::EvaluateScalar(const Expression &expr) {
55203
- D_ASSERT(expr.IsFoldable());
55217
+ Value ExpressionExecutor::EvaluateScalar(const Expression &expr, bool allow_unfoldable) {
55218
+ D_ASSERT(allow_unfoldable || expr.IsFoldable());
55204
55219
  D_ASSERT(expr.IsScalar());
55205
55220
  // use an ExpressionExecutor to execute the expression
55206
55221
  ExpressionExecutor executor(Allocator::DefaultAllocator(), expr);
@@ -55208,7 +55223,7 @@ Value ExpressionExecutor::EvaluateScalar(const Expression &expr) {
55208
55223
  Vector result(expr.return_type);
55209
55224
  executor.ExecuteExpression(result);
55210
55225
 
55211
- D_ASSERT(result.GetVectorType() == VectorType::CONSTANT_VECTOR);
55226
+ D_ASSERT(allow_unfoldable || result.GetVectorType() == VectorType::CONSTANT_VECTOR);
55212
55227
  auto result_value = result.GetValue(0);
55213
55228
  D_ASSERT(result_value.type().InternalType() == expr.return_type.InternalType());
55214
55229
  return result_value;
@@ -62938,7 +62953,15 @@ void PhysicalLimitPercent::GetData(ExecutionContext &context, DataChunk &chunk,
62938
62953
  if (count > 0) {
62939
62954
  count += offset;
62940
62955
  }
62941
- limit = MinValue((idx_t)(limit_percent / 100 * count), count);
62956
+ if (limit_percent < 0 || limit_percent > 100) {
62957
+ throw OutOfRangeException("Limit percent out of range, should be between 0% and 100%");
62958
+ }
62959
+ double limit_dbl = limit_percent / 100 * count;
62960
+ if (limit_dbl > count) {
62961
+ limit = count;
62962
+ } else {
62963
+ limit = idx_t(limit_dbl);
62964
+ }
62942
62965
  if (limit == 0) {
62943
62966
  return;
62944
62967
  }
@@ -63920,9 +63943,6 @@ public:
63920
63943
 
63921
63944
  unique_ptr<VacuumInfo> info;
63922
63945
 
63923
- private:
63924
- unordered_map<idx_t, idx_t> column_id_map;
63925
-
63926
63946
  public:
63927
63947
  // Source interface
63928
63948
  void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate,
@@ -64065,12 +64085,6 @@ namespace duckdb {
64065
64085
  PhysicalVacuum::PhysicalVacuum(unique_ptr<VacuumInfo> info_p, idx_t estimated_cardinality)
64066
64086
  : PhysicalOperator(PhysicalOperatorType::VACUUM, {LogicalType::BOOLEAN}, estimated_cardinality),
64067
64087
  info(move(info_p)) {
64068
- if (info->has_table) {
64069
- auto &get = (LogicalGet &)*info->bound_ref->get;
64070
- for (idx_t i = 0; i < get.column_ids.size(); i++) {
64071
- column_id_map[i] = get.column_ids[i];
64072
- }
64073
- }
64074
64088
  }
64075
64089
 
64076
64090
  class VacuumLocalSinkState : public LocalSinkState {
@@ -64107,7 +64121,7 @@ unique_ptr<GlobalSinkState> PhysicalVacuum::GetGlobalSinkState(ClientContext &co
64107
64121
  SinkResultType PhysicalVacuum::Sink(ExecutionContext &context, GlobalSinkState &gstate_p, LocalSinkState &lstate_p,
64108
64122
  DataChunk &input) const {
64109
64123
  auto &lstate = (VacuumLocalSinkState &)lstate_p;
64110
- D_ASSERT(lstate.column_distinct_stats.size() == column_id_map.size());
64124
+ D_ASSERT(lstate.column_distinct_stats.size() == info->column_id_map.size());
64111
64125
 
64112
64126
  for (idx_t col_idx = 0; col_idx < input.data.size(); col_idx++) {
64113
64127
  lstate.column_distinct_stats[col_idx]->Update(input.data[col_idx], input.size(), false);
@@ -64131,9 +64145,9 @@ SinkFinalizeType PhysicalVacuum::Finalize(Pipeline &pipeline, Event &event, Clie
64131
64145
  GlobalSinkState &gstate) const {
64132
64146
  auto &sink = (VacuumGlobalSinkState &)gstate;
64133
64147
 
64134
- auto table = info->bound_ref->table;
64148
+ auto table = info->table;
64135
64149
  for (idx_t col_idx = 0; col_idx < sink.column_distinct_stats.size(); col_idx++) {
64136
- table->storage->SetStatistics(column_id_map.at(col_idx), [&](BaseStatistics &stats) {
64150
+ table->storage->SetStatistics(info->column_id_map.at(col_idx), [&](BaseStatistics &stats) {
64137
64151
  stats.distinct_stats = move(sink.column_distinct_stats[col_idx]);
64138
64152
  });
64139
64153
  }
@@ -76551,6 +76565,16 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
76551
76565
  if (op.join_stats.empty()) {
76552
76566
  return;
76553
76567
  }
76568
+ for (auto &type : op.children[1]->types) {
76569
+ switch (type.id()) {
76570
+ case LogicalTypeId::STRUCT:
76571
+ case LogicalTypeId::LIST:
76572
+ case LogicalTypeId::MAP:
76573
+ return;
76574
+ default:
76575
+ break;
76576
+ }
76577
+ }
76554
76578
  // with equality condition and null values not equal
76555
76579
  for (auto &&condition : op.conditions) {
76556
76580
  if (condition.comparison != ExpressionType::COMPARE_EQUAL) {
@@ -79202,16 +79226,12 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalSimple &op
79202
79226
  return make_unique<PhysicalTransaction>(unique_ptr_cast<ParseInfo, TransactionInfo>(move(op.info)),
79203
79227
  op.estimated_cardinality);
79204
79228
  case LogicalOperatorType::LOGICAL_VACUUM: {
79205
- auto &info = (VacuumInfo &)*op.info;
79206
- if (!info.has_table) {
79207
- return make_unique<PhysicalVacuum>(unique_ptr_cast<ParseInfo, VacuumInfo>(move(op.info)),
79208
- op.estimated_cardinality);
79209
- }
79210
- info.bound_ref->get->ResolveOperatorTypes();
79211
- auto child = CreatePlan(*info.bound_ref->get);
79212
79229
  auto result = make_unique<PhysicalVacuum>(unique_ptr_cast<ParseInfo, VacuumInfo>(move(op.info)),
79213
79230
  op.estimated_cardinality);
79214
- result->children.push_back(move(child));
79231
+ if (!op.children.empty()) {
79232
+ auto child = CreatePlan(*op.children[0]);
79233
+ result->children.push_back(move(child));
79234
+ }
79215
79235
  return move(result);
79216
79236
  }
79217
79237
  case LogicalOperatorType::LOGICAL_LOAD:
@@ -79471,21 +79491,18 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalWindow &op
79471
79491
  types.resize(output_idx);
79472
79492
 
79473
79493
  // Identify streaming windows
79474
- vector<idx_t> blocking_windows;
79475
- vector<idx_t> streaming_windows;
79494
+ vector<idx_t> window_expressions;
79495
+ bool process_streaming = true;
79476
79496
  for (idx_t expr_idx = 0; expr_idx < op.expressions.size(); expr_idx++) {
79477
- if (IsStreamingWindow(op.expressions[expr_idx])) {
79478
- streaming_windows.push_back(expr_idx);
79479
- } else {
79480
- blocking_windows.push_back(expr_idx);
79497
+ window_expressions.push_back(expr_idx);
79498
+ if (!IsStreamingWindow(op.expressions[expr_idx])) {
79499
+ process_streaming = false;
79481
79500
  }
79482
79501
  }
79483
-
79484
79502
  // Process the window functions by sharing the partition/order definitions
79485
79503
  vector<idx_t> evaluation_order;
79486
- while (!blocking_windows.empty() || !streaming_windows.empty()) {
79487
- const bool process_streaming = blocking_windows.empty();
79488
- auto &remaining = process_streaming ? streaming_windows : blocking_windows;
79504
+ while (!window_expressions.empty()) {
79505
+ auto &remaining = window_expressions;
79489
79506
 
79490
79507
  // Find all functions that share the partitioning of the first remaining expression
79491
79508
  const auto over_idx = remaining[0];
@@ -80067,7 +80084,7 @@ void RadixPartitionedHashTable::GetData(ExecutionContext &context, DataChunk &ch
80067
80084
  // special case hack to sort out aggregating from empty intermediates
80068
80085
  // for aggregations without groups
80069
80086
  if (gstate.is_empty && grouping_set.empty()) {
80070
- D_ASSERT(chunk.ColumnCount() == null_groups.size() + op.aggregates.size());
80087
+ D_ASSERT(chunk.ColumnCount() == null_groups.size() + op.aggregates.size() + op.grouping_functions.size());
80071
80088
  // for each column in the aggregates, set to initial state
80072
80089
  chunk.SetCardinality(1);
80073
80090
  for (auto null_group : null_groups) {
@@ -80087,6 +80104,9 @@ void RadixPartitionedHashTable::GetData(ExecutionContext &context, DataChunk &ch
80087
80104
  aggr.function.destructor(state_vector, 1);
80088
80105
  }
80089
80106
  }
80107
+ for (idx_t i = 0; i < op.grouping_functions.size(); i++) {
80108
+ chunk.data[null_groups.size() + op.aggregates.size() + i].Reference(grouping_values[i]);
80109
+ }
80090
80110
  state.finished = true;
80091
80111
  return;
80092
80112
  }
@@ -103472,6 +103492,9 @@ static unique_ptr<FunctionData> LikeBindFunction(ClientContext &context, ScalarF
103472
103492
  D_ASSERT(arguments.size() == 2 || arguments.size() == 3);
103473
103493
  if (arguments[1]->IsFoldable()) {
103474
103494
  Value pattern_str = ExpressionExecutor::EvaluateScalar(*arguments[1]);
103495
+ if (pattern_str.IsNull()) {
103496
+ return nullptr;
103497
+ }
103475
103498
  return LikeMatcher::CreateLikeMatcher(pattern_str.ToString());
103476
103499
  }
103477
103500
  return nullptr;
@@ -105818,6 +105841,9 @@ static void StructExtractFunction(DataChunk &args, ExpressionState &state, Vecto
105818
105841
  static unique_ptr<FunctionData> StructExtractBind(ClientContext &context, ScalarFunction &bound_function,
105819
105842
  vector<unique_ptr<Expression>> &arguments) {
105820
105843
  D_ASSERT(bound_function.arguments.size() == 2);
105844
+ if (arguments[0]->return_type.id() == LogicalTypeId::UNKNOWN) {
105845
+ throw ParameterNotResolvedException();
105846
+ }
105821
105847
  D_ASSERT(LogicalTypeId::STRUCT == arguments[0]->return_type.id());
105822
105848
  auto &struct_children = StructType::GetChildTypes(arguments[0]->return_type);
105823
105849
  if (struct_children.empty()) {
@@ -117754,7 +117780,14 @@ unique_ptr<PendingQueryResult> ClientContext::PendingStatementInternal(ClientCon
117754
117780
  unique_ptr<SQLStatement> statement,
117755
117781
  PendingQueryParameters parameters) {
117756
117782
  // prepare the query for execution
117757
- auto prepared = CreatePreparedStatement(lock, query, move(statement));
117783
+ auto prepared = CreatePreparedStatement(lock, query, move(statement), parameters.parameters);
117784
+ if (prepared->properties.parameter_count > 0 && !parameters.parameters) {
117785
+ return make_unique<PendingQueryResult>(StringUtil::Format("Expected %lld parameters, but none were supplied",
117786
+ prepared->properties.parameter_count));
117787
+ }
117788
+ if (!prepared->properties.bound_all_parameters) {
117789
+ return make_unique<PendingQueryResult>("Not all parameters were bound");
117790
+ }
117758
117791
  // execute the prepared statement
117759
117792
  return PendingPreparedStatement(lock, move(prepared), parameters);
117760
117793
  }
@@ -138716,7 +138749,7 @@ unique_ptr<LogicalOperator> FilterPushdown::PushdownCrossProduct(unique_ptr<Logi
138716
138749
  // bindings match right side: push into right
138717
138750
  right_pushdown.filters.push_back(move(f));
138718
138751
  } else {
138719
- D_ASSERT(side == JoinSide::BOTH);
138752
+ D_ASSERT(side == JoinSide::BOTH || side == JoinSide::NONE);
138720
138753
  // bindings match both: turn into join condition
138721
138754
  join_conditions.push_back(move(f->filter));
138722
138755
  }
@@ -139604,23 +139637,6 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) {
139604
139637
  everything_referenced = true;
139605
139638
  break;
139606
139639
  }
139607
- case LogicalOperatorType::LOGICAL_VACUUM: {
139608
- auto &vacuum = (LogicalSimple &)op;
139609
- auto &info = (VacuumInfo &)*vacuum.info;
139610
- if (!info.bound_ref) {
139611
- break;
139612
- }
139613
-
139614
- auto &get = (LogicalGet &)*info.bound_ref->get;
139615
- for (auto &col : info.columns) {
139616
- for (idx_t col_idx = 0; col_idx < get.names.size(); col_idx++) {
139617
- if (get.names[col_idx] == col) {
139618
- get.column_ids.push_back(col_idx);
139619
- break;
139620
- }
139621
- }
139622
- }
139623
- }
139624
139640
  default:
139625
139641
  break;
139626
139642
  }
@@ -150987,7 +151003,7 @@ string KeywordHelper::WriteOptionallyQuoted(const string &text, char quote) {
150987
151003
  namespace duckdb {
150988
151004
 
150989
151005
  AlterInfo::AlterInfo(AlterType type, string schema_p, string name_p)
150990
- : type(type), schema(move(schema_p)), name(move(name_p)) {
151006
+ : type(type), if_exists(false), schema(move(schema_p)), name(move(name_p)) {
150991
151007
  }
150992
151008
 
150993
151009
  AlterInfo::~AlterInfo() {
@@ -160794,6 +160810,8 @@ unique_ptr<ParsedExpression> Transformer::TransformLambda(duckdb_libpgquery::PGL
160794
160810
 
160795
160811
  auto lhs = TransformExpression(node->lhs);
160796
160812
  auto rhs = TransformExpression(node->rhs);
160813
+ D_ASSERT(lhs);
160814
+ D_ASSERT(rhs);
160797
160815
  return make_unique<LambdaExpression>(move(lhs), move(rhs));
160798
160816
  }
160799
160817
 
@@ -162398,7 +162416,9 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n
162398
162416
  LogicalTypeId base_type = TransformStringToLogicalTypeId(name);
162399
162417
 
162400
162418
  LogicalType result_type;
162401
- if (base_type == LogicalTypeId::STRUCT) {
162419
+ if (base_type == LogicalTypeId::LIST) {
162420
+ throw ParserException("LIST is not valid as a stand-alone type");
162421
+ } else if (base_type == LogicalTypeId::STRUCT) {
162402
162422
  if (!type_name->typmods || type_name->typmods->length == 0) {
162403
162423
  throw ParserException("Struct needs a name and entries");
162404
162424
  }
@@ -162666,6 +162686,7 @@ unique_ptr<AlterStatement> Transformer::TransformAlter(duckdb_libpgquery::PGNode
162666
162686
  throw NotImplementedException("ALTER TABLE option not supported yet!");
162667
162687
  }
162668
162688
  }
162689
+ result->info->if_exists = stmt->missing_ok;
162669
162690
 
162670
162691
  return result;
162671
162692
  }
@@ -166421,7 +166442,7 @@ BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth,
166421
166442
  if (!is_lambda) {
166422
166443
  // this is for binding JSON
166423
166444
  auto lhs_expr = expr.lhs->Copy();
166424
- OperatorExpression arrow_expr(ExpressionType::ARROW, move(lhs_expr), move(expr.expr));
166445
+ OperatorExpression arrow_expr(ExpressionType::ARROW, move(lhs_expr), expr.expr->Copy());
166425
166446
  return BindExpression(arrow_expr, depth);
166426
166447
  }
166427
166448
 
@@ -168020,12 +168041,16 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
168020
168041
  SelectBinder select_binder(*this, context, *result, info);
168021
168042
  vector<LogicalType> internal_sql_types;
168022
168043
  for (idx_t i = 0; i < statement.select_list.size(); i++) {
168044
+ bool is_window = statement.select_list[i]->IsWindow();
168023
168045
  LogicalType result_type;
168024
168046
  auto expr = select_binder.Bind(statement.select_list[i], &result_type);
168025
168047
  if (statement.aggregate_handling == AggregateHandling::FORCE_AGGREGATES && select_binder.HasBoundColumns()) {
168026
168048
  if (select_binder.BoundAggregates()) {
168027
168049
  throw BinderException("Cannot mix aggregates with non-aggregated columns!");
168028
168050
  }
168051
+ if (is_window) {
168052
+ throw BinderException("Cannot group on a window clause");
168053
+ }
168029
168054
  // we are forcing aggregates, and the node has columns bound
168030
168055
  // this entry becomes a group
168031
168056
  auto group_ref = make_unique<BoundColumnRefExpression>(
@@ -169487,33 +169512,70 @@ void Binder::BindLogicalType(ClientContext &context, LogicalType &type, const st
169487
169512
  }
169488
169513
  }
169489
169514
 
169490
- static void FindMatchingPrimaryKeyColumns(vector<unique_ptr<Constraint>> &constraints, ForeignKeyConstraint &fk) {
169491
- if (!fk.pk_columns.empty()) {
169492
- return;
169493
- }
169515
+ static void FindMatchingPrimaryKeyColumns(const vector<ColumnDefinition> &columns,
169516
+ const vector<unique_ptr<Constraint>> &constraints, ForeignKeyConstraint &fk) {
169494
169517
  // find the matching primary key constraint
169518
+ bool found_constraint = false;
169519
+ // if no columns are defined, we will automatically try to bind to the primary key
169520
+ bool find_primary_key = fk.pk_columns.empty();
169495
169521
  for (auto &constr : constraints) {
169496
169522
  if (constr->type != ConstraintType::UNIQUE) {
169497
169523
  continue;
169498
169524
  }
169499
169525
  auto &unique = (UniqueConstraint &)*constr;
169500
- if (!unique.is_primary_key) {
169526
+ if (find_primary_key && !unique.is_primary_key) {
169501
169527
  continue;
169502
169528
  }
169503
- idx_t column_count;
169529
+ found_constraint = true;
169530
+
169531
+ vector<string> pk_names;
169504
169532
  if (unique.index != DConstants::INVALID_INDEX) {
169505
- fk.info.pk_keys.push_back(unique.index);
169506
- column_count = 1;
169533
+ pk_names.push_back(columns[unique.index].Name());
169507
169534
  } else {
169508
- fk.pk_columns = unique.columns;
169509
- column_count = unique.columns.size();
169535
+ pk_names = unique.columns;
169510
169536
  }
169511
- if (column_count != fk.fk_columns.size()) {
169512
- throw BinderException("The number of referencing and referenced columns for foreign keys must be the same");
169537
+ if (pk_names.size() != fk.fk_columns.size()) {
169538
+ // the number of referencing and referenced columns for foreign keys must be the same
169539
+ continue;
169540
+ }
169541
+ if (find_primary_key) {
169542
+ // found matching primary key
169543
+ fk.pk_columns = pk_names;
169544
+ return;
169513
169545
  }
169546
+ if (fk.pk_columns != pk_names) {
169547
+ // Name mismatch
169548
+ continue;
169549
+ }
169550
+ // found match
169514
169551
  return;
169515
169552
  }
169516
- throw BinderException("there is no primary key for referenced table \"%s\"", fk.info.table);
169553
+ // no match found! examine why
169554
+ if (!found_constraint) {
169555
+ // no unique constraint or primary key
169556
+ string search_term = find_primary_key ? "primary key" : "primary key or unique constraint";
169557
+ throw BinderException("Failed to create foreign key: there is no %s for referenced table \"%s\"", search_term,
169558
+ fk.info.table);
169559
+ }
169560
+ // check if all the columns exist
169561
+ for (auto &name : fk.pk_columns) {
169562
+ bool found = false;
169563
+ for (auto &col : columns) {
169564
+ if (col.Name() == name) {
169565
+ found = true;
169566
+ break;
169567
+ }
169568
+ }
169569
+ if (!found) {
169570
+ throw BinderException(
169571
+ "Failed to create foreign key: referenced table \"%s\" does not have a column named \"%s\"",
169572
+ fk.info.table, name);
169573
+ }
169574
+ }
169575
+ auto fk_names = StringUtil::Join(fk.pk_columns, ",");
169576
+ throw BinderException("Failed to create foreign key: referenced table \"%s\" does not have a primary key or unique "
169577
+ "constraint on the columns %s",
169578
+ fk.info.table, fk_names);
169517
169579
  }
169518
169580
 
169519
169581
  void ExpressionContainsGeneratedColumn(const ParsedExpression &expr, const unordered_set<string> &gcols,
@@ -169678,13 +169740,13 @@ BoundStatement Binder::Bind(CreateStatement &stmt) {
169678
169740
  D_ASSERT(fk.info.pk_keys.empty());
169679
169741
  if (create_info.table == fk.info.table) {
169680
169742
  fk.info.type = ForeignKeyType::FK_TYPE_SELF_REFERENCE_TABLE;
169681
- FindMatchingPrimaryKeyColumns(create_info.constraints, fk);
169743
+ FindMatchingPrimaryKeyColumns(create_info.columns, create_info.constraints, fk);
169682
169744
  } else {
169683
169745
  // have to resolve referenced table
169684
169746
  auto pk_table_entry_ptr = catalog.GetEntry<TableCatalogEntry>(context, fk.info.schema, fk.info.table);
169685
169747
  fk_schemas.insert(pk_table_entry_ptr->schema);
169686
169748
  D_ASSERT(fk.info.pk_keys.empty());
169687
- FindMatchingPrimaryKeyColumns(pk_table_entry_ptr->constraints, fk);
169749
+ FindMatchingPrimaryKeyColumns(pk_table_entry_ptr->columns, pk_table_entry_ptr->constraints, fk);
169688
169750
  for (auto &keyname : fk.pk_columns) {
169689
169751
  auto entry = pk_table_entry_ptr->name_map.find(keyname);
169690
169752
  if (entry == pk_table_entry_ptr->name_map.end()) {
@@ -170301,7 +170363,7 @@ BoundStatement Binder::Bind(ExecuteStatement &stmt) {
170301
170363
  ConstantBinder cbinder(*constant_binder, context, "EXECUTE statement");
170302
170364
  auto bound_expr = cbinder.Bind(stmt.values[i]);
170303
170365
 
170304
- Value value = ExpressionExecutor::EvaluateScalar(*bound_expr);
170366
+ Value value = ExpressionExecutor::EvaluateScalar(*bound_expr, true);
170305
170367
  bind_values.push_back(move(value));
170306
170368
  }
170307
170369
  unique_ptr<LogicalOperator> rebound_plan;
@@ -170967,7 +171029,8 @@ BoundStatement Binder::Bind(AlterStatement &stmt) {
170967
171029
  result.names = {"Success"};
170968
171030
  result.types = {LogicalType::BOOLEAN};
170969
171031
  Catalog &catalog = Catalog::GetCatalog(context);
170970
- auto entry = catalog.GetEntry(context, stmt.info->GetCatalogType(), stmt.info->schema, stmt.info->name, true);
171032
+ auto entry = catalog.GetEntry(context, stmt.info->GetCatalogType(), stmt.info->schema, stmt.info->name,
171033
+ stmt.info->if_exists);
170971
171034
  if (entry && !entry->temporary) {
170972
171035
  // we can only alter temporary tables/views in read-only mode
170973
171036
  properties.read_only = false;
@@ -171428,29 +171491,58 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) {
171428
171491
 
171429
171492
 
171430
171493
 
171494
+
171495
+
171431
171496
  namespace duckdb {
171432
171497
 
171433
171498
  BoundStatement Binder::Bind(VacuumStatement &stmt) {
171434
171499
  BoundStatement result;
171435
171500
 
171501
+ unique_ptr<LogicalOperator> root;
171502
+
171436
171503
  if (stmt.info->has_table) {
171504
+ D_ASSERT(!stmt.info->table);
171505
+ D_ASSERT(stmt.info->column_id_map.empty());
171437
171506
  auto bound_table = Bind(*stmt.info->ref);
171438
171507
  if (bound_table->type != TableReferenceType::BASE_TABLE) {
171439
171508
  throw InvalidInputException("Can only vacuum/analyze base tables!");
171440
171509
  }
171441
- stmt.info->bound_ref = unique_ptr_cast<BoundTableRef, BoundBaseTableRef>(move(bound_table));
171510
+ auto ref = unique_ptr_cast<BoundTableRef, BoundBaseTableRef>(move(bound_table));
171511
+ stmt.info->table = ref->table;
171442
171512
 
171443
171513
  auto &columns = stmt.info->columns;
171514
+ vector<unique_ptr<Expression>> select_list;
171444
171515
  if (columns.empty()) {
171445
171516
  // Empty means ALL columns should be vacuumed/analyzed
171446
- auto &get = (LogicalGet &)*stmt.info->bound_ref->get;
171517
+ auto &get = (LogicalGet &)*ref->get;
171447
171518
  columns.insert(columns.end(), get.names.begin(), get.names.end());
171448
171519
  }
171520
+ for (auto &col_name : columns) {
171521
+ ColumnRefExpression colref(col_name, ref->table->name);
171522
+ auto result = bind_context.BindColumn(colref, 0);
171523
+ D_ASSERT(!result.HasError());
171524
+ select_list.push_back(move(result.expression));
171525
+ }
171526
+ auto table_scan = CreatePlan(*ref);
171527
+ D_ASSERT(table_scan->type == LogicalOperatorType::LOGICAL_GET);
171528
+ auto &get = (LogicalGet &)*table_scan;
171529
+ for (idx_t i = 0; i < get.column_ids.size(); i++) {
171530
+ stmt.info->column_id_map[i] = get.column_ids[i];
171531
+ }
171532
+
171533
+ auto projection = make_unique<LogicalProjection>(GenerateTableIndex(), move(select_list));
171534
+ projection->children.push_back(move(table_scan));
171535
+
171536
+ root = move(projection);
171537
+ }
171538
+ auto vacuum = make_unique<LogicalSimple>(LogicalOperatorType::LOGICAL_VACUUM, move(stmt.info));
171539
+ if (root) {
171540
+ vacuum->children.push_back(move(root));
171449
171541
  }
171450
171542
 
171451
171543
  result.names = {"Success"};
171452
171544
  result.types = {LogicalType::BOOLEAN};
171453
- result.plan = make_unique<LogicalSimple>(LogicalOperatorType::LOGICAL_VACUUM, move(stmt.info));
171545
+ result.plan = move(vacuum);
171454
171546
  properties.return_type = StatementReturnType::NOTHING;
171455
171547
  return result;
171456
171548
  }
@@ -174466,8 +174558,11 @@ BindResult ColumnAliasBinder::BindAlias(ExpressionBinder &enclosing_binder, Colu
174466
174558
  return BindResult(StringUtil::Format("Alias %s is not found.", expr.ToString()));
174467
174559
  }
174468
174560
 
174561
+ if (in_alias) {
174562
+ return BindResult("Cannot resolve self-referential alias");
174563
+ }
174564
+
174469
174565
  // found an alias: bind the alias expression
174470
- D_ASSERT(!in_alias);
174471
174566
  auto expression = node.original_expressions[alias_entry->second]->Copy();
174472
174567
  in_alias = true;
174473
174568
  auto result = enclosing_binder.BindExpression(&expression, depth, root_expression);
@@ -176779,6 +176874,15 @@ namespace duckdb {
176779
176874
  Planner::Planner(ClientContext &context) : binder(Binder::CreateBinder(context)), context(context) {
176780
176875
  }
176781
176876
 
176877
+ static void CheckTreeDepth(const LogicalOperator &op, idx_t max_depth, idx_t depth = 0) {
176878
+ if (depth >= max_depth) {
176879
+ throw ParserException("Maximum tree depth of %lld exceeded in logical planner", max_depth);
176880
+ }
176881
+ for (auto &child : op.children) {
176882
+ CheckTreeDepth(*child, max_depth, depth + 1);
176883
+ }
176884
+ }
176885
+
176782
176886
  void Planner::CreatePlan(SQLStatement &statement) {
176783
176887
  auto &profiler = QueryProfiler::Get(context);
176784
176888
  auto parameter_count = statement.n_param;
@@ -176797,6 +176901,8 @@ void Planner::CreatePlan(SQLStatement &statement) {
176797
176901
  this->types = bound_statement.types;
176798
176902
  this->plan = move(bound_statement.plan);
176799
176903
 
176904
+ auto max_tree_depth = ClientConfig::GetConfig(context).max_expression_depth;
176905
+ CheckTreeDepth(*plan, max_tree_depth);
176800
176906
  } catch (ParameterNotResolvedException &ex) {
176801
176907
  // parameter types could not be resolved
176802
176908
  this->names = {"unknown"};