duckdb 0.3.2-dev277.0 → 0.3.2-dev292.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-dev277.0",
4
+ "version": "0.3.2-dev292.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -11086,42 +11086,53 @@ string LogicalOperatorToString(LogicalOperatorType type) {
11086
11086
 
11087
11087
 
11088
11088
 
11089
+
11089
11090
  namespace duckdb {
11090
11091
 
11092
+ struct DefaultOptimizerType {
11093
+ const char *name;
11094
+ OptimizerType type;
11095
+ };
11096
+
11097
+ static DefaultOptimizerType internal_optimizer_types[] = {
11098
+ {"expression_rewriter", OptimizerType::EXPRESSION_REWRITER},
11099
+ {"filter_pullup", OptimizerType::FILTER_PULLUP},
11100
+ {"filter_pushdown", OptimizerType::FILTER_PUSHDOWN},
11101
+ {"regex_range", OptimizerType::REGEX_RANGE},
11102
+ {"in_clause", OptimizerType::IN_CLAUSE},
11103
+ {"join_order", OptimizerType::JOIN_ORDER},
11104
+ {"deliminator", OptimizerType::DELIMINATOR},
11105
+ {"unused_columns", OptimizerType::UNUSED_COLUMNS},
11106
+ {"statistics_propagation", OptimizerType::STATISTICS_PROPAGATION},
11107
+ {"common_subexpressions", OptimizerType::COMMON_SUBEXPRESSIONS},
11108
+ {"common_aggregate", OptimizerType::COMMON_AGGREGATE},
11109
+ {"column_lifetime", OptimizerType::COLUMN_LIFETIME},
11110
+ {"top_n", OptimizerType::TOP_N},
11111
+ {"reorder_filter", OptimizerType::REORDER_FILTER},
11112
+ {nullptr, OptimizerType::INVALID}};
11113
+
11091
11114
  string OptimizerTypeToString(OptimizerType type) {
11092
- switch (type) {
11093
- case OptimizerType::EXPRESSION_REWRITER:
11094
- return "expression_rewriter";
11095
- case OptimizerType::FILTER_PULLUP:
11096
- return "filter_pullup";
11097
- case OptimizerType::FILTER_PUSHDOWN:
11098
- return "filter_pushdown";
11099
- case OptimizerType::REGEX_RANGE:
11100
- return "regex_range";
11101
- case OptimizerType::IN_CLAUSE:
11102
- return "in_clause";
11103
- case OptimizerType::JOIN_ORDER:
11104
- return "join_order";
11105
- case OptimizerType::DELIMINATOR:
11106
- return "deliminator";
11107
- case OptimizerType::UNUSED_COLUMNS:
11108
- return "unused_columns";
11109
- case OptimizerType::STATISTICS_PROPAGATION:
11110
- return "statistics_propagation";
11111
- case OptimizerType::COMMON_SUBEXPRESSIONS:
11112
- return "common_subexpressions";
11113
- case OptimizerType::COMMON_AGGREGATE:
11114
- return "common_aggregate";
11115
- case OptimizerType::COLUMN_LIFETIME:
11116
- return "column_lifetime";
11117
- case OptimizerType::TOP_N:
11118
- return "top_n";
11119
- case OptimizerType::REORDER_FILTER:
11120
- return "reorder_filter";
11121
- case OptimizerType::INVALID: // LCOV_EXCL_START
11122
- break;
11115
+ for (idx_t i = 0; internal_optimizer_types[i].name; i++) {
11116
+ if (internal_optimizer_types[i].type == type) {
11117
+ return internal_optimizer_types[i].name;
11118
+ }
11123
11119
  }
11124
- return "INVALID"; // LCOV_EXCL_STOP
11120
+ throw InternalException("Invalid optimizer type");
11121
+ }
11122
+
11123
+ OptimizerType OptimizerTypeFromString(const string &str) {
11124
+ for (idx_t i = 0; internal_optimizer_types[i].name; i++) {
11125
+ if (internal_optimizer_types[i].name == str) {
11126
+ return internal_optimizer_types[i].type;
11127
+ }
11128
+ }
11129
+ // optimizer not found, construct candidate list
11130
+ vector<string> optimizer_names;
11131
+ for (idx_t i = 0; internal_optimizer_types[i].name; i++) {
11132
+ optimizer_names.emplace_back(internal_optimizer_types[i].name);
11133
+ }
11134
+ throw ParserException("Optimizer type \"%s\" not recognized\n%s", str,
11135
+ StringUtil::CandidatesErrorMessage(optimizer_names, str, "Candidate optimizers"));
11125
11136
  }
11126
11137
 
11127
11138
  } // namespace duckdb
@@ -21229,21 +21240,37 @@ idx_t LocalFileSystem::GetFilePointer(FileHandle &handle) {
21229
21240
  return ((WindowsFileHandle &)handle).position;
21230
21241
  }
21231
21242
 
21232
- void LocalFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) {
21233
- HANDLE hFile = ((WindowsFileHandle &)handle).fd;
21234
- DWORD bytes_read;
21243
+ static DWORD FSInternalRead(FileHandle &handle, HANDLE hFile, void *buffer, int64_t nr_bytes, idx_t location) {
21244
+ DWORD bytes_read = 0;
21245
+ bool overlapped_read = false;
21235
21246
  OVERLAPPED ov = {};
21236
21247
  ov.Internal = 0;
21237
21248
  ov.InternalHigh = 0;
21238
21249
  ov.Offset = location & 0xFFFFFFFF;
21239
21250
  ov.OffsetHigh = location >> 32;
21240
21251
  ov.hEvent = 0;
21241
- ReadFile(hFile, buffer, (DWORD)nr_bytes, NULL, &ov);
21242
- auto rc = GetOverlappedResult(hFile, &ov, &bytes_read, true);
21252
+ auto rc = ReadFile(hFile, buffer, (DWORD)nr_bytes, &bytes_read, &ov);
21243
21253
  if (rc == 0) {
21244
- auto error = GetLastErrorAsString();
21245
- throw IOException("Could not read file \"%s\": %s", handle.path, error);
21254
+ if (GetLastError() != ERROR_IO_PENDING) {
21255
+ auto error = GetLastErrorAsString();
21256
+ throw IOException("Could not read file \"%s\" (error in ReadFile): %s", handle.path, error);
21257
+ } else {
21258
+ overlapped_read = true;
21259
+ }
21260
+ }
21261
+ if (overlapped_read) {
21262
+ rc = GetOverlappedResult(hFile, &ov, &bytes_read, true);
21263
+ if (rc == 0) {
21264
+ auto error = GetLastErrorAsString();
21265
+ throw IOException("Could not read file \"%s\" (error in GetOverlappedResult): %s", handle.path, error);
21266
+ }
21246
21267
  }
21268
+ return bytes_read;
21269
+ }
21270
+
21271
+ void LocalFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) {
21272
+ HANDLE hFile = ((WindowsFileHandle &)handle).fd;
21273
+ auto bytes_read = FSInternalRead(handle, hFile, buffer, nr_bytes, location);
21247
21274
  if (bytes_read != nr_bytes) {
21248
21275
  throw IOException("Could not read all bytes from file \"%s\": wanted=%lld read=%lld", handle.path, nr_bytes,
21249
21276
  bytes_read);
@@ -21252,40 +21279,44 @@ void LocalFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes, i
21252
21279
 
21253
21280
  int64_t LocalFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes) {
21254
21281
  HANDLE hFile = ((WindowsFileHandle &)handle).fd;
21255
- DWORD bytes_read;
21256
21282
  auto &pos = ((WindowsFileHandle &)handle).position;
21257
- OVERLAPPED ov = {};
21258
- ov.Internal = 0;
21259
- ov.InternalHigh = 0;
21260
- ov.Offset = pos & 0xFFFFFFFF;
21261
- ov.OffsetHigh = pos >> 32;
21262
- ov.hEvent = 0;
21263
21283
  auto n = std::min<idx_t>(std::max<idx_t>(GetFileSize(handle), pos) - pos, nr_bytes);
21264
- ReadFile(hFile, buffer, (DWORD)n, NULL, &ov);
21265
- auto rc = GetOverlappedResult(hFile, &ov, &bytes_read, true);
21266
- if (rc == 0) {
21267
- auto error = GetLastErrorAsString();
21268
- throw IOException("Could not read file \"%s\": %s", handle.path, error);
21269
- }
21284
+ auto bytes_read = FSInternalRead(handle, hFile, buffer, n, pos);
21270
21285
  pos += bytes_read;
21271
21286
  return bytes_read;
21272
21287
  }
21273
21288
 
21274
- void LocalFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) {
21275
- HANDLE hFile = ((WindowsFileHandle &)handle).fd;
21276
- DWORD bytes_written;
21289
+ static DWORD FSInternalWrite(FileHandle &handle, HANDLE hFile, void *buffer, int64_t nr_bytes, idx_t location) {
21290
+ DWORD bytes_written = 0;
21291
+ bool overlapped_write = false;
21277
21292
  OVERLAPPED ov = {};
21278
21293
  ov.Internal = 0;
21279
21294
  ov.InternalHigh = 0;
21280
21295
  ov.Offset = location & 0xFFFFFFFF;
21281
21296
  ov.OffsetHigh = location >> 32;
21282
21297
  ov.hEvent = 0;
21283
- WriteFile(hFile, buffer, (DWORD)nr_bytes, NULL, &ov);
21284
- auto rc = GetOverlappedResult(hFile, &ov, &bytes_written, true);
21298
+ auto rc = WriteFile(hFile, buffer, (DWORD)nr_bytes, &bytes_written, &ov);
21285
21299
  if (rc == 0) {
21286
- auto error = GetLastErrorAsString();
21287
- throw IOException("Could not write file \"%s\": %s", handle.path, error);
21300
+ if (GetLastError() != ERROR_IO_PENDING) {
21301
+ auto error = GetLastErrorAsString();
21302
+ throw IOException("Could not write file \"%s\" (error in WriteFile): %s", handle.path, error);
21303
+ } else {
21304
+ overlapped_write = true;
21305
+ }
21306
+ }
21307
+ if (overlapped_write) {
21308
+ rc = GetOverlappedResult(hFile, &ov, &bytes_written, true);
21309
+ if (rc == 0) {
21310
+ auto error = GetLastErrorAsString();
21311
+ throw IOException("Could not write file \"%s\" (error in GetOverlappedResult): %s", handle.path, error);
21312
+ }
21288
21313
  }
21314
+ return bytes_written;
21315
+ }
21316
+
21317
+ void LocalFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) {
21318
+ HANDLE hFile = ((WindowsFileHandle &)handle).fd;
21319
+ auto bytes_written = FSInternalWrite(handle, hFile, buffer, nr_bytes, location);
21289
21320
  if (bytes_written != nr_bytes) {
21290
21321
  throw IOException("Could not write all bytes from file \"%s\": wanted=%lld wrote=%lld", handle.path, nr_bytes,
21291
21322
  bytes_written);
@@ -21294,20 +21325,8 @@ void LocalFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes,
21294
21325
 
21295
21326
  int64_t LocalFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes) {
21296
21327
  HANDLE hFile = ((WindowsFileHandle &)handle).fd;
21297
- DWORD bytes_written;
21298
21328
  auto &pos = ((WindowsFileHandle &)handle).position;
21299
- OVERLAPPED ov = {};
21300
- ov.Internal = 0;
21301
- ov.InternalHigh = 0;
21302
- ov.Offset = pos & 0xFFFFFFFF;
21303
- ov.OffsetHigh = pos >> 32;
21304
- ov.hEvent = 0;
21305
- WriteFile(hFile, buffer, (DWORD)nr_bytes, NULL, &ov);
21306
- auto rc = GetOverlappedResult(hFile, &ov, &bytes_written, true);
21307
- if (rc == 0) {
21308
- auto error = GetLastErrorAsString();
21309
- throw IOException("Could not write file \"%s\": %s", handle.path, error);
21310
- }
21329
+ auto bytes_written = FSInternalWrite(handle, hFile, buffer, nr_bytes, pos);
21311
21330
  pos += bytes_written;
21312
21331
  return bytes_written;
21313
21332
  }
@@ -32735,6 +32754,12 @@ string StringUtil::CandidatesMessage(const vector<string> &candidates, const str
32735
32754
  return result_str;
32736
32755
  }
32737
32756
 
32757
+ string StringUtil::CandidatesErrorMessage(const vector<string> &strings, const string &target,
32758
+ const string &message_prefix, idx_t n) {
32759
+ auto closest_strings = StringUtil::TopNLevenshtein(strings, target, n);
32760
+ return StringUtil::CandidatesMessage(closest_strings, message_prefix);
32761
+ }
32762
+
32738
32763
  } // namespace duckdb
32739
32764
  //===----------------------------------------------------------------------===//
32740
32765
  // DuckDB
@@ -57789,9 +57814,9 @@ void PhysicalSet::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSou
57789
57814
  for (auto &entry : config.extension_parameters) {
57790
57815
  potential_names.push_back(entry.first);
57791
57816
  }
57792
- auto closest_settings = StringUtil::TopNLevenshtein(potential_names, name);
57817
+
57793
57818
  throw CatalogException("unrecognized configuration parameter \"%s\"\n%s", name,
57794
- StringUtil::CandidatesMessage(closest_settings, "Did you mean"));
57819
+ StringUtil::CandidatesErrorMessage(potential_names, name, "Did you mean"));
57795
57820
  }
57796
57821
  //! it is!
57797
57822
  auto &extension_option = entry->second;
@@ -103314,6 +103339,14 @@ struct DefaultNullOrderSetting {
103314
103339
  static Value GetSetting(ClientContext &context);
103315
103340
  };
103316
103341
 
103342
+ struct DisabledOptimizersSetting {
103343
+ static constexpr const char *Name = "disabled_optimizers";
103344
+ static constexpr const char *Description = "DEBUG SETTING: disable a specific set of optimizers (comma separated)";
103345
+ static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR;
103346
+ static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &parameter);
103347
+ static Value GetSetting(ClientContext &context);
103348
+ };
103349
+
103317
103350
  struct EnableExternalAccessSetting {
103318
103351
  static constexpr const char *Name = "enable_external_access";
103319
103352
  static constexpr const char *Description =
@@ -103490,6 +103523,7 @@ static ConfigurationOption internal_options[] = {DUCKDB_GLOBAL(AccessModeSetting
103490
103523
  DUCKDB_GLOBAL_LOCAL(DefaultCollationSetting),
103491
103524
  DUCKDB_GLOBAL(DefaultOrderSetting),
103492
103525
  DUCKDB_GLOBAL(DefaultNullOrderSetting),
103526
+ DUCKDB_GLOBAL(DisabledOptimizersSetting),
103493
103527
  DUCKDB_GLOBAL(EnableExternalAccessSetting),
103494
103528
  DUCKDB_GLOBAL(EnableObjectCacheSetting),
103495
103529
  DUCKDB_LOCAL(EnableProfilingSetting),
@@ -115947,6 +115981,35 @@ Value DefaultNullOrderSetting::GetSetting(ClientContext &context) {
115947
115981
  }
115948
115982
  }
115949
115983
 
115984
+ //===--------------------------------------------------------------------===//
115985
+ // Disabled Optimizer
115986
+ //===--------------------------------------------------------------------===//
115987
+ void DisabledOptimizersSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) {
115988
+ auto list = StringUtil::Split(input.ToString(), ",");
115989
+ set<OptimizerType> disabled_optimizers;
115990
+ for (auto &entry : list) {
115991
+ auto param = StringUtil::Lower(entry);
115992
+ StringUtil::Trim(param);
115993
+ if (param.empty()) {
115994
+ continue;
115995
+ }
115996
+ disabled_optimizers.insert(OptimizerTypeFromString(param));
115997
+ }
115998
+ config.disabled_optimizers = move(disabled_optimizers);
115999
+ }
116000
+
116001
+ Value DisabledOptimizersSetting::GetSetting(ClientContext &context) {
116002
+ auto &config = DBConfig::GetConfig(context);
116003
+ string result;
116004
+ for (auto &optimizer : config.disabled_optimizers) {
116005
+ if (!result.empty()) {
116006
+ result += ",";
116007
+ }
116008
+ result += OptimizerTypeToString(optimizer);
116009
+ }
116010
+ return Value(result);
116011
+ }
116012
+
115950
116013
  //===--------------------------------------------------------------------===//
115951
116014
  // Enable External Access
115952
116015
  //===--------------------------------------------------------------------===//
@@ -116715,6 +116778,9 @@ void CommonSubExpressionOptimizer::CountExpressions(Expression &expr, CSEReplace
116715
116778
  case ExpressionClass::BOUND_COLUMN_REF:
116716
116779
  case ExpressionClass::BOUND_CONSTANT:
116717
116780
  case ExpressionClass::BOUND_PARAMETER:
116781
+ // skip conjunctions and case, since short-circuiting might be incorrectly disabled otherwise
116782
+ case ExpressionClass::BOUND_CONJUNCTION:
116783
+ case ExpressionClass::BOUND_CASE:
116718
116784
  return;
116719
116785
  default:
116720
116786
  break;
@@ -116754,7 +116820,9 @@ void CommonSubExpressionOptimizer::PerformCSEReplacement(unique_ptr<Expression>
116754
116820
  return;
116755
116821
  }
116756
116822
  // check if this child is eligible for CSE elimination
116757
- if (state.expression_count.find(&expr) != state.expression_count.end()) {
116823
+ bool can_cse = expr.expression_class != ExpressionClass::BOUND_CONJUNCTION &&
116824
+ expr.expression_class != ExpressionClass::BOUND_CASE;
116825
+ if (can_cse && state.expression_count.find(&expr) != state.expression_count.end()) {
116758
116826
  auto &node = state.expression_count[&expr];
116759
116827
  if (node.count > 1) {
116760
116828
  // this expression occurs more than once! push it into the projection
@@ -123045,7 +123113,7 @@ unique_ptr<Expression> InClauseSimplificationRule::Apply(LogicalOperator &op, ve
123045
123113
  }
123046
123114
  //! Here we check if we can apply the expression on the constant side
123047
123115
  auto target_type = cast_expression->source_type();
123048
- if (!BoundCastExpression::CastIsInvertible(target_type, cast_expression->return_type)) {
123116
+ if (!BoundCastExpression::CastIsInvertible(cast_expression->return_type, target_type)) {
123049
123117
  return nullptr;
123050
123118
  }
123051
123119
  vector<unique_ptr<BoundConstantExpression>> cast_list;
package/src/duckdb.hpp CHANGED
@@ -10,8 +10,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
10
10
 
11
11
  #pragma once
12
12
  #define DUCKDB_AMALGAMATION 1
13
- #define DUCKDB_SOURCE_ID "b10ef8b11"
14
- #define DUCKDB_VERSION "0.3.2-dev277"
13
+ #define DUCKDB_SOURCE_ID "43a2bb05d"
14
+ #define DUCKDB_VERSION "0.3.2-dev292"
15
15
  //===----------------------------------------------------------------------===//
16
16
  // DuckDB
17
17
  //
@@ -9863,7 +9863,13 @@ public:
9863
9863
  idx_t threshold = 5);
9864
9864
  DUCKDB_API static string CandidatesMessage(const vector<string> &candidates,
9865
9865
  const string &candidate = "Candidate bindings");
9866
+
9867
+ //! Generate an error message in the form of "{message_prefix}: nearest_string, nearest_string2, ...
9868
+ //! Equivalent to calling TopNLevenshtein followed by CandidatesMessage
9869
+ DUCKDB_API static string CandidatesErrorMessage(const vector<string> &strings, const string &target,
9870
+ const string &message_prefix, idx_t n = 5);
9866
9871
  };
9872
+
9867
9873
  } // namespace duckdb
9868
9874
 
9869
9875
 
@@ -9976,6 +9982,7 @@ enum class OptimizerType : uint32_t {
9976
9982
  };
9977
9983
 
9978
9984
  string OptimizerTypeToString(OptimizerType type);
9985
+ OptimizerType OptimizerTypeFromString(const string &str);
9979
9986
 
9980
9987
  } // namespace duckdb
9981
9988