Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/duckdb-wasm/src/bindings/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ export enum FileFlags {
FILE_FLAGS_FILE_CREATE_NEW = 1 << 4,
//! Open file in append mode
FILE_FLAGS_APPEND = 1 << 5,
FILE_FLAGS_PRIVATE = 1 << 6,
FILE_FLAGS_NULL_IF_NOT_EXISTS = 1 << 7,
FILE_FLAGS_PARALLEL_ACCESS = 1 << 8,
FILE_FLAGS_EXCLUSIVE_CREATE = 1 << 9,
FILE_FLAGS_NULL_IF_EXISTS = 1 << 10
}

/** Configuration for the AWS S3 Filesystem */
Expand Down
5 changes: 5 additions & 0 deletions packages/duckdb-wasm/src/bindings/runtime_browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,11 @@ export const BROWSER_RUNTIME: DuckDBRuntime & {
return result;
}

// Depending on file flags, return nullptr
if (flags & FileFlags.FILE_FLAGS_NULL_IF_NOT_EXISTS) {
return 0;
}

// Fall back to empty buffered file in the browser
console.warn(`Buffering missing file: ${file.fileName}`);
const result = mod._malloc(2 * 8);
Expand Down
5 changes: 5 additions & 0 deletions packages/duckdb-wasm/src/bindings/runtime_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ export const NODE_RUNTIME: DuckDBRuntime & {
case DuckDBDataProtocol.NODE_FS: {
let fd = NODE_RUNTIME._files?.get(file.dataUrl!);
if (fd === null || fd === undefined) {
// Depending on file flags, return nullptr
if (flags & FileFlags.FILE_FLAGS_NULL_IF_NOT_EXISTS) {
return 0;
}

fd = fs.openSync(
file.dataUrl!,
fs.constants.O_CREAT | fs.constants.O_RDWR,
Expand Down
17 changes: 10 additions & 7 deletions patches/duckdb/fix_load_database.patch
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
diff --git a/src/storage/storage_manager.cpp b/src/storage/storage_manager.cpp
index cb6c654e5f..a6b2af3b85 100644
index 45d42174f1..10b3ce47b1 100644
--- a/src/storage/storage_manager.cpp
+++ b/src/storage/storage_manager.cpp
@@ -160,9 +160,12 @@ void SingleFileStorageManager::LoadDatabase(StorageOptions storage_options) {
@@ -162,9 +162,15 @@ void SingleFileStorageManager::LoadDatabase(StorageOptions storage_options) {
row_group_size, STANDARD_VECTOR_SIZE);
}
}
- // Check if the database file already exists.
- // Note: a file can also exist if there was a ROLLBACK on a previous transaction creating that file.
- if (!read_only && !fs.FileExists(path)) {
+ auto db_file_handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_READ | FileFlags::FILE_FLAGS_NULL_IF_NOT_EXISTS);
+ bool is_empty_file = db_file_handle->GetFileSize() == 0;
+ db_file_handle.reset();
+ bool is_empty_file = true;
+ auto db_file_handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_READ | FileFlags::FILE_FLAGS_NULL_IF_NOT_EXISTS);
+ if (db_file_handle && db_file_handle->GetFileSize() != 0) {
+ is_empty_file = false;
+ db_file_handle.reset();
+ }
+
+ // first check if the database exists
+ if (!read_only && ( !fs.FileExists(path) || ( options.use_direct_io && is_empty_file )) ) {
+ // first check if the database exists
+ if (!read_only && (!fs.FileExists(path) || (options.use_direct_io && is_empty_file))) {
// file does not exist and we are in read-write mode
// create a new file