duckdb 0.3.2-dev782.0 → 0.3.2-dev838.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
- "version": "0.3.2-dev782.0",
4
+ "version": "0.3.2-dev838.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -38204,6 +38204,9 @@ LogicalType LogicalType::STRUCT(child_list_t<LogicalType> children) {
38204
38204
  return LogicalType(LogicalTypeId::STRUCT, move(info));
38205
38205
  }
38206
38206
 
38207
+ //===--------------------------------------------------------------------===//
38208
+ // Map Type
38209
+ //===--------------------------------------------------------------------===//
38207
38210
  LogicalType LogicalType::MAP(child_list_t<LogicalType> children) {
38208
38211
  auto info = make_shared<StructTypeInfo>(move(children));
38209
38212
  return LogicalType(LogicalTypeId::MAP, move(info));
@@ -38216,6 +38219,16 @@ LogicalType LogicalType::MAP(LogicalType key, LogicalType value) {
38216
38219
  return LogicalType::MAP(move(child_types));
38217
38220
  }
38218
38221
 
38222
+ const LogicalType &MapType::KeyType(const LogicalType &type) {
38223
+ D_ASSERT(type.id() == LogicalTypeId::MAP);
38224
+ return StructType::GetChildTypes(type)[0].second;
38225
+ }
38226
+
38227
+ const LogicalType &MapType::ValueType(const LogicalType &type) {
38228
+ D_ASSERT(type.id() == LogicalTypeId::MAP);
38229
+ return StructType::GetChildTypes(type)[1].second;
38230
+ }
38231
+
38219
38232
  //===--------------------------------------------------------------------===//
38220
38233
  // User Type
38221
38234
  //===--------------------------------------------------------------------===//
@@ -74467,7 +74480,8 @@ string MacroFunction::ValidateArguments(MacroCatalogEntry &macro_func, FunctionE
74467
74480
  } else if (defaults.find(arg->alias) != defaults.end()) {
74468
74481
  return StringUtil::Format("Duplicate default parameters %s!", arg->alias);
74469
74482
  }
74470
- defaults[arg->alias] = move(arg);
74483
+ auto alias = arg->alias;
74484
+ defaults[alias] = move(arg);
74471
74485
  } else if (!defaults.empty()) {
74472
74486
  return "Positional parameters cannot come after parameters with a default value!";
74473
74487
  } else {
@@ -88573,9 +88587,9 @@ static void GenerateUUIDFunction(DataChunk &args, ExpressionState &state, Vector
88573
88587
  }
88574
88588
 
88575
88589
  void UUIDFun::RegisterFunction(BuiltinFunctions &set) {
88590
+ ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, true, UUIDRandomBind);
88576
88591
  // generate a random uuid
88577
- set.AddFunction(
88578
- ScalarFunction("gen_random_uuid", {}, LogicalType::UUID, GenerateUUIDFunction, true, UUIDRandomBind));
88592
+ set.AddFunction({"uuid", "gen_random_uuid"}, uuid_function);
88579
88593
  }
88580
88594
 
88581
88595
  } // namespace duckdb
@@ -98273,8 +98287,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
98273
98287
  } catch (std::exception &ex) {
98274
98288
  original_result->error = ex.what();
98275
98289
  original_result->success = false;
98276
- interrupted = false;
98277
98290
  }
98291
+ interrupted = false;
98278
98292
 
98279
98293
  // check explain, only if q does not already contain EXPLAIN
98280
98294
  if (original_result->success) {
@@ -98294,8 +98308,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
98294
98308
  } catch (std::exception &ex) {
98295
98309
  copied_result->error = ex.what();
98296
98310
  copied_result->success = false;
98297
- interrupted = false;
98298
98311
  }
98312
+ interrupted = false;
98299
98313
  // now execute the deserialized statement
98300
98314
  try {
98301
98315
  auto result = RunStatementInternal(lock, query, move(deserialized_stmt), false, false);
@@ -98303,8 +98317,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
98303
98317
  } catch (std::exception &ex) {
98304
98318
  deserialized_result->error = ex.what();
98305
98319
  deserialized_result->success = false;
98306
- interrupted = false;
98307
98320
  }
98321
+ interrupted = false;
98308
98322
  // now execute the unoptimized statement
98309
98323
  config.enable_optimizer = false;
98310
98324
  try {
@@ -98313,8 +98327,8 @@ string ClientContext::VerifyQuery(ClientContextLock &lock, const string &query,
98313
98327
  } catch (std::exception &ex) {
98314
98328
  unoptimized_result->error = ex.what();
98315
98329
  unoptimized_result->success = false;
98316
- interrupted = false;
98317
98330
  }
98331
+ interrupted = false;
98318
98332
  config.enable_optimizer = true;
98319
98333
 
98320
98334
  if (profiling_is_enabled) {
@@ -99884,6 +99898,7 @@ ExtensionLoadResult ExtensionHelper::LoadExtensionInternal(DuckDB &db, const std
99884
99898
 
99885
99899
 
99886
99900
 
99901
+ #ifndef DISABLE_DUCKDB_REMOTE_INSTALL
99887
99902
 
99888
99903
 
99889
99904
  // LICENSE_CHANGE_BEGIN
@@ -107326,6 +107341,7 @@ inline SSL_CTX *Client::ssl_context() const {
107326
107341
 
107327
107342
  // LICENSE_CHANGE_END
107328
107343
 
107344
+ #endif
107329
107345
 
107330
107346
 
107331
107347
  #include <fstream>
@@ -107383,6 +107399,9 @@ void ExtensionHelper::InstallExtension(DatabaseInstance &db, const string &exten
107383
107399
  throw IOException("Failed to read extension from \"%s\": no such file", extension);
107384
107400
  }
107385
107401
 
107402
+ #ifdef DISABLE_DUCKDB_REMOTE_INSTALL
107403
+ throw BinderException("Remote extension installation is disabled through configuration");
107404
+ #else
107386
107405
  string url_template = "http://extensions.duckdb.org/${REVISION}/${PLATFORM}/${NAME}.duckdb_extension.gz";
107387
107406
 
107388
107407
  if (is_http_url) {
@@ -107421,6 +107440,7 @@ void ExtensionHelper::InstallExtension(DatabaseInstance &db, const string &exten
107421
107440
  if (out.bad()) {
107422
107441
  throw IOException("Failed to write extension to %s", local_extension_path);
107423
107442
  }
107443
+ #endif
107424
107444
  }
107425
107445
 
107426
107446
  } // namespace duckdb
@@ -112829,7 +112849,10 @@ void ExpressionRewriter::VisitExpression(unique_ptr<Expression> *expression) {
112829
112849
 
112830
112850
 
112831
112851
 
112852
+
112853
+
112832
112854
  #include <functional>
112855
+ #include <map>
112833
112856
 
112834
112857
  namespace duckdb {
112835
112858
 
@@ -112867,6 +112890,37 @@ private:
112867
112890
  idx_t GetEquivalenceSet(Expression *expr);
112868
112891
  FilterResult AddConstantComparison(vector<ExpressionValueInformation> &info_list, ExpressionValueInformation info);
112869
112892
 
112893
+ //! Functions used to push and generate OR Filters
112894
+ void LookUpConjunctions(Expression *expr);
112895
+ bool BFSLookUpConjunctions(BoundConjunctionExpression *conjunction);
112896
+ void VerifyOrsToPush(Expression &expr);
112897
+
112898
+ bool UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr);
112899
+ bool UpdateFilterByColumn(BoundColumnRefExpression *column_ref, BoundComparisonExpression *comparison_expr);
112900
+ void GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids);
112901
+
112902
+ template <typename CONJUNCTION_TYPE>
112903
+ void GenerateConjunctionFilter(BoundConjunctionExpression *conjunction, ConjunctionFilter *last_conj_filter) {
112904
+ auto new_filter = NextConjunctionFilter<CONJUNCTION_TYPE>(conjunction);
112905
+ auto conj_filter_ptr = (ConjunctionFilter *)new_filter.get();
112906
+ last_conj_filter->child_filters.push_back(move(new_filter));
112907
+ last_conj_filter = conj_filter_ptr;
112908
+ }
112909
+
112910
+ template <typename CONJUNCTION_TYPE>
112911
+ unique_ptr<TableFilter> NextConjunctionFilter(BoundConjunctionExpression *conjunction) {
112912
+ unique_ptr<ConjunctionFilter> conj_filter = make_unique<CONJUNCTION_TYPE>();
112913
+ for (auto &expr : conjunction->children) {
112914
+ auto comp_expr = (BoundComparisonExpression *)expr.get();
112915
+ auto &const_expr =
112916
+ (comp_expr->left->type == ExpressionType::VALUE_CONSTANT) ? *comp_expr->left : *comp_expr->right;
112917
+ auto const_value = ExpressionExecutor::EvaluateScalar(const_expr);
112918
+ auto const_filter = make_unique<ConstantFilter>(comp_expr->type, const_value);
112919
+ conj_filter->child_filters.push_back(move(const_filter));
112920
+ }
112921
+ return move(conj_filter);
112922
+ }
112923
+
112870
112924
  private:
112871
112925
  vector<unique_ptr<Expression>> remaining_filters;
112872
112926
 
@@ -112875,6 +112929,26 @@ private:
112875
112929
  unordered_map<idx_t, vector<ExpressionValueInformation>> constant_values;
112876
112930
  unordered_map<idx_t, vector<Expression *>> equivalence_map;
112877
112931
  idx_t set_index = 0;
112932
+
112933
+ //! Structures used for OR Filters
112934
+
112935
+ struct ConjunctionsToPush {
112936
+ BoundConjunctionExpression *root_or;
112937
+
112938
+ // only preserve AND if there is a single column in the expression
112939
+ bool preserve_and = true;
112940
+
112941
+ // conjunction chain for this column
112942
+ vector<unique_ptr<BoundConjunctionExpression>> conjunctions;
112943
+ };
112944
+
112945
+ expression_map_t<vector<unique_ptr<ConjunctionsToPush>>> map_col_conjunctions;
112946
+ vector<BoundColumnRefExpression *> vec_colref_insertion_order;
112947
+
112948
+ BoundConjunctionExpression *cur_root_or;
112949
+ BoundConjunctionExpression *cur_conjunction;
112950
+
112951
+ BoundColumnRefExpression *cur_colref_to_push;
112878
112952
  };
112879
112953
 
112880
112954
  } // namespace duckdb
@@ -112896,6 +112970,7 @@ private:
112896
112970
 
112897
112971
 
112898
112972
 
112973
+
112899
112974
  namespace duckdb {
112900
112975
 
112901
112976
  using ExpressionValueInformation = FilterCombiner::ExpressionValueInformation;
@@ -112958,6 +113033,7 @@ FilterResult FilterCombiner::AddConstantComparison(vector<ExpressionValueInforma
112958
113033
  }
112959
113034
 
112960
113035
  FilterResult FilterCombiner::AddFilter(unique_ptr<Expression> expr) {
113036
+ LookUpConjunctions(expr.get());
112961
113037
  // try to push the filter into the combiner
112962
113038
  auto result = AddFilter(expr.get());
112963
113039
  if (result == FilterResult::UNSUPPORTED) {
@@ -113430,6 +113506,8 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
113430
113506
  }
113431
113507
  }
113432
113508
 
113509
+ GenerateORFilters(table_filters, column_ids);
113510
+
113433
113511
  return table_filters;
113434
113512
  }
113435
113513
 
@@ -113867,6 +113945,176 @@ ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left,
113867
113945
  }
113868
113946
  }
113869
113947
 
113948
+ void FilterCombiner::LookUpConjunctions(Expression *expr) {
113949
+ if (expr->GetExpressionType() == ExpressionType::CONJUNCTION_OR) {
113950
+ auto root_or_expr = (BoundConjunctionExpression *)expr;
113951
+ for (const auto &entry : map_col_conjunctions) {
113952
+ for (const auto &conjs_to_push : entry.second) {
113953
+ if (conjs_to_push->root_or->Equals(root_or_expr)) {
113954
+ return;
113955
+ }
113956
+ }
113957
+ }
113958
+
113959
+ cur_root_or = root_or_expr;
113960
+ cur_conjunction = root_or_expr;
113961
+ cur_colref_to_push = nullptr;
113962
+ if (!BFSLookUpConjunctions(cur_root_or)) {
113963
+ if (cur_colref_to_push) {
113964
+ auto entry = map_col_conjunctions.find(cur_colref_to_push);
113965
+ auto &vec_conjs_to_push = entry->second;
113966
+ if (vec_conjs_to_push.size() == 1) {
113967
+ map_col_conjunctions.erase(entry);
113968
+ return;
113969
+ }
113970
+ vec_conjs_to_push.pop_back();
113971
+ }
113972
+ }
113973
+ return;
113974
+ }
113975
+
113976
+ // Verify if the expression has a column already pushed down by other OR expression
113977
+ VerifyOrsToPush(*expr);
113978
+ }
113979
+
113980
+ bool FilterCombiner::BFSLookUpConjunctions(BoundConjunctionExpression *conjunction) {
113981
+ vector<BoundConjunctionExpression *> conjunctions_to_visit;
113982
+
113983
+ for (auto &child : conjunction->children) {
113984
+ switch (child->GetExpressionClass()) {
113985
+ case ExpressionClass::BOUND_CONJUNCTION: {
113986
+ auto child_conjunction = (BoundConjunctionExpression *)child.get();
113987
+ conjunctions_to_visit.emplace_back(child_conjunction);
113988
+ break;
113989
+ }
113990
+ case ExpressionClass::BOUND_COMPARISON: {
113991
+ if (!UpdateConjunctionFilter((BoundComparisonExpression *)child.get())) {
113992
+ return false;
113993
+ }
113994
+ break;
113995
+ }
113996
+ default: {
113997
+ return false;
113998
+ }
113999
+ }
114000
+ }
114001
+
114002
+ for (auto child_conjunction : conjunctions_to_visit) {
114003
+ cur_conjunction = child_conjunction;
114004
+ // traverse child conjuction
114005
+ if (!BFSLookUpConjunctions(child_conjunction)) {
114006
+ return false;
114007
+ }
114008
+ }
114009
+ return true;
114010
+ }
114011
+
114012
+ void FilterCombiner::VerifyOrsToPush(Expression &expr) {
114013
+ if (expr.type == ExpressionType::BOUND_COLUMN_REF) {
114014
+ auto colref = (BoundColumnRefExpression *)&expr;
114015
+ auto entry = map_col_conjunctions.find(colref);
114016
+ if (entry == map_col_conjunctions.end()) {
114017
+ return;
114018
+ }
114019
+ map_col_conjunctions.erase(entry);
114020
+ }
114021
+ ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { VerifyOrsToPush(child); });
114022
+ }
114023
+
114024
+ bool FilterCombiner::UpdateConjunctionFilter(BoundComparisonExpression *comparison_expr) {
114025
+ bool left_is_scalar = comparison_expr->left->IsFoldable();
114026
+ bool right_is_scalar = comparison_expr->right->IsFoldable();
114027
+
114028
+ Expression *non_scalar_expr;
114029
+ if (left_is_scalar || right_is_scalar) {
114030
+ // only support comparison with scalar
114031
+ non_scalar_expr = left_is_scalar ? comparison_expr->right.get() : comparison_expr->left.get();
114032
+
114033
+ if (non_scalar_expr->GetExpressionType() == ExpressionType::BOUND_COLUMN_REF) {
114034
+ return UpdateFilterByColumn((BoundColumnRefExpression *)non_scalar_expr, comparison_expr);
114035
+ }
114036
+ }
114037
+
114038
+ return false;
114039
+ }
114040
+
114041
+ bool FilterCombiner::UpdateFilterByColumn(BoundColumnRefExpression *column_ref,
114042
+ BoundComparisonExpression *comparison_expr) {
114043
+ if (cur_colref_to_push == nullptr) {
114044
+ cur_colref_to_push = column_ref;
114045
+
114046
+ auto or_conjunction = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_OR);
114047
+ or_conjunction->children.emplace_back(comparison_expr->Copy());
114048
+
114049
+ unique_ptr<ConjunctionsToPush> conjs_to_push = make_unique<ConjunctionsToPush>();
114050
+ conjs_to_push->conjunctions.emplace_back(move(or_conjunction));
114051
+ conjs_to_push->root_or = cur_root_or;
114052
+
114053
+ auto &&vec_col_conjs = map_col_conjunctions[column_ref];
114054
+ vec_col_conjs.emplace_back(move(conjs_to_push));
114055
+ vec_colref_insertion_order.emplace_back(column_ref);
114056
+ return true;
114057
+ }
114058
+
114059
+ auto entry = map_col_conjunctions.find(cur_colref_to_push);
114060
+ D_ASSERT(entry != map_col_conjunctions.end());
114061
+ auto &conjunctions_to_push = entry->second.back();
114062
+
114063
+ if (!cur_colref_to_push->Equals(column_ref)) {
114064
+ // check for multiple colunms in the same root OR node
114065
+ if (cur_root_or == cur_conjunction) {
114066
+ return false;
114067
+ }
114068
+ // found an AND using a different column, we should stop the look up
114069
+ if (cur_conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND) {
114070
+ return false;
114071
+ }
114072
+
114073
+ // found a different column, AND conditions cannot be preserved anymore
114074
+ conjunctions_to_push->preserve_and = false;
114075
+ return true;
114076
+ }
114077
+
114078
+ auto &last_conjunction = conjunctions_to_push->conjunctions.back();
114079
+ if (cur_conjunction->GetExpressionType() == last_conjunction->GetExpressionType()) {
114080
+ last_conjunction->children.emplace_back(comparison_expr->Copy());
114081
+ } else {
114082
+ auto new_conjunction = make_unique<BoundConjunctionExpression>(cur_conjunction->GetExpressionType());
114083
+ new_conjunction->children.emplace_back(comparison_expr->Copy());
114084
+ conjunctions_to_push->conjunctions.emplace_back(move(new_conjunction));
114085
+ }
114086
+ return true;
114087
+ }
114088
+
114089
+ void FilterCombiner::GenerateORFilters(TableFilterSet &table_filter, vector<idx_t> &column_ids) {
114090
+ for (const auto colref : vec_colref_insertion_order) {
114091
+ auto column_index = column_ids[colref->binding.column_index];
114092
+ if (column_index == COLUMN_IDENTIFIER_ROW_ID) {
114093
+ break;
114094
+ }
114095
+
114096
+ for (const auto &conjunctions_to_push : map_col_conjunctions[colref]) {
114097
+ // root OR filter to push into the TableFilter
114098
+ auto root_or_filter = make_unique<ConjunctionOrFilter>();
114099
+ // variable to hold the last conjuntion filter pointer
114100
+ // the next filter will be added into it, i.e., we create a chain of conjunction filters
114101
+ ConjunctionFilter *last_conj_filter = root_or_filter.get();
114102
+
114103
+ for (auto &conjunction : conjunctions_to_push->conjunctions) {
114104
+ if (conjunction->GetExpressionType() == ExpressionType::CONJUNCTION_AND &&
114105
+ conjunctions_to_push->preserve_and) {
114106
+ GenerateConjunctionFilter<ConjunctionAndFilter>(conjunction.get(), last_conj_filter);
114107
+ } else {
114108
+ GenerateConjunctionFilter<ConjunctionOrFilter>(conjunction.get(), last_conj_filter);
114109
+ }
114110
+ }
114111
+ table_filter.PushFilter(column_index, move(root_or_filter));
114112
+ }
114113
+ }
114114
+ map_col_conjunctions.clear();
114115
+ vec_colref_insertion_order.clear();
114116
+ }
114117
+
113870
114118
  } // namespace duckdb
113871
114119
  //===----------------------------------------------------------------------===//
113872
114120
  // DuckDB
@@ -119003,6 +119251,10 @@ FilterPropagateResult StatisticsPropagator::PropagateComparison(BaseStatistics &
119003
119251
  // only handle numerics for now
119004
119252
  switch (left.type.InternalType()) {
119005
119253
  case PhysicalType::BOOL:
119254
+ case PhysicalType::UINT8:
119255
+ case PhysicalType::UINT16:
119256
+ case PhysicalType::UINT32:
119257
+ case PhysicalType::UINT64:
119006
119258
  case PhysicalType::INT8:
119007
119259
  case PhysicalType::INT16:
119008
119260
  case PhysicalType::INT32:
@@ -119130,6 +119382,10 @@ namespace duckdb {
119130
119382
  unique_ptr<BaseStatistics> StatisticsPropagator::StatisticsFromValue(const Value &input) {
119131
119383
  switch (input.type().InternalType()) {
119132
119384
  case PhysicalType::BOOL:
119385
+ case PhysicalType::UINT8:
119386
+ case PhysicalType::UINT16:
119387
+ case PhysicalType::UINT32:
119388
+ case PhysicalType::UINT64:
119133
119389
  case PhysicalType::INT8:
119134
119390
  case PhysicalType::INT16:
119135
119391
  case PhysicalType::INT32:
@@ -138758,7 +139014,8 @@ unique_ptr<CreateStatement> Transformer::TransformCreateFunction(duckdb_libpgque
138758
139014
  if (macro_func->default_parameters.find(param->alias) != macro_func->default_parameters.end()) {
138759
139015
  throw ParserException("Duplicate default parameter: '%s'", param->alias);
138760
139016
  }
138761
- macro_func->default_parameters[param->alias] = move(param);
139017
+ auto alias = param->alias;
139018
+ macro_func->default_parameters[alias] = move(param);
138762
139019
  } else if (param->GetExpressionClass() == ExpressionClass::COLUMN_REF) {
138763
139020
  // positional parameters
138764
139021
  if (!macro_func->default_parameters.empty()) {
@@ -149818,7 +150075,7 @@ void ExpressionIterator::EnumerateQueryNodeChildren(BoundQueryNode &node,
149818
150075
 
149819
150076
  namespace duckdb {
149820
150077
 
149821
- ConjunctionOrFilter::ConjunctionOrFilter() : TableFilter(TableFilterType::CONJUNCTION_OR) {
150078
+ ConjunctionOrFilter::ConjunctionOrFilter() : ConjunctionFilter(TableFilterType::CONJUNCTION_OR) {
149822
150079
  }
149823
150080
 
149824
150081
  FilterPropagateResult ConjunctionOrFilter::CheckStatistics(BaseStatistics &stats) {
@@ -149847,7 +150104,7 @@ string ConjunctionOrFilter::ToString(const string &column_name) {
149847
150104
  }
149848
150105
 
149849
150106
  bool ConjunctionOrFilter::Equals(const TableFilter &other_p) const {
149850
- if (!TableFilter::Equals(other_p)) {
150107
+ if (!ConjunctionFilter::Equals(other_p)) {
149851
150108
  return false;
149852
150109
  }
149853
150110
  auto &other = (ConjunctionOrFilter &)other_p;
@@ -149862,11 +150119,11 @@ bool ConjunctionOrFilter::Equals(const TableFilter &other_p) const {
149862
150119
  return true;
149863
150120
  }
149864
150121
 
149865
- ConjunctionAndFilter::ConjunctionAndFilter() : TableFilter(TableFilterType::CONJUNCTION_AND) {
150122
+ ConjunctionAndFilter::ConjunctionAndFilter() : ConjunctionFilter(TableFilterType::CONJUNCTION_AND) {
149866
150123
  }
149867
150124
 
149868
150125
  FilterPropagateResult ConjunctionAndFilter::CheckStatistics(BaseStatistics &stats) {
149869
- // the OR filter is true if ALL of the children is true
150126
+ // the AND filter is true if ALL of the children is true
149870
150127
  D_ASSERT(!child_filters.empty());
149871
150128
  auto result = FilterPropagateResult::FILTER_ALWAYS_TRUE;
149872
150129
  for (auto &filter : child_filters) {
@@ -149892,7 +150149,7 @@ string ConjunctionAndFilter::ToString(const string &column_name) {
149892
150149
  }
149893
150150
 
149894
150151
  bool ConjunctionAndFilter::Equals(const TableFilter &other_p) const {
149895
- if (!TableFilter::Equals(other_p)) {
150152
+ if (!ConjunctionFilter::Equals(other_p)) {
149896
150153
  return false;
149897
150154
  }
149898
150155
  auto &other = (ConjunctionAndFilter &)other_p;
@@ -160109,6 +160366,14 @@ FilterPropagateResult NumericStatistics::CheckZonemap(ExpressionType comparison_
160109
160366
  } else {
160110
160367
  return FilterPropagateResult::FILTER_ALWAYS_FALSE;
160111
160368
  }
160369
+ case ExpressionType::COMPARE_NOTEQUAL:
160370
+ if (constant < min || constant > max) {
160371
+ return FilterPropagateResult::FILTER_ALWAYS_TRUE;
160372
+ } else if (min == max && min == constant) {
160373
+ // corner case of a cluster with one numeric equal to the target constant
160374
+ return FilterPropagateResult::FILTER_ALWAYS_FALSE;
160375
+ }
160376
+ return FilterPropagateResult::NO_PRUNING_POSSIBLE;
160112
160377
  case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
160113
160378
  // X >= C
160114
160379
  // this can be true only if max(X) >= C
@@ -160305,7 +160570,6 @@ unique_ptr<BaseStatistics> StringStatistics::Copy() {
160305
160570
  memcpy(stats->max, max, MAX_STRING_MINMAX_SIZE);
160306
160571
  stats->has_unicode = has_unicode;
160307
160572
  stats->max_string_length = max_string_length;
160308
- stats->max_string_length = max_string_length;
160309
160573
  if (validity_stats) {
160310
160574
  stats->validity_stats = validity_stats->Copy();
160311
160575
  }
@@ -160409,6 +160673,11 @@ FilterPropagateResult StringStatistics::CheckZonemap(ExpressionType comparison_t
160409
160673
  } else {
160410
160674
  return FilterPropagateResult::FILTER_ALWAYS_FALSE;
160411
160675
  }
160676
+ case ExpressionType::COMPARE_NOTEQUAL:
160677
+ if (min_comp < 0 || max_comp > 0) {
160678
+ return FilterPropagateResult::FILTER_ALWAYS_TRUE;
160679
+ }
160680
+ return FilterPropagateResult::NO_PRUNING_POSSIBLE;
160412
160681
  case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
160413
160682
  case ExpressionType::COMPARE_GREATERTHAN:
160414
160683
  if (max_comp <= 0) {
@@ -162532,6 +162801,16 @@ static void FilterSelectionSwitch(T *vec, T *predicate, SelectionVector &sel, id
162532
162801
  }
162533
162802
  break;
162534
162803
  }
162804
+ case ExpressionType::COMPARE_NOTEQUAL: {
162805
+ if (mask.AllValid()) {
162806
+ approved_tuple_count =
162807
+ TemplatedFilterSelection<T, NotEquals, false>(vec, predicate, sel, approved_tuple_count, mask, new_sel);
162808
+ } else {
162809
+ approved_tuple_count =
162810
+ TemplatedFilterSelection<T, NotEquals, true>(vec, predicate, sel, approved_tuple_count, mask, new_sel);
162811
+ }
162812
+ break;
162813
+ }
162535
162814
  case ExpressionType::COMPARE_LESSTHAN: {
162536
162815
  if (mask.AllValid()) {
162537
162816
  approved_tuple_count =
@@ -162601,15 +162880,44 @@ static idx_t TemplatedNullSelection(SelectionVector &sel, idx_t approved_tuple_c
162601
162880
  }
162602
162881
  }
162603
162882
 
162604
- void ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter,
162605
- idx_t &approved_tuple_count, ValidityMask &mask) {
162883
+ idx_t ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter,
162884
+ idx_t &approved_tuple_count, ValidityMask &mask) {
162606
162885
  switch (filter.filter_type) {
162886
+ case TableFilterType::CONJUNCTION_OR: {
162887
+ // similar to the CONJUNCTION_AND, but we need to take care of the SelectionVectors (OR all of them)
162888
+ idx_t count_total = 0;
162889
+ SelectionVector result_sel(approved_tuple_count);
162890
+ auto &conjunction_or = (ConjunctionOrFilter &)filter;
162891
+ for (auto &child_filter : conjunction_or.child_filters) {
162892
+ SelectionVector temp_sel;
162893
+ temp_sel.Initialize(sel);
162894
+ idx_t temp_tuple_count = approved_tuple_count;
162895
+ idx_t temp_count = FilterSelection(temp_sel, result, *child_filter, temp_tuple_count, mask);
162896
+ // tuples passed, move them into the actual result vector
162897
+ for (idx_t i = 0; i < temp_count; i++) {
162898
+ auto new_idx = temp_sel.get_index(i);
162899
+ bool is_new_idx = true;
162900
+ for (idx_t res_idx = 0; res_idx < count_total; res_idx++) {
162901
+ if (result_sel.get_index(res_idx) == new_idx) {
162902
+ is_new_idx = false;
162903
+ break;
162904
+ }
162905
+ }
162906
+ if (is_new_idx) {
162907
+ result_sel.set_index(count_total++, new_idx);
162908
+ }
162909
+ }
162910
+ }
162911
+ sel.Initialize(result_sel);
162912
+ approved_tuple_count = count_total;
162913
+ return approved_tuple_count;
162914
+ }
162607
162915
  case TableFilterType::CONJUNCTION_AND: {
162608
162916
  auto &conjunction_and = (ConjunctionAndFilter &)filter;
162609
162917
  for (auto &child_filter : conjunction_and.child_filters) {
162610
162918
  FilterSelection(sel, result, *child_filter, approved_tuple_count, mask);
162611
162919
  }
162612
- break;
162920
+ return approved_tuple_count;
162613
162921
  }
162614
162922
  case TableFilterType::CONSTANT_COMPARISON: {
162615
162923
  auto &constant_filter = (ConstantFilter &)filter;
@@ -162722,14 +163030,12 @@ void ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const
162722
163030
  default:
162723
163031
  throw InvalidTypeException(result.GetType(), "Invalid type for filter pushed down to table comparison");
162724
163032
  }
162725
- break;
163033
+ return approved_tuple_count;
162726
163034
  }
162727
163035
  case TableFilterType::IS_NULL:
162728
- TemplatedNullSelection<true>(sel, approved_tuple_count, mask);
162729
- break;
163036
+ return TemplatedNullSelection<true>(sel, approved_tuple_count, mask);
162730
163037
  case TableFilterType::IS_NOT_NULL:
162731
- TemplatedNullSelection<false>(sel, approved_tuple_count, mask);
162732
- break;
163038
+ return TemplatedNullSelection<false>(sel, approved_tuple_count, mask);
162733
163039
  default:
162734
163040
  throw InternalException("FIXME: unsupported type for filter selection");
162735
163041
  }
package/src/duckdb.hpp CHANGED
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
11
11
  #pragma once
12
12
  #define DUCKDB_AMALGAMATION 1
13
13
  #define DUCKDB_AMALGAMATION_EXTENDED 1
14
- #define DUCKDB_SOURCE_ID "7473f3eb0"
15
- #define DUCKDB_VERSION "0.3.2-dev782"
14
+ #define DUCKDB_SOURCE_ID "542f5d599"
15
+ #define DUCKDB_VERSION "0.3.2-dev838"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //
@@ -1097,6 +1097,11 @@ struct StructType {
1097
1097
  DUCKDB_API static idx_t GetChildCount(const LogicalType &type);
1098
1098
  };
1099
1099
 
1100
+ struct MapType {
1101
+ DUCKDB_API static const LogicalType &KeyType(const LogicalType &type);
1102
+ DUCKDB_API static const LogicalType &ValueType(const LogicalType &type);
1103
+ };
1104
+
1100
1105
 
1101
1106
  string LogicalTypeIdToString(LogicalTypeId type);
1102
1107
 
@@ -19200,8 +19205,8 @@ public:
19200
19205
  //! Fetch a value of the specific row id and append it to the result
19201
19206
  void FetchRow(ColumnFetchState &state, row_t row_id, Vector &result, idx_t result_idx);
19202
19207
 
19203
- static void FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter,
19204
- idx_t &approved_tuple_count, ValidityMask &mask);
19208
+ static idx_t FilterSelection(SelectionVector &sel, Vector &result, const TableFilter &filter,
19209
+ idx_t &approved_tuple_count, ValidityMask &mask);
19205
19210
 
19206
19211
  //! Skip a scan forward to the row_index specified in the scan state
19207
19212
  void Skip(ColumnScanState &state);
@@ -20102,27 +20107,40 @@ void NumericStatistics::Update<list_entry_t>(SegmentStatistics &stats, list_entr
20102
20107
 
20103
20108
 
20104
20109
  namespace duckdb {
20105
-
20106
- class ConjunctionOrFilter : public TableFilter {
20110
+ class ConjunctionFilter : public TableFilter {
20107
20111
  public:
20108
- ConjunctionOrFilter();
20112
+ ConjunctionFilter(TableFilterType filter_type_p) : TableFilter(filter_type_p) {
20113
+ }
20109
20114
 
20110
- //! The filters to OR together
20115
+ virtual ~ConjunctionFilter() {
20116
+ }
20117
+
20118
+ //! The filters of this conjunction
20111
20119
  vector<unique_ptr<TableFilter>> child_filters;
20112
20120
 
20121
+ public:
20122
+ virtual FilterPropagateResult CheckStatistics(BaseStatistics &stats) = 0;
20123
+ virtual string ToString(const string &column_name) = 0;
20124
+
20125
+ virtual bool Equals(const TableFilter &other) const {
20126
+ return TableFilter::Equals(other);
20127
+ }
20128
+ };
20129
+
20130
+ class ConjunctionOrFilter : public ConjunctionFilter {
20131
+ public:
20132
+ ConjunctionOrFilter();
20133
+
20113
20134
  public:
20114
20135
  FilterPropagateResult CheckStatistics(BaseStatistics &stats) override;
20115
20136
  string ToString(const string &column_name) override;
20116
20137
  bool Equals(const TableFilter &other) const override;
20117
20138
  };
20118
20139
 
20119
- class ConjunctionAndFilter : public TableFilter {
20140
+ class ConjunctionAndFilter : public ConjunctionFilter {
20120
20141
  public:
20121
20142
  ConjunctionAndFilter();
20122
20143
 
20123
- //! The filters to OR together
20124
- vector<unique_ptr<TableFilter>> child_filters;
20125
-
20126
20144
  public:
20127
20145
  FilterPropagateResult CheckStatistics(BaseStatistics &stats) override;
20128
20146
  string ToString(const string &column_name) override;