duckdb 0.2.10-dev331.0 → 0.2.10-dev343.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.2.10-dev331.0",
4
+ "version": "0.2.10-dev343.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -20327,14 +20327,18 @@ extern "C" WINBASEAPI BOOL WINAPI GetPhysicallyInstalledSystemMemory(PULONGLONG)
20327
20327
  namespace duckdb {
20328
20328
 
20329
20329
  static void AssertValidFileFlags(uint8_t flags) {
20330
- // cannot combine Read and Write flags
20331
- D_ASSERT(!(flags & FileFlags::FILE_FLAGS_READ && flags & FileFlags::FILE_FLAGS_WRITE));
20332
- // cannot combine Read and CREATE/Append flags
20333
- D_ASSERT(!(flags & FileFlags::FILE_FLAGS_READ && flags & FileFlags::FILE_FLAGS_APPEND));
20334
- D_ASSERT(!(flags & FileFlags::FILE_FLAGS_READ && flags & FileFlags::FILE_FLAGS_FILE_CREATE));
20335
- D_ASSERT(!(flags & FileFlags::FILE_FLAGS_READ && flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW));
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));
20336
20339
  // cannot combine CREATE and CREATE_NEW flags
20337
20340
  D_ASSERT(!(flags & FileFlags::FILE_FLAGS_FILE_CREATE && flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW));
20341
+ #endif
20338
20342
  }
20339
20343
 
20340
20344
  #ifndef _WIN32
@@ -20367,6 +20371,31 @@ public:
20367
20371
  int fd;
20368
20372
  };
20369
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
+
20370
20399
  unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock_type,
20371
20400
  FileCompressionType compression, FileOpener *opener) {
20372
20401
  if (compression != FileCompressionType::UNCOMPRESSED) {
@@ -20377,12 +20406,21 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t fla
20377
20406
 
20378
20407
  int open_flags = 0;
20379
20408
  int rc;
20380
- if (flags & FileFlags::FILE_FLAGS_READ) {
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) {
20381
20414
  open_flags = O_RDONLY;
20415
+ } else if (open_write) {
20416
+ open_flags = O_WRONLY;
20382
20417
  } else {
20418
+ throw InternalException("READ, WRITE or both should be specified when opening a file");
20419
+ }
20420
+ if (open_write) {
20383
20421
  // need Read or Write
20384
20422
  D_ASSERT(flags & FileFlags::FILE_FLAGS_WRITE);
20385
- open_flags = O_RDWR | O_CLOEXEC;
20423
+ open_flags |= O_CLOEXEC;
20386
20424
  if (flags & FileFlags::FILE_FLAGS_FILE_CREATE) {
20387
20425
  open_flags |= O_CREAT;
20388
20426
  } else if (flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW) {
@@ -20418,15 +20456,19 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t fla
20418
20456
  // #endif
20419
20457
  if (lock_type != FileLockType::NO_LOCK) {
20420
20458
  // set lock on file
20421
- struct flock fl;
20422
- memset(&fl, 0, sizeof fl);
20423
- fl.l_type = lock_type == FileLockType::READ_LOCK ? F_RDLCK : F_WRLCK;
20424
- fl.l_whence = SEEK_SET;
20425
- fl.l_start = 0;
20426
- fl.l_len = 0;
20427
- rc = fcntl(fd, F_SETLK, &fl);
20428
- if (rc == -1) {
20429
- throw IOException("Could not set lock on file \"%s\": %s", path, strerror(errno));
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
+ }
20430
20472
  }
20431
20473
  }
20432
20474
  return make_unique<UnixFileHandle>(*this, path, fd);
@@ -20512,28 +20554,7 @@ time_t LocalFileSystem::GetLastModifiedTime(FileHandle &handle) {
20512
20554
 
20513
20555
  FileType LocalFileSystem::GetFileType(FileHandle &handle) {
20514
20556
  int fd = ((UnixFileHandle &)handle).fd;
20515
- struct stat s;
20516
- if (fstat(fd, &s) == -1) {
20517
- return FileType::FILE_TYPE_INVALID;
20518
- }
20519
- switch (s.st_mode & S_IFMT) {
20520
- case S_IFBLK:
20521
- return FileType::FILE_TYPE_BLOCKDEV;
20522
- case S_IFCHR:
20523
- return FileType::FILE_TYPE_CHARDEV;
20524
- case S_IFIFO:
20525
- return FileType::FILE_TYPE_FIFO;
20526
- case S_IFDIR:
20527
- return FileType::FILE_TYPE_DIR;
20528
- case S_IFLNK:
20529
- return FileType::FILE_TYPE_LINK;
20530
- case S_IFREG:
20531
- return FileType::FILE_TYPE_REGULAR;
20532
- case S_IFSOCK:
20533
- return FileType::FILE_TYPE_SOCKET;
20534
- default:
20535
- return FileType::FILE_TYPE_INVALID;
20536
- }
20557
+ return GetFileTypeInternal(fd);
20537
20558
  }
20538
20559
 
20539
20560
  void LocalFileSystem::Truncate(FileHandle &handle, int64_t new_size) {
@@ -20736,14 +20757,21 @@ unique_ptr<FileHandle> LocalFileSystem::OpenFile(const string &path, uint8_t fla
20736
20757
  DWORD share_mode;
20737
20758
  DWORD creation_disposition = OPEN_EXISTING;
20738
20759
  DWORD flags_and_attributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED;
20739
- if (flags & FileFlags::FILE_FLAGS_READ) {
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) {
20740
20766
  desired_access = GENERIC_READ;
20741
20767
  share_mode = FILE_SHARE_READ;
20742
- } else {
20743
- // need Read or Write
20744
- D_ASSERT(flags & FileFlags::FILE_FLAGS_WRITE);
20745
- desired_access = GENERIC_READ | GENERIC_WRITE;
20768
+ } else if (open_write) {
20769
+ desired_access = GENERIC_WRITE;
20746
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) {
20747
20775
  if (flags & FileFlags::FILE_FLAGS_FILE_CREATE) {
20748
20776
  creation_disposition = OPEN_ALWAYS;
20749
20777
  } else if (flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW) {
@@ -34540,6 +34568,7 @@ hash_t Hash(uint8_t *val, size_t size) {
34540
34568
 
34541
34569
 
34542
34570
 
34571
+
34543
34572
  #include <cmath>
34544
34573
  #include <limits>
34545
34574
 
@@ -59863,7 +59892,7 @@ unique_ptr<FileHandle> BufferedCSVReader::OpenCSV(const BufferedCSVReaderOptions
59863
59892
  static string GenerateColumnName(const idx_t total_cols, const idx_t col_number, const string &prefix = "column") {
59864
59893
  int max_digits = NumericHelper::UnsignedLength(total_cols - 1);
59865
59894
  int digits = NumericHelper::UnsignedLength(col_number);
59866
- string leading_zeros = string("0", max_digits - digits);
59895
+ string leading_zeros = string(max_digits - digits, '0');
59867
59896
  string value = to_string(col_number);
59868
59897
  return string(prefix + leading_zeros + value);
59869
59898
  }
@@ -83966,6 +83995,7 @@ void BitwiseNotFun::RegisterFunction(BuiltinFunctions &set) {
83966
83995
 
83967
83996
 
83968
83997
 
83998
+
83969
83999
  #include <limits>
83970
84000
  #include <algorithm>
83971
84001
 
@@ -92159,6 +92189,7 @@ public:
92159
92189
  } // namespace duckdb
92160
92190
 
92161
92191
 
92192
+
92162
92193
  #include <limits>
92163
92194
 
92164
92195
  namespace duckdb {
@@ -99873,13 +99904,47 @@ void QueryProfiler::ToStream(std::ostream &ss, bool print_optimizer_output) cons
99873
99904
  }
99874
99905
  }
99875
99906
 
99907
+ static string JSONSanitize(const string &text) {
99908
+ string result;
99909
+ result.reserve(text.size());
99910
+ for (idx_t i = 0; i < text.size(); i++) {
99911
+ switch (text[i]) {
99912
+ case '\b':
99913
+ result += "\\b";
99914
+ break;
99915
+ case '\f':
99916
+ result += "\\f";
99917
+ break;
99918
+ case '\n':
99919
+ result += "\\n";
99920
+ break;
99921
+ case '\r':
99922
+ result += "\\r";
99923
+ break;
99924
+ case '\t':
99925
+ result += "\\t";
99926
+ break;
99927
+ case '"':
99928
+ result += "\\\"";
99929
+ break;
99930
+ case '\\':
99931
+ result += "\\\\";
99932
+ break;
99933
+ default:
99934
+ result += text[i];
99935
+ break;
99936
+ }
99937
+ }
99938
+ return result;
99939
+ }
99940
+
99876
99941
  // Print a row
99877
99942
  static void PrintRow(std::ostream &ss, const string &annotation, int id, const string &name, double time,
99878
- int sample_counter, int tuple_counter, string extra_info, int depth) {
99943
+ int sample_counter, int tuple_counter, const string &extra_info, int depth) {
99879
99944
  ss << string(depth * 3, ' ') << " {\n";
99880
- ss << string(depth * 3, ' ') << " \"annotation\": \"" + annotation + "\",\n";
99945
+ ss << string(depth * 3, ' ') << " \"annotation\": \"" + JSONSanitize(annotation) + "\",\n";
99881
99946
  ss << string(depth * 3, ' ') << " \"id\": " + to_string(id) + ",\n";
99882
- ss << string(depth * 3, ' ') << " \"name\": \"" + name + "\",\n";
99947
+ ss << string(depth * 3, ' ') << " \"name\": \"" + JSONSanitize(name) + "\",\n";
99883
99948
  #if defined(RDTSC)
99884
99949
  ss << string(depth * 3, ' ') << " \"timing\": \"NULL\" ,\n";
99885
99950
  ss << string(depth * 3, ' ') << " \"cycles_per_tuple\": " + StringUtil::Format("%.4f", time) + ",\n";
@@ -99889,8 +99954,7 @@ static void PrintRow(std::ostream &ss, const string &annotation, int id, const s
99889
99954
  #endif
99890
99955
  ss << string(depth * 3, ' ') << " \"sample_size\": " << to_string(sample_counter) + ",\n";
99891
99956
  ss << string(depth * 3, ' ') << " \"input_size\": " << to_string(tuple_counter) + ",\n";
99892
- ss << string(depth * 3, ' ') << " \"extra_info\": \""
99893
- << StringUtil::Replace(std::move(extra_info), "\n", "\\n") + "\"\n";
99957
+ ss << string(depth * 3, ' ') << " \"extra_info\": \"" << JSONSanitize(extra_info) + "\"\n";
99894
99958
  ss << string(depth * 3, ' ') << " },\n";
99895
99959
  }
99896
99960
 
@@ -99912,11 +99976,10 @@ static void ExtractFunctions(std::ostream &ss, ExpressionInfo &info, int &fun_id
99912
99976
 
99913
99977
  static void ToJSONRecursive(QueryProfiler::TreeNode &node, std::ostream &ss, int depth = 1) {
99914
99978
  ss << string(depth * 3, ' ') << " {\n";
99915
- ss << string(depth * 3, ' ') << " \"name\": \"" + node.name + "\",\n";
99979
+ ss << string(depth * 3, ' ') << " \"name\": \"" + JSONSanitize(node.name) + "\",\n";
99916
99980
  ss << string(depth * 3, ' ') << " \"timing\":" + to_string(node.info.time) + ",\n";
99917
99981
  ss << string(depth * 3, ' ') << " \"cardinality\":" + to_string(node.info.elements) + ",\n";
99918
- ss << string(depth * 3, ' ')
99919
- << " \"extra_info\": \"" + StringUtil::Replace(node.extra_info, "\n", "\\n") + "\",\n";
99982
+ ss << string(depth * 3, ' ') << " \"extra_info\": \"" + JSONSanitize(node.extra_info) + "\",\n";
99920
99983
  ss << string(depth * 3, ' ') << " \"timings\": [";
99921
99984
  int32_t function_counter = 1;
99922
99985
  int32_t expression_counter = 1;
@@ -99970,8 +100033,7 @@ string QueryProfiler::ToJSON() const {
99970
100033
  ss << " \"timing\": " + to_string(main_query.Elapsed()) + ",\n";
99971
100034
  ss << " \"cardinality\": " + to_string(root->info.elements) + ",\n";
99972
100035
  // JSON cannot have literal control characters in string literals
99973
- string extra_info = StringUtil::Replace(query, "\t", "\\t");
99974
- extra_info = StringUtil::Replace(extra_info, "\n", "\\n");
100036
+ string extra_info = JSONSanitize(query);
99975
100037
  ss << " \"extra-info\": \"" + extra_info + "\", \n";
99976
100038
  // print the phase timings
99977
100039
  ss << " \"timings\": [\n";
@@ -146502,7 +146564,7 @@ SingleFileBlockManager::SingleFileBlockManager(DatabaseInstance &db, string path
146502
146564
  flags = FileFlags::FILE_FLAGS_READ;
146503
146565
  lock = FileLockType::READ_LOCK;
146504
146566
  } else {
146505
- flags = FileFlags::FILE_FLAGS_WRITE;
146567
+ flags = FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_READ;
146506
146568
  lock = FileLockType::WRITE_LOCK;
146507
146569
  if (create_new) {
146508
146570
  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 "7dd852e1d"
14
- #define DUCKDB_VERSION "0.2.10-dev331"
13
+ #define DUCKDB_SOURCE_ID "f327c62f7"
14
+ #define DUCKDB_VERSION "0.2.10-dev343"
15
15
  //===----------------------------------------------------------------------===//
16
16
  // DuckDB
17
17
  //