duckdb 0.8.2-dev3949.0 → 0.8.2-dev3989.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.
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # This is the default extension configuration for NodeJS builds. Basically it means that all these extensions are
6
6
  # "baked in" to the NodeJS binaries Note that the configuration here is only when building Node using the main
7
- # CMakeLists.txt file with the `BUILD_R` variable.
7
+ # CMakeLists.txt file with the `BUILD_NODE` variable.
8
8
  # TODO: unify this by making setup.py also use this configuration, making this the config for all Node builds
9
9
  duckdb_extension_load(json)
10
10
  duckdb_extension_load(icu)
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "0.8.2-dev3949.0",
5
+ "version": "0.8.2-dev3989.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -68,7 +68,7 @@ FileBuffer::MemoryRequirement FileBuffer::CalculateMemory(uint64_t user_size) {
68
68
  result.alloc_size = user_size;
69
69
  } else {
70
70
  result.header_size = Storage::BLOCK_HEADER_SIZE;
71
- result.alloc_size = AlignValue<uint32_t, Storage::SECTOR_SIZE>(result.header_size + user_size);
71
+ result.alloc_size = AlignValue<idx_t, Storage::SECTOR_SIZE>(result.header_size + user_size);
72
72
  }
73
73
  return result;
74
74
  }
@@ -98,6 +98,9 @@ struct SplitStringListOperation {
98
98
  child_start++;
99
99
  return;
100
100
  }
101
+ if (start_pos > pos) {
102
+ pos = start_pos;
103
+ }
101
104
  child_data[child_start] = StringVector::AddString(child, buf + start_pos, pos - start_pos);
102
105
  child_start++;
103
106
  }
@@ -109,6 +112,7 @@ static bool SplitStringListInternal(const string_t &input, OP &state) {
109
112
  idx_t len = input.GetSize();
110
113
  idx_t lvl = 1;
111
114
  idx_t pos = 0;
115
+ bool seen_value = false;
112
116
 
113
117
  SkipWhitespace(buf, pos, len);
114
118
  if (pos == len || buf[pos] != '[') {
@@ -132,9 +136,10 @@ static bool SplitStringListInternal(const string_t &input, OP &state) {
132
136
  while (StringUtil::CharacterIsSpace(buf[pos - trailing_whitespace - 1])) {
133
137
  trailing_whitespace++;
134
138
  }
135
- if (!(buf[pos] == ']' && start_pos == pos)) {
139
+ if (buf[pos] != ']' || start_pos != pos || seen_value) {
136
140
  state.HandleValue(buf, start_pos, pos - trailing_whitespace);
137
- } // else the list is empty
141
+ seen_value = true;
142
+ }
138
143
  if (buf[pos] == ']') {
139
144
  lvl--;
140
145
  break;
@@ -1,8 +1,8 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.8.2-dev3949"
2
+ #define DUCKDB_VERSION "0.8.2-dev3989"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "c21a9cb87c"
5
+ #define DUCKDB_SOURCE_ID "a7a88cb691"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
@@ -46,13 +46,16 @@ public:
46
46
  static void InstallExtension(DBConfig &config, FileSystem &fs, const string &extension, bool force_install,
47
47
  const string &respository = "");
48
48
  static void LoadExternalExtension(ClientContext &context, const string &extension);
49
- static void LoadExternalExtension(DatabaseInstance &db, FileSystem &fs, const string &extension);
49
+ static void LoadExternalExtension(DatabaseInstance &db, FileSystem &fs, const string &extension,
50
+ optional_ptr<const ClientConfig> client_config);
50
51
 
51
52
  //! Autoload an extension by name. Depending on the current settings, this will either load or install+load
52
53
  static void AutoLoadExtension(ClientContext &context, const string &extension_name);
53
54
 
54
55
  static string ExtensionDirectory(ClientContext &context);
55
56
  static string ExtensionDirectory(DBConfig &config, FileSystem &fs);
57
+ static string ExtensionUrlTemplate(optional_ptr<const ClientConfig> config, const string &repository);
58
+ static string ExtensionFinalizeUrlTemplate(const string &url, const string &name);
56
59
 
57
60
  static idx_t DefaultExtensionCount();
58
61
  static DefaultExtension GetDefaultExtension(idx_t index);
@@ -101,9 +104,10 @@ private:
101
104
  const string &repository);
102
105
  static const vector<string> PathComponents();
103
106
  static bool AllowAutoInstall(const string &extension);
104
- static ExtensionInitResult InitialLoad(DBConfig &config, FileSystem &fs, const string &extension);
107
+ static ExtensionInitResult InitialLoad(DBConfig &config, FileSystem &fs, const string &extension,
108
+ optional_ptr<const ClientConfig> client_config);
105
109
  static bool TryInitialLoad(DBConfig &config, FileSystem &fs, const string &extension, ExtensionInitResult &result,
106
- string &error);
110
+ string &error, optional_ptr<const ClientConfig> client_config);
107
111
  //! For tagged releases we use the tag, else we use the git commit hash
108
112
  static const string GetVersionDirectoryName();
109
113
  //! Version tags occur with and without 'v', tag in extension path is always with 'v'
@@ -234,7 +234,7 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf
234
234
  if (!config.file_system) {
235
235
  throw InternalException("No file system!?");
236
236
  }
237
- ExtensionHelper::LoadExternalExtension(*this, *config.file_system, config.options.database_type);
237
+ ExtensionHelper::LoadExternalExtension(*this, *config.file_system, config.options.database_type, nullptr);
238
238
  }
239
239
 
240
240
  if (!config.options.unrecognized_options.empty()) {
@@ -45,7 +45,7 @@ const vector<string> ExtensionHelper::PathComponents() {
45
45
 
46
46
  string ExtensionHelper::ExtensionDirectory(DBConfig &config, FileSystem &fs) {
47
47
  #ifdef WASM_LOADABLE_EXTENSIONS
48
- static_assertion(0, "ExtensionDirectory functionality is not supported in duckdb-wasm");
48
+ static_assert(0, "ExtensionDirectory functionality is not supported in duckdb-wasm");
49
49
  #endif
50
50
  string extension_directory;
51
51
  if (!config.options.extension_directory.empty()) { // create the extension directory if not present
@@ -157,6 +157,32 @@ void WriteExtensionFileToDisk(FileSystem &fs, const string &path, void *data, id
157
157
  target_file.reset();
158
158
  }
159
159
 
160
+ string ExtensionHelper::ExtensionUrlTemplate(optional_ptr<const ClientConfig> client_config, const string &repository) {
161
+ string default_endpoint = "http://extensions.duckdb.org";
162
+ string versioned_path = "/${REVISION}/${PLATFORM}/${NAME}.duckdb_extension.gz";
163
+ #ifdef WASM_LOADABLE_EXTENSIONS
164
+ versioned_path = "/duckdb-wasm" + versioned_path;
165
+ #endif
166
+ string custom_endpoint = client_config ? client_config->custom_extension_repo : string();
167
+ string endpoint;
168
+ if (!repository.empty()) {
169
+ endpoint = repository;
170
+ } else if (!custom_endpoint.empty()) {
171
+ endpoint = custom_endpoint;
172
+ } else {
173
+ endpoint = default_endpoint;
174
+ }
175
+ string url_template = endpoint + versioned_path;
176
+ return url_template;
177
+ }
178
+
179
+ string ExtensionHelper::ExtensionFinalizeUrlTemplate(const string &url_template, const string &extension_name) {
180
+ auto url = StringUtil::Replace(url_template, "${REVISION}", GetVersionDirectoryName());
181
+ url = StringUtil::Replace(url, "${PLATFORM}", DuckDB::Platform());
182
+ url = StringUtil::Replace(url, "${NAME}", extension_name);
183
+ return url;
184
+ }
185
+
160
186
  void ExtensionHelper::InstallExtensionInternal(DBConfig &config, ClientConfig *client_config, FileSystem &fs,
161
187
  const string &local_path, const string &extension, bool force_install,
162
188
  const string &repository) {
@@ -197,27 +223,14 @@ void ExtensionHelper::InstallExtensionInternal(DBConfig &config, ClientConfig *c
197
223
  throw BinderException("Remote extension installation is disabled through configuration");
198
224
  #else
199
225
 
200
- string versioned_path = "/${REVISION}/${PLATFORM}/${NAME}.duckdb_extension.gz";
201
- string custom_endpoint = client_config ? client_config->custom_extension_repo : string();
202
- string endpoint;
203
- if (!repository.empty()) {
204
- endpoint = repository;
205
- } else if (!custom_endpoint.empty()) {
206
- endpoint = custom_endpoint;
207
- } else {
208
- endpoint = "http://extensions.duckdb.org";
209
- }
210
-
211
- string url_template = endpoint + versioned_path;
226
+ string url_template = ExtensionUrlTemplate(client_config, repository);
212
227
 
213
228
  if (is_http_url) {
214
229
  url_template = extension;
215
230
  extension_name = "";
216
231
  }
217
232
 
218
- auto url = StringUtil::Replace(url_template, "${REVISION}", GetVersionDirectoryName());
219
- url = StringUtil::Replace(url, "${PLATFORM}", DuckDB::Platform());
220
- url = StringUtil::Replace(url, "${NAME}", extension_name);
233
+ string url = ExtensionFinalizeUrlTemplate(url_template, extension_name);
221
234
 
222
235
  string no_http = StringUtil::Replace(url, "http://", "");
223
236
 
@@ -227,7 +240,7 @@ void ExtensionHelper::InstallExtensionInternal(DBConfig &config, ClientConfig *c
227
240
  }
228
241
 
229
242
  // Special case to install extension from a local file, useful for testing
230
- if (!StringUtil::Contains(endpoint, "http://")) {
243
+ if (!StringUtil::Contains(url_template, "http://")) {
231
244
  string file = fs.ConvertSeparators(url);
232
245
  if (!fs.FileExists(file)) {
233
246
  // check for non-gzipped variant
@@ -58,7 +58,8 @@ static void ComputeSHA256FileSegment(FileHandle *handle, const idx_t start, cons
58
58
  #endif
59
59
 
60
60
  bool ExtensionHelper::TryInitialLoad(DBConfig &config, FileSystem &fs, const string &extension,
61
- ExtensionInitResult &result, string &error) {
61
+ ExtensionInitResult &result, string &error,
62
+ optional_ptr<const ClientConfig> client_config) {
62
63
  #ifdef DUCKDB_DISABLE_EXTENSION_LOAD
63
64
  throw PermissionException("Loading external extensions is disabled through a compile time flag");
64
65
  #else
@@ -69,6 +70,30 @@ bool ExtensionHelper::TryInitialLoad(DBConfig &config, FileSystem &fs, const str
69
70
 
70
71
  // shorthand case
71
72
  if (!ExtensionHelper::IsFullPath(extension)) {
73
+ #ifdef WASM_LOADABLE_EXTENSIONS
74
+ string url_template = ExtensionUrlTemplate(client_config, "");
75
+ string url = ExtensionFinalizeUrlTemplate(url_template, extension_name);
76
+
77
+ char *str = (char *)EM_ASM_PTR(
78
+ {
79
+ var jsString = ((typeof runtime == = 'object') && runtime &&
80
+ (typeof runtime.whereToLoad == = 'function') && runtime.whereToLoad)
81
+ ? runtime.whereToLoad(UTF8ToString($0))
82
+ : (UTF8ToString($1));
83
+ var lengthBytes = lengthBytesUTF8(jsString) + 1;
84
+ // 'jsString.length' would return the length of the string as UTF-16
85
+ // units, but Emscripten C strings operate as UTF-8.
86
+ var stringOnWasmHeap = _malloc(lengthBytes);
87
+ stringToUTF8(jsString, stringOnWasmHeap, lengthBytes);
88
+ return stringOnWasmHeap;
89
+ },
90
+ filename.c_str(), url.c_str());
91
+ std::string address(str);
92
+ free(str);
93
+
94
+ filename = address;
95
+ #else
96
+
72
97
  string local_path =
73
98
  !config.options.extension_directory.empty() ? config.options.extension_directory : fs.GetHomeDirectory();
74
99
 
@@ -82,6 +107,7 @@ bool ExtensionHelper::TryInitialLoad(DBConfig &config, FileSystem &fs, const str
82
107
  }
83
108
  string extension_name = ApplyExtensionAlias(extension);
84
109
  filename = fs.JoinPath(local_path, extension_name + ".duckdb_extension");
110
+ #endif
85
111
  }
86
112
  if (!fs.FileExists(filename)) {
87
113
  string message;
@@ -216,17 +242,18 @@ bool ExtensionHelper::TryInitialLoad(DBConfig &config, FileSystem &fs, const str
216
242
  #endif
217
243
  }
218
244
 
219
- ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileSystem &fs, const string &extension) {
245
+ ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileSystem &fs, const string &extension,
246
+ optional_ptr<const ClientConfig> client_config) {
220
247
  string error;
221
248
  ExtensionInitResult result;
222
- if (!TryInitialLoad(config, fs, extension, result, error)) {
249
+ if (!TryInitialLoad(config, fs, extension, result, error, client_config)) {
223
250
  if (!ExtensionHelper::AllowAutoInstall(extension)) {
224
251
  throw IOException(error);
225
252
  }
226
253
  // the extension load failed - try installing the extension
227
254
  ExtensionHelper::InstallExtension(config, fs, extension, false);
228
255
  // try loading again
229
- if (!TryInitialLoad(config, fs, extension, result, error)) {
256
+ if (!TryInitialLoad(config, fs, extension, result, error, client_config)) {
230
257
  throw IOException(error);
231
258
  }
232
259
  }
@@ -254,14 +281,15 @@ string ExtensionHelper::GetExtensionName(const string &original_name) {
254
281
  return ExtensionHelper::ApplyExtensionAlias(splits.front());
255
282
  }
256
283
 
257
- void ExtensionHelper::LoadExternalExtension(DatabaseInstance &db, FileSystem &fs, const string &extension) {
284
+ void ExtensionHelper::LoadExternalExtension(DatabaseInstance &db, FileSystem &fs, const string &extension,
285
+ optional_ptr<const ClientConfig> client_config) {
258
286
  if (db.ExtensionIsLoaded(extension)) {
259
287
  return;
260
288
  }
261
289
  #ifdef DUCKDB_DISABLE_EXTENSION_LOAD
262
290
  throw PermissionException("Loading external extensions is disabled through a compile time flag");
263
291
  #else
264
- auto res = InitialLoad(DBConfig::GetConfig(db), fs, extension);
292
+ auto res = InitialLoad(DBConfig::GetConfig(db), fs, extension, client_config);
265
293
  auto init_fun_name = res.basename + "_init";
266
294
 
267
295
  ext_init_fun_t init_fun;
@@ -279,7 +307,8 @@ void ExtensionHelper::LoadExternalExtension(DatabaseInstance &db, FileSystem &fs
279
307
  }
280
308
 
281
309
  void ExtensionHelper::LoadExternalExtension(ClientContext &context, const string &extension) {
282
- LoadExternalExtension(DatabaseInstance::GetDatabase(context), FileSystem::GetFileSystem(context), extension);
310
+ LoadExternalExtension(DatabaseInstance::GetDatabase(context), FileSystem::GetFileSystem(context), extension,
311
+ &ClientConfig::GetConfig(context));
283
312
  }
284
313
 
285
314
  string ExtensionHelper::ExtractExtensionPrefixFromPath(const string &path) {