duckdb 0.2.10-dev325.0 → 0.2.10-dev337.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 +1 -1
- package/src/duckdb.cpp +213 -75
- package/src/duckdb.hpp +16 -7
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -18182,6 +18182,10 @@ FileSystem &FileSystem::GetFileSystem(ClientContext &context) {
|
|
|
18182
18182
|
return *context.db->config.file_system;
|
|
18183
18183
|
}
|
|
18184
18184
|
|
|
18185
|
+
FileOpener *FileSystem::GetFileOpener(ClientContext &context) {
|
|
18186
|
+
return context.file_opener.get();
|
|
18187
|
+
}
|
|
18188
|
+
|
|
18185
18189
|
#ifndef _WIN32
|
|
18186
18190
|
string FileSystem::PathSeparator() {
|
|
18187
18191
|
return "/";
|
|
@@ -18283,7 +18287,7 @@ string FileSystem::GetHomeDirectory() {
|
|
|
18283
18287
|
|
|
18284
18288
|
// LCOV_EXCL_START
|
|
18285
18289
|
unique_ptr<FileHandle> FileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock,
|
|
18286
|
-
FileCompressionType compression) {
|
|
18290
|
+
FileCompressionType compression, FileOpener *opener) {
|
|
18287
18291
|
throw NotImplementedException("%s: OpenFile is not implemented!", GetName());
|
|
18288
18292
|
}
|
|
18289
18293
|
|
|
@@ -20215,7 +20219,8 @@ namespace duckdb {
|
|
|
20215
20219
|
class LocalFileSystem : public FileSystem {
|
|
20216
20220
|
public:
|
|
20217
20221
|
unique_ptr<FileHandle> OpenFile(const string &path, uint8_t flags, FileLockType lock = FileLockType::NO_LOCK,
|
|
20218
|
-
FileCompressionType compression = FileCompressionType::UNCOMPRESSED
|
|
20222
|
+
FileCompressionType compression = FileCompressionType::UNCOMPRESSED,
|
|
20223
|
+
FileOpener *opener = nullptr) override;
|
|
20219
20224
|
|
|
20220
20225
|
//! Read exactly nr_bytes from the specified location in the file. Fails if nr_bytes could not be read. This is
|
|
20221
20226
|
//! equivalent to calling SetFilePointer(location) followed by calling Read().
|
|
@@ -20322,14 +20327,18 @@ extern "C" WINBASEAPI BOOL WINAPI GetPhysicallyInstalledSystemMemory(PULONGLONG)
|
|
|
20322
20327
|
namespace duckdb {
|
|
20323
20328
|
|
|
20324
20329
|
static void AssertValidFileFlags(uint8_t flags) {
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
D_ASSERT(
|
|
20330
|
-
|
|
20330
|
+
#ifdef DEBUG
|
|
20331
|
+
bool is_read = flags & FileFlags::FILE_FLAGS_READ;
|
|
20332
|
+
bool is_write = flags & FileFlags::FILE_FLAGS_WRITE;
|
|
20333
|
+
// require either READ or WRITE (or both)
|
|
20334
|
+
D_ASSERT(is_read || is_write);
|
|
20335
|
+
// CREATE/Append flags require writing
|
|
20336
|
+
D_ASSERT(is_write || !(flags & FileFlags::FILE_FLAGS_APPEND));
|
|
20337
|
+
D_ASSERT(is_write || !(flags & FileFlags::FILE_FLAGS_FILE_CREATE));
|
|
20338
|
+
D_ASSERT(is_write || !(flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW));
|
|
20331
20339
|
// cannot combine CREATE and CREATE_NEW flags
|
|
20332
20340
|
D_ASSERT(!(flags & FileFlags::FILE_FLAGS_FILE_CREATE && flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW));
|
|
20341
|
+
#endif
|
|
20333
20342
|
}
|
|
20334
20343
|
|
|
20335
20344
|
#ifndef _WIN32
|
|
@@ -20362,8 +20371,33 @@ public:
|
|
|
20362
20371
|
int fd;
|
|
20363
20372
|
};
|
|
20364
20373
|
|
|
20374
|
+
static FileType GetFileTypeInternal(int fd) {
|
|
20375
|
+
struct stat s;
|
|
20376
|
+
if (fstat(fd, &s) == -1) {
|
|
20377
|
+
return FileType::FILE_TYPE_INVALID;
|
|
20378
|
+
}
|
|
20379
|
+
switch (s.st_mode & S_IFMT) {
|
|
20380
|
+
case S_IFBLK:
|
|
20381
|
+
return FileType::FILE_TYPE_BLOCKDEV;
|
|
20382
|
+
case S_IFCHR:
|
|
20383
|
+
return FileType::FILE_TYPE_CHARDEV;
|
|
20384
|
+
case S_IFIFO:
|
|
20385
|
+
return FileType::FILE_TYPE_FIFO;
|
|
20386
|
+
case S_IFDIR:
|
|
20387
|
+
return FileType::FILE_TYPE_DIR;
|
|
20388
|
+
case S_IFLNK:
|
|
20389
|
+
return FileType::FILE_TYPE_LINK;
|
|
20390
|
+
case S_IFREG:
|
|
20391
|
+
return FileType::FILE_TYPE_REGULAR;
|
|
20392
|
+
case S_IFSOCK:
|
|
20393
|
+
return FileType::FILE_TYPE_SOCKET;
|
|
20394
|
+
default:
|
|
20395
|
+
return FileType::FILE_TYPE_INVALID;
|
|
20396
|
+
}
|
|
20397
|
+
}
|
|
20398
|
+
|
|
20365
20399
|
unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock_type,
|
|
20366
|
-
FileCompressionType compression) {
|
|
20400
|
+
FileCompressionType compression, FileOpener *opener) {
|
|
20367
20401
|
if (compression != FileCompressionType::UNCOMPRESSED) {
|
|
20368
20402
|
throw NotImplementedException("Unsupported compression type for default file system");
|
|
20369
20403
|
}
|
|
@@ -20372,12 +20406,21 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t fla
|
|
|
20372
20406
|
|
|
20373
20407
|
int open_flags = 0;
|
|
20374
20408
|
int rc;
|
|
20375
|
-
|
|
20409
|
+
bool open_read = flags & FileFlags::FILE_FLAGS_READ;
|
|
20410
|
+
bool open_write = flags & FileFlags::FILE_FLAGS_WRITE;
|
|
20411
|
+
if (open_read && open_write) {
|
|
20412
|
+
open_flags = O_RDWR;
|
|
20413
|
+
} else if (open_read) {
|
|
20376
20414
|
open_flags = O_RDONLY;
|
|
20415
|
+
} else if (open_write) {
|
|
20416
|
+
open_flags = O_WRONLY;
|
|
20377
20417
|
} else {
|
|
20418
|
+
throw InternalException("READ, WRITE or both should be specified when opening a file");
|
|
20419
|
+
}
|
|
20420
|
+
if (open_write) {
|
|
20378
20421
|
// need Read or Write
|
|
20379
20422
|
D_ASSERT(flags & FileFlags::FILE_FLAGS_WRITE);
|
|
20380
|
-
open_flags
|
|
20423
|
+
open_flags |= O_CLOEXEC;
|
|
20381
20424
|
if (flags & FileFlags::FILE_FLAGS_FILE_CREATE) {
|
|
20382
20425
|
open_flags |= O_CREAT;
|
|
20383
20426
|
} else if (flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW) {
|
|
@@ -20413,15 +20456,19 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t fla
|
|
|
20413
20456
|
// #endif
|
|
20414
20457
|
if (lock_type != FileLockType::NO_LOCK) {
|
|
20415
20458
|
// set lock on file
|
|
20416
|
-
|
|
20417
|
-
|
|
20418
|
-
|
|
20419
|
-
|
|
20420
|
-
|
|
20421
|
-
|
|
20422
|
-
|
|
20423
|
-
|
|
20424
|
-
|
|
20459
|
+
// but only if it is not an input/output stream
|
|
20460
|
+
auto file_type = GetFileTypeInternal(fd);
|
|
20461
|
+
if (file_type != FileType::FILE_TYPE_FIFO && file_type != FileType::FILE_TYPE_SOCKET) {
|
|
20462
|
+
struct flock fl;
|
|
20463
|
+
memset(&fl, 0, sizeof fl);
|
|
20464
|
+
fl.l_type = lock_type == FileLockType::READ_LOCK ? F_RDLCK : F_WRLCK;
|
|
20465
|
+
fl.l_whence = SEEK_SET;
|
|
20466
|
+
fl.l_start = 0;
|
|
20467
|
+
fl.l_len = 0;
|
|
20468
|
+
rc = fcntl(fd, F_SETLK, &fl);
|
|
20469
|
+
if (rc == -1) {
|
|
20470
|
+
throw IOException("Could not set lock on file \"%s\": %s", path, strerror(errno));
|
|
20471
|
+
}
|
|
20425
20472
|
}
|
|
20426
20473
|
}
|
|
20427
20474
|
return make_unique<UnixFileHandle>(*this, path, fd);
|
|
@@ -20507,28 +20554,7 @@ time_t LocalFileSystem::GetLastModifiedTime(FileHandle &handle) {
|
|
|
20507
20554
|
|
|
20508
20555
|
FileType LocalFileSystem::GetFileType(FileHandle &handle) {
|
|
20509
20556
|
int fd = ((UnixFileHandle &)handle).fd;
|
|
20510
|
-
|
|
20511
|
-
if (fstat(fd, &s) == -1) {
|
|
20512
|
-
return FileType::FILE_TYPE_INVALID;
|
|
20513
|
-
}
|
|
20514
|
-
switch (s.st_mode & S_IFMT) {
|
|
20515
|
-
case S_IFBLK:
|
|
20516
|
-
return FileType::FILE_TYPE_BLOCKDEV;
|
|
20517
|
-
case S_IFCHR:
|
|
20518
|
-
return FileType::FILE_TYPE_CHARDEV;
|
|
20519
|
-
case S_IFIFO:
|
|
20520
|
-
return FileType::FILE_TYPE_FIFO;
|
|
20521
|
-
case S_IFDIR:
|
|
20522
|
-
return FileType::FILE_TYPE_DIR;
|
|
20523
|
-
case S_IFLNK:
|
|
20524
|
-
return FileType::FILE_TYPE_LINK;
|
|
20525
|
-
case S_IFREG:
|
|
20526
|
-
return FileType::FILE_TYPE_REGULAR;
|
|
20527
|
-
case S_IFSOCK:
|
|
20528
|
-
return FileType::FILE_TYPE_SOCKET;
|
|
20529
|
-
default:
|
|
20530
|
-
return FileType::FILE_TYPE_INVALID;
|
|
20531
|
-
}
|
|
20557
|
+
return GetFileTypeInternal(fd);
|
|
20532
20558
|
}
|
|
20533
20559
|
|
|
20534
20560
|
void LocalFileSystem::Truncate(FileHandle &handle, int64_t new_size) {
|
|
@@ -20721,7 +20747,7 @@ public:
|
|
|
20721
20747
|
};
|
|
20722
20748
|
|
|
20723
20749
|
unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock_type,
|
|
20724
|
-
FileCompressionType compression) {
|
|
20750
|
+
FileCompressionType compression, FileOpener *opener) {
|
|
20725
20751
|
if (compression != FileCompressionType::UNCOMPRESSED) {
|
|
20726
20752
|
throw NotImplementedException("Unsupported compression type for default file system");
|
|
20727
20753
|
}
|
|
@@ -20731,14 +20757,21 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t fla
|
|
|
20731
20757
|
DWORD share_mode;
|
|
20732
20758
|
DWORD creation_disposition = OPEN_EXISTING;
|
|
20733
20759
|
DWORD flags_and_attributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED;
|
|
20734
|
-
|
|
20760
|
+
bool open_read = flags & FileFlags::FILE_FLAGS_READ;
|
|
20761
|
+
bool open_write = flags & FileFlags::FILE_FLAGS_WRITE;
|
|
20762
|
+
if (open_read && open_write) {
|
|
20763
|
+
desired_access = GENERIC_READ | GENERIC_WRITE;
|
|
20764
|
+
share_mode = 0;
|
|
20765
|
+
} else if (open_read) {
|
|
20735
20766
|
desired_access = GENERIC_READ;
|
|
20736
20767
|
share_mode = FILE_SHARE_READ;
|
|
20737
|
-
} else {
|
|
20738
|
-
|
|
20739
|
-
D_ASSERT(flags & FileFlags::FILE_FLAGS_WRITE);
|
|
20740
|
-
desired_access = GENERIC_READ | GENERIC_WRITE;
|
|
20768
|
+
} else if (open_write) {
|
|
20769
|
+
desired_access = GENERIC_WRITE;
|
|
20741
20770
|
share_mode = 0;
|
|
20771
|
+
} else {
|
|
20772
|
+
throw InternalException("READ, WRITE or both should be specified when opening a file");
|
|
20773
|
+
}
|
|
20774
|
+
if (open_write) {
|
|
20742
20775
|
if (flags & FileFlags::FILE_FLAGS_FILE_CREATE) {
|
|
20743
20776
|
creation_disposition = OPEN_ALWAYS;
|
|
20744
20777
|
} else if (flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW) {
|
|
@@ -28380,7 +28413,7 @@ namespace duckdb {
|
|
|
28380
28413
|
|
|
28381
28414
|
class BufferedFileReader : public Deserializer {
|
|
28382
28415
|
public:
|
|
28383
|
-
BufferedFileReader(FileSystem &fs, const char *path);
|
|
28416
|
+
BufferedFileReader(FileSystem &fs, const char *path, FileOpener *opener = nullptr);
|
|
28384
28417
|
|
|
28385
28418
|
FileSystem &fs;
|
|
28386
28419
|
unique_ptr<data_t[]> data;
|
|
@@ -28412,9 +28445,10 @@ private:
|
|
|
28412
28445
|
|
|
28413
28446
|
namespace duckdb {
|
|
28414
28447
|
|
|
28415
|
-
BufferedFileReader::BufferedFileReader(FileSystem &fs, const char *path)
|
|
28448
|
+
BufferedFileReader::BufferedFileReader(FileSystem &fs, const char *path, FileOpener *opener)
|
|
28416
28449
|
: fs(fs), data(unique_ptr<data_t[]>(new data_t[FILE_BUFFER_SIZE])), offset(0), read_data(0), total_read(0) {
|
|
28417
|
-
handle =
|
|
28450
|
+
handle =
|
|
28451
|
+
fs.OpenFile(path, FileFlags::FILE_FLAGS_READ, FileLockType::READ_LOCK, FileSystem::DEFAULT_COMPRESSION, opener);
|
|
28418
28452
|
file_size = fs.GetFileSize(*handle);
|
|
28419
28453
|
}
|
|
28420
28454
|
|
|
@@ -28467,9 +28501,12 @@ bool BufferedFileReader::Finished() {
|
|
|
28467
28501
|
|
|
28468
28502
|
namespace duckdb {
|
|
28469
28503
|
|
|
28470
|
-
|
|
28504
|
+
// Remove this when we switch C++17: https://stackoverflow.com/a/53350948
|
|
28505
|
+
constexpr uint8_t BufferedFileWriter::DEFAULT_OPEN_FLAGS;
|
|
28506
|
+
|
|
28507
|
+
BufferedFileWriter::BufferedFileWriter(FileSystem &fs, const string &path, uint8_t open_flags, FileOpener *opener)
|
|
28471
28508
|
: fs(fs), data(unique_ptr<data_t[]>(new data_t[FILE_BUFFER_SIZE])), offset(0), total_written(0) {
|
|
28472
|
-
handle = fs.OpenFile(path, open_flags, FileLockType::WRITE_LOCK);
|
|
28509
|
+
handle = fs.OpenFile(path, open_flags, FileLockType::WRITE_LOCK, FileSystem::DEFAULT_COMPRESSION, opener);
|
|
28473
28510
|
}
|
|
28474
28511
|
|
|
28475
28512
|
int64_t BufferedFileWriter::GetFileSize() {
|
|
@@ -45310,7 +45347,8 @@ public:
|
|
|
45310
45347
|
VirtualFileSystem();
|
|
45311
45348
|
|
|
45312
45349
|
unique_ptr<FileHandle> OpenFile(const string &path, uint8_t flags, FileLockType lock = FileLockType::NO_LOCK,
|
|
45313
|
-
FileCompressionType compression = FileCompressionType::UNCOMPRESSED
|
|
45350
|
+
FileCompressionType compression = FileCompressionType::UNCOMPRESSED,
|
|
45351
|
+
FileOpener *opener = nullptr) override;
|
|
45314
45352
|
|
|
45315
45353
|
void Read(FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) override {
|
|
45316
45354
|
handle.file_system.Read(handle, buffer, nr_bytes, location);
|
|
@@ -45414,7 +45452,7 @@ VirtualFileSystem::VirtualFileSystem() : default_fs(FileSystem::CreateLocal()) {
|
|
|
45414
45452
|
}
|
|
45415
45453
|
|
|
45416
45454
|
unique_ptr<FileHandle> VirtualFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock,
|
|
45417
|
-
FileCompressionType compression) {
|
|
45455
|
+
FileCompressionType compression, FileOpener *opener) {
|
|
45418
45456
|
if (compression == FileCompressionType::AUTO_DETECT) {
|
|
45419
45457
|
// auto detect compression settings based on file name
|
|
45420
45458
|
auto lower_path = StringUtil::Lower(path);
|
|
@@ -45425,7 +45463,7 @@ unique_ptr<FileHandle> VirtualFileSystem::OpenFile(const string &path, uint8_t f
|
|
|
45425
45463
|
}
|
|
45426
45464
|
}
|
|
45427
45465
|
// open the base file handle
|
|
45428
|
-
auto file_handle = FindFileSystem(path)->OpenFile(path, flags, lock, FileCompressionType::UNCOMPRESSED);
|
|
45466
|
+
auto file_handle = FindFileSystem(path)->OpenFile(path, flags, lock, FileCompressionType::UNCOMPRESSED, opener);
|
|
45429
45467
|
if (file_handle->GetType() == FileType::FILE_TYPE_FIFO) {
|
|
45430
45468
|
file_handle = PipeFileSystem::OpenPipe(move(file_handle));
|
|
45431
45469
|
} else if (compression != FileCompressionType::UNCOMPRESSED) {
|
|
@@ -59462,6 +59500,7 @@ struct CopyInfo;
|
|
|
59462
59500
|
struct FileHandle;
|
|
59463
59501
|
struct StrpTimeFormat;
|
|
59464
59502
|
|
|
59503
|
+
class FileOpener;
|
|
59465
59504
|
class FileSystem;
|
|
59466
59505
|
|
|
59467
59506
|
//! The shifts array allows for linear searching of multi-byte values. For each position, it determines the next
|
|
@@ -59562,10 +59601,11 @@ public:
|
|
|
59562
59601
|
BufferedCSVReader(ClientContext &context, BufferedCSVReaderOptions options,
|
|
59563
59602
|
const vector<LogicalType> &requested_types = vector<LogicalType>());
|
|
59564
59603
|
|
|
59565
|
-
BufferedCSVReader(FileSystem &fs, BufferedCSVReaderOptions options,
|
|
59604
|
+
BufferedCSVReader(FileSystem &fs, FileOpener *opener, BufferedCSVReaderOptions options,
|
|
59566
59605
|
const vector<LogicalType> &requested_types = vector<LogicalType>());
|
|
59567
59606
|
|
|
59568
59607
|
FileSystem &fs;
|
|
59608
|
+
FileOpener *opener;
|
|
59569
59609
|
BufferedCSVReaderOptions options;
|
|
59570
59610
|
vector<LogicalType> sql_types;
|
|
59571
59611
|
vector<string> col_names;
|
|
@@ -59798,16 +59838,17 @@ TextSearchShiftArray::TextSearchShiftArray(string search_term) : length(search_t
|
|
|
59798
59838
|
}
|
|
59799
59839
|
}
|
|
59800
59840
|
|
|
59801
|
-
BufferedCSVReader::BufferedCSVReader(FileSystem &fs_p, BufferedCSVReaderOptions options_p,
|
|
59841
|
+
BufferedCSVReader::BufferedCSVReader(FileSystem &fs_p, FileOpener *opener_p, BufferedCSVReaderOptions options_p,
|
|
59802
59842
|
const vector<LogicalType> &requested_types)
|
|
59803
|
-
: fs(fs_p), options(move(options_p)), buffer_size(0), position(0), start(0) {
|
|
59843
|
+
: fs(fs_p), opener(opener_p), options(move(options_p)), buffer_size(0), position(0), start(0) {
|
|
59804
59844
|
file_handle = OpenCSV(options);
|
|
59805
59845
|
Initialize(requested_types);
|
|
59806
59846
|
}
|
|
59807
59847
|
|
|
59808
59848
|
BufferedCSVReader::BufferedCSVReader(ClientContext &context, BufferedCSVReaderOptions options_p,
|
|
59809
59849
|
const vector<LogicalType> &requested_types)
|
|
59810
|
-
: BufferedCSVReader(FileSystem::GetFileSystem(context), move(options_p),
|
|
59850
|
+
: BufferedCSVReader(FileSystem::GetFileSystem(context), FileSystem::GetFileOpener(context), move(options_p),
|
|
59851
|
+
requested_types) {
|
|
59811
59852
|
}
|
|
59812
59853
|
|
|
59813
59854
|
void BufferedCSVReader::Initialize(const vector<LogicalType> &requested_types) {
|
|
@@ -59839,8 +59880,8 @@ unique_ptr<FileHandle> BufferedCSVReader::OpenCSV(const BufferedCSVReaderOptions
|
|
|
59839
59880
|
this->compression = FileCompressionType::GZIP;
|
|
59840
59881
|
}
|
|
59841
59882
|
|
|
59842
|
-
auto result =
|
|
59843
|
-
|
|
59883
|
+
auto result = fs.OpenFile(options.file_path.c_str(), FileFlags::FILE_FLAGS_READ, FileLockType::NO_LOCK,
|
|
59884
|
+
this->compression, this->opener);
|
|
59844
59885
|
plain_file_source = result->OnDiskFile() && result->CanSeek();
|
|
59845
59886
|
file_size = result->GetFileSize();
|
|
59846
59887
|
return result;
|
|
@@ -59850,7 +59891,7 @@ unique_ptr<FileHandle> BufferedCSVReader::OpenCSV(const BufferedCSVReaderOptions
|
|
|
59850
59891
|
static string GenerateColumnName(const idx_t total_cols, const idx_t col_number, const string &prefix = "column") {
|
|
59851
59892
|
int max_digits = NumericHelper::UnsignedLength(total_cols - 1);
|
|
59852
59893
|
int digits = NumericHelper::UnsignedLength(col_number);
|
|
59853
|
-
string leading_zeros = string(
|
|
59894
|
+
string leading_zeros = string(max_digits - digits, '0');
|
|
59854
59895
|
string value = to_string(col_number);
|
|
59855
59896
|
return string(prefix + leading_zeros + value);
|
|
59856
59897
|
}
|
|
@@ -61584,10 +61625,10 @@ static void WriteCatalogEntries(stringstream &ss, vector<CatalogEntry *> &entrie
|
|
|
61584
61625
|
ss << std::endl;
|
|
61585
61626
|
}
|
|
61586
61627
|
|
|
61587
|
-
static void WriteStringStreamToFile(FileSystem &fs, stringstream &ss, const string &path) {
|
|
61628
|
+
static void WriteStringStreamToFile(FileSystem &fs, FileOpener *opener, stringstream &ss, const string &path) {
|
|
61588
61629
|
auto ss_string = ss.str();
|
|
61589
61630
|
auto handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE_NEW,
|
|
61590
|
-
FileLockType::WRITE_LOCK);
|
|
61631
|
+
FileLockType::WRITE_LOCK, FileSystem::DEFAULT_COMPRESSION, opener);
|
|
61591
61632
|
fs.Write(*handle, (void *)ss_string.c_str(), ss_string.size());
|
|
61592
61633
|
handle.reset();
|
|
61593
61634
|
}
|
|
@@ -61641,6 +61682,7 @@ static void WriteCopyStatement(FileSystem &fs, stringstream &ss, TableCatalogEnt
|
|
|
61641
61682
|
void PhysicalExport::GetChunkInternal(ExecutionContext &context, DataChunk &chunk, PhysicalOperatorState *state) const {
|
|
61642
61683
|
auto &ccontext = context.client;
|
|
61643
61684
|
auto &fs = FileSystem::GetFileSystem(ccontext);
|
|
61685
|
+
auto *opener = FileSystem::GetFileOpener(ccontext);
|
|
61644
61686
|
|
|
61645
61687
|
// gather all catalog types to export
|
|
61646
61688
|
vector<CatalogEntry *> schemas;
|
|
@@ -61680,7 +61722,7 @@ void PhysicalExport::GetChunkInternal(ExecutionContext &context, DataChunk &chun
|
|
|
61680
61722
|
WriteCatalogEntries(ss, views);
|
|
61681
61723
|
WriteCatalogEntries(ss, indexes);
|
|
61682
61724
|
|
|
61683
|
-
WriteStringStreamToFile(fs, ss, fs.JoinPath(info->file_path, "schema.sql"));
|
|
61725
|
+
WriteStringStreamToFile(fs, opener, ss, fs.JoinPath(info->file_path, "schema.sql"));
|
|
61684
61726
|
|
|
61685
61727
|
// write the load.sql file
|
|
61686
61728
|
// for every table, we write COPY INTO statement with the specified options
|
|
@@ -61690,7 +61732,7 @@ void PhysicalExport::GetChunkInternal(ExecutionContext &context, DataChunk &chun
|
|
|
61690
61732
|
auto exported_table_info = kv.second;
|
|
61691
61733
|
WriteCopyStatement(fs, load_ss, table, *info, exported_table_info, function);
|
|
61692
61734
|
}
|
|
61693
|
-
WriteStringStreamToFile(fs, load_ss, fs.JoinPath(info->file_path, "load.sql"));
|
|
61735
|
+
WriteStringStreamToFile(fs, opener, load_ss, fs.JoinPath(info->file_path, "load.sql"));
|
|
61694
61736
|
state->finished = true;
|
|
61695
61737
|
}
|
|
61696
61738
|
|
|
@@ -76035,7 +76077,9 @@ static void PragmaLogQueryPath(ClientContext &context, const FunctionParameters
|
|
|
76035
76077
|
// empty path: clean up query writer
|
|
76036
76078
|
context.log_query_writer = nullptr;
|
|
76037
76079
|
} else {
|
|
76038
|
-
context.log_query_writer =
|
|
76080
|
+
context.log_query_writer =
|
|
76081
|
+
make_unique<BufferedFileWriter>(FileSystem::GetFileSystem(context), str_val,
|
|
76082
|
+
BufferedFileWriter::DEFAULT_OPEN_FLAGS, context.file_opener.get());
|
|
76039
76083
|
}
|
|
76040
76084
|
}
|
|
76041
76085
|
|
|
@@ -76243,12 +76287,15 @@ string PragmaVersion(ClientContext &context, const FunctionParameters ¶meter
|
|
|
76243
76287
|
|
|
76244
76288
|
string PragmaImportDatabase(ClientContext &context, const FunctionParameters ¶meters) {
|
|
76245
76289
|
auto &fs = FileSystem::GetFileSystem(context);
|
|
76290
|
+
auto *opener = FileSystem::GetFileOpener(context);
|
|
76291
|
+
|
|
76246
76292
|
string query;
|
|
76247
76293
|
// read the "shema.sql" and "load.sql" files
|
|
76248
76294
|
vector<string> files = {"schema.sql", "load.sql"};
|
|
76249
76295
|
for (auto &file : files) {
|
|
76250
76296
|
auto file_path = fs.JoinPath(parameters.values[0].ToString(), file);
|
|
76251
|
-
auto handle = fs.OpenFile(file_path, FileFlags::FILE_FLAGS_READ
|
|
76297
|
+
auto handle = fs.OpenFile(file_path, FileFlags::FILE_FLAGS_READ, FileSystem::DEFAULT_LOCK,
|
|
76298
|
+
FileSystem::DEFAULT_COMPRESSION, opener);
|
|
76252
76299
|
auto fsize = fs.GetFileSize(*handle);
|
|
76253
76300
|
auto buffer = unique_ptr<char[]>(new char[fsize]);
|
|
76254
76301
|
fs.Read(*handle, buffer.get(), fsize);
|
|
@@ -91223,9 +91270,9 @@ struct LocalReadCSVData : public LocalFunctionData {
|
|
|
91223
91270
|
};
|
|
91224
91271
|
|
|
91225
91272
|
struct GlobalWriteCSVData : public GlobalFunctionData {
|
|
91226
|
-
GlobalWriteCSVData(FileSystem &fs, const string &file_path) : fs(fs) {
|
|
91273
|
+
GlobalWriteCSVData(FileSystem &fs, const string &file_path, FileOpener *opener) : fs(fs) {
|
|
91227
91274
|
handle = fs.OpenFile(file_path, FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE_NEW,
|
|
91228
|
-
FileLockType::WRITE_LOCK);
|
|
91275
|
+
FileLockType::WRITE_LOCK, FileSystem::DEFAULT_COMPRESSION, opener);
|
|
91229
91276
|
}
|
|
91230
91277
|
|
|
91231
91278
|
void WriteData(const_data_ptr_t data, idx_t size) {
|
|
@@ -91255,7 +91302,8 @@ static unique_ptr<LocalFunctionData> WriteCSVInitializeLocal(ClientContext &cont
|
|
|
91255
91302
|
static unique_ptr<GlobalFunctionData> WriteCSVInitializeGlobal(ClientContext &context, FunctionData &bind_data) {
|
|
91256
91303
|
auto &csv_data = (WriteCSVData &)bind_data;
|
|
91257
91304
|
auto &options = csv_data.options;
|
|
91258
|
-
auto global_data = make_unique<GlobalWriteCSVData>(FileSystem::GetFileSystem(context), csv_data.files[0]
|
|
91305
|
+
auto global_data = make_unique<GlobalWriteCSVData>(FileSystem::GetFileSystem(context), csv_data.files[0],
|
|
91306
|
+
FileSystem::GetFileOpener(context));
|
|
91259
91307
|
|
|
91260
91308
|
if (options.header) {
|
|
91261
91309
|
BufferedSerializer serializer;
|
|
@@ -96978,6 +97026,61 @@ bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row) {
|
|
|
96978
97026
|
return result->columns[col].nullmask[row];
|
|
96979
97027
|
}
|
|
96980
97028
|
|
|
97029
|
+
//===----------------------------------------------------------------------===//
|
|
97030
|
+
// DuckDB
|
|
97031
|
+
//
|
|
97032
|
+
// duckdb/main/client_context_file_opener.hpp
|
|
97033
|
+
//
|
|
97034
|
+
//
|
|
97035
|
+
//===----------------------------------------------------------------------===//
|
|
97036
|
+
|
|
97037
|
+
|
|
97038
|
+
|
|
97039
|
+
//===----------------------------------------------------------------------===//
|
|
97040
|
+
// DuckDB
|
|
97041
|
+
//
|
|
97042
|
+
// duckdb/common/file_opener.hpp
|
|
97043
|
+
//
|
|
97044
|
+
//
|
|
97045
|
+
//===----------------------------------------------------------------------===//
|
|
97046
|
+
|
|
97047
|
+
|
|
97048
|
+
|
|
97049
|
+
|
|
97050
|
+
|
|
97051
|
+
namespace duckdb {
|
|
97052
|
+
|
|
97053
|
+
class Value;
|
|
97054
|
+
|
|
97055
|
+
//! Abstact type that provide client-spcific context to FileSystem.
|
|
97056
|
+
class FileOpener {
|
|
97057
|
+
public:
|
|
97058
|
+
virtual ~FileOpener() {};
|
|
97059
|
+
|
|
97060
|
+
virtual bool TryGetCurrentSetting(const string &key, Value &result) = 0;
|
|
97061
|
+
};
|
|
97062
|
+
|
|
97063
|
+
} // namespace duckdb
|
|
97064
|
+
|
|
97065
|
+
namespace duckdb {
|
|
97066
|
+
|
|
97067
|
+
class ClientContext;
|
|
97068
|
+
|
|
97069
|
+
//! ClientContext-specific FileOpener implemenation.
|
|
97070
|
+
//! This object is owned by ClientContext and never outlives it.
|
|
97071
|
+
class ClientContextFileOpener : public FileOpener {
|
|
97072
|
+
public:
|
|
97073
|
+
explicit ClientContextFileOpener(ClientContext &context_p) : context(context_p) {
|
|
97074
|
+
}
|
|
97075
|
+
|
|
97076
|
+
bool TryGetCurrentSetting(const string &key, Value &result) override;
|
|
97077
|
+
|
|
97078
|
+
private:
|
|
97079
|
+
ClientContext &context;
|
|
97080
|
+
};
|
|
97081
|
+
|
|
97082
|
+
} // namespace duckdb
|
|
97083
|
+
|
|
96981
97084
|
|
|
96982
97085
|
|
|
96983
97086
|
|
|
@@ -97428,7 +97531,8 @@ private:
|
|
|
97428
97531
|
ClientContext::ClientContext(shared_ptr<DatabaseInstance> database)
|
|
97429
97532
|
: profiler(make_unique<QueryProfiler>()), query_profiler_history(make_unique<QueryProfilerHistory>()),
|
|
97430
97533
|
db(move(database)), transaction(db->GetTransactionManager(), *this), interrupted(false), executor(*this),
|
|
97431
|
-
temporary_objects(make_unique<SchemaCatalogEntry>(&db->GetCatalog(), TEMP_SCHEMA, true)),
|
|
97534
|
+
temporary_objects(make_unique<SchemaCatalogEntry>(&db->GetCatalog(), TEMP_SCHEMA, true)),
|
|
97535
|
+
file_opener(make_unique<ClientContextFileOpener>(*this)), open_result(nullptr) {
|
|
97432
97536
|
std::random_device rd;
|
|
97433
97537
|
random_engine.seed(rd());
|
|
97434
97538
|
|
|
@@ -97895,7 +97999,8 @@ void ClientContext::LogQueryInternal(ClientContextLock &, const string &query) {
|
|
|
97895
97999
|
#ifdef DUCKDB_FORCE_QUERY_LOG
|
|
97896
98000
|
try {
|
|
97897
98001
|
string log_path(DUCKDB_FORCE_QUERY_LOG);
|
|
97898
|
-
log_query_writer = make_unique<BufferedFileWriter>(
|
|
98002
|
+
log_query_writer = make_unique<BufferedFileWriter>(
|
|
98003
|
+
FileSystem::GetFileSystem(*this), log_path, BufferedFileWriter::DEFAULT_OPEN_FLAGS, file_opener.get());
|
|
97899
98004
|
} catch (...) {
|
|
97900
98005
|
return;
|
|
97901
98006
|
}
|
|
@@ -98315,6 +98420,16 @@ bool ClientContext::TryGetCurrentSetting(const std::string &key, Value &result)
|
|
|
98315
98420
|
|
|
98316
98421
|
|
|
98317
98422
|
|
|
98423
|
+
namespace duckdb {
|
|
98424
|
+
|
|
98425
|
+
bool ClientContextFileOpener::TryGetCurrentSetting(const string &key, Value &result) {
|
|
98426
|
+
return context.TryGetCurrentSetting(key, result);
|
|
98427
|
+
}
|
|
98428
|
+
|
|
98429
|
+
} // namespace duckdb
|
|
98430
|
+
|
|
98431
|
+
|
|
98432
|
+
|
|
98318
98433
|
namespace duckdb {
|
|
98319
98434
|
|
|
98320
98435
|
static ConfigurationOption internal_options[] = {
|
|
@@ -145876,6 +145991,29 @@ idx_t LocalStorage::Delete(DataTable *table, Vector &row_ids, idx_t count) {
|
|
|
145876
145991
|
idx_t chunk_idx = GetChunk(row_ids);
|
|
145877
145992
|
D_ASSERT(chunk_idx < storage->collection.ChunkCount());
|
|
145878
145993
|
|
|
145994
|
+
// delete from unique indices (if any)
|
|
145995
|
+
if (!storage->indexes.empty()) {
|
|
145996
|
+
// Index::Delete assumes that ALL rows are being deleted, so
|
|
145997
|
+
// Slice out the rows that are being deleted from the storage Chunk
|
|
145998
|
+
auto &chunk = storage->collection.GetChunk(chunk_idx);
|
|
145999
|
+
|
|
146000
|
+
VectorData row_ids_data;
|
|
146001
|
+
row_ids.Orrify(count, row_ids_data);
|
|
146002
|
+
auto row_identifiers = (const row_t *)row_ids_data.data;
|
|
146003
|
+
SelectionVector sel(count);
|
|
146004
|
+
for (idx_t i = 0; i < count; ++i) {
|
|
146005
|
+
const auto idx = row_ids_data.sel->get_index(i);
|
|
146006
|
+
sel.set_index(i, row_identifiers[idx] - MAX_ROW_ID);
|
|
146007
|
+
}
|
|
146008
|
+
|
|
146009
|
+
DataChunk deleted;
|
|
146010
|
+
deleted.InitializeEmpty(chunk.GetTypes());
|
|
146011
|
+
deleted.Slice(chunk, sel, count);
|
|
146012
|
+
for (auto &index : storage->indexes) {
|
|
146013
|
+
index->Delete(deleted, row_ids);
|
|
146014
|
+
}
|
|
146015
|
+
}
|
|
146016
|
+
|
|
145879
146017
|
// get a pointer to the deleted entries for this chunk
|
|
145880
146018
|
bool *deleted;
|
|
145881
146019
|
auto entry = storage->deleted_entries.find(chunk_idx);
|
|
@@ -146392,7 +146530,7 @@ SingleFileBlockManager::SingleFileBlockManager(DatabaseInstance &db, string path
|
|
|
146392
146530
|
flags = FileFlags::FILE_FLAGS_READ;
|
|
146393
146531
|
lock = FileLockType::READ_LOCK;
|
|
146394
146532
|
} else {
|
|
146395
|
-
flags = FileFlags::FILE_FLAGS_WRITE;
|
|
146533
|
+
flags = FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_READ;
|
|
146396
146534
|
lock = FileLockType::WRITE_LOCK;
|
|
146397
146535
|
if (create_new) {
|
|
146398
146536
|
flags |= FileFlags::FILE_FLAGS_FILE_CREATE;
|
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 "
|
|
14
|
-
#define DUCKDB_VERSION "0.2.10-
|
|
13
|
+
#define DUCKDB_SOURCE_ID "ee3e405a9"
|
|
14
|
+
#define DUCKDB_VERSION "0.2.10-dev337"
|
|
15
15
|
//===----------------------------------------------------------------------===//
|
|
16
16
|
// DuckDB
|
|
17
17
|
//
|
|
@@ -1710,6 +1710,7 @@ enum class FileCompressionType : uint8_t { AUTO_DETECT = 0, UNCOMPRESSED = 1, GZ
|
|
|
1710
1710
|
namespace duckdb {
|
|
1711
1711
|
class ClientContext;
|
|
1712
1712
|
class DatabaseInstance;
|
|
1713
|
+
class FileOpener;
|
|
1713
1714
|
class FileSystem;
|
|
1714
1715
|
|
|
1715
1716
|
enum class FileType {
|
|
@@ -1787,12 +1788,15 @@ public:
|
|
|
1787
1788
|
}
|
|
1788
1789
|
|
|
1789
1790
|
public:
|
|
1791
|
+
static constexpr FileLockType DEFAULT_LOCK = FileLockType::NO_LOCK;
|
|
1792
|
+
static constexpr FileCompressionType DEFAULT_COMPRESSION = FileCompressionType::UNCOMPRESSED;
|
|
1790
1793
|
static FileSystem &GetFileSystem(ClientContext &context);
|
|
1791
1794
|
static FileSystem &GetFileSystem(DatabaseInstance &db);
|
|
1795
|
+
static FileOpener *GetFileOpener(ClientContext &context);
|
|
1792
1796
|
|
|
1793
|
-
virtual unique_ptr<FileHandle> OpenFile(const string &path, uint8_t flags,
|
|
1794
|
-
|
|
1795
|
-
|
|
1797
|
+
virtual unique_ptr<FileHandle> OpenFile(const string &path, uint8_t flags, FileLockType lock = DEFAULT_LOCK,
|
|
1798
|
+
FileCompressionType compression = DEFAULT_COMPRESSION,
|
|
1799
|
+
FileOpener *opener = nullptr);
|
|
1796
1800
|
|
|
1797
1801
|
//! Read exactly nr_bytes from the specified location in the file. Fails if nr_bytes could not be read. This is
|
|
1798
1802
|
//! equivalent to calling SetFilePointer(location) followed by calling Read().
|
|
@@ -1889,10 +1893,12 @@ namespace duckdb {
|
|
|
1889
1893
|
|
|
1890
1894
|
class BufferedFileWriter : public Serializer {
|
|
1891
1895
|
public:
|
|
1896
|
+
static constexpr uint8_t DEFAULT_OPEN_FLAGS = FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE;
|
|
1897
|
+
|
|
1892
1898
|
//! Serializes to a buffer allocated by the serializer, will expand when
|
|
1893
1899
|
//! writing past the initial threshold
|
|
1894
|
-
BufferedFileWriter(FileSystem &fs, const string &path,
|
|
1895
|
-
|
|
1900
|
+
BufferedFileWriter(FileSystem &fs, const string &path, uint8_t open_flags = DEFAULT_OPEN_FLAGS,
|
|
1901
|
+
FileOpener *opener = nullptr);
|
|
1896
1902
|
|
|
1897
1903
|
FileSystem &fs;
|
|
1898
1904
|
unique_ptr<data_t[]> data;
|
|
@@ -13058,6 +13064,7 @@ class Appender;
|
|
|
13058
13064
|
class Catalog;
|
|
13059
13065
|
class ChunkCollection;
|
|
13060
13066
|
class DatabaseInstance;
|
|
13067
|
+
class FileOpener;
|
|
13061
13068
|
class LogicalOperator;
|
|
13062
13069
|
class PreparedStatementData;
|
|
13063
13070
|
class Relation;
|
|
@@ -13129,6 +13136,8 @@ public:
|
|
|
13129
13136
|
//! The schema search path, in order by which entries are searched if no schema entry is provided
|
|
13130
13137
|
vector<string> catalog_search_path = {TEMP_SCHEMA, DEFAULT_SCHEMA, "pg_catalog"};
|
|
13131
13138
|
|
|
13139
|
+
unique_ptr<FileOpener> file_opener;
|
|
13140
|
+
|
|
13132
13141
|
public:
|
|
13133
13142
|
DUCKDB_API Transaction &ActiveTransaction() {
|
|
13134
13143
|
return transaction.ActiveTransaction();
|