duckdb 0.3.3-dev382.0 → 0.3.3-dev432.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.3-dev382.0",
4
+ "version": "0.3.3-dev432.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -13658,6 +13658,10 @@ bool FileSystem::FileExists(const string &filename) {
13658
13658
  throw NotImplementedException("%s: FileExists is not implemented!", GetName());
13659
13659
  }
13660
13660
 
13661
+ bool FileSystem::IsPipe(const string &filename) {
13662
+ throw NotImplementedException("%s: IsPipe is not implemented!", GetName());
13663
+ }
13664
+
13661
13665
  void FileSystem::RemoveFile(const string &filename) {
13662
13666
  throw NotImplementedException("%s: RemoveFile is not implemented!", GetName());
13663
13667
  }
@@ -15773,6 +15777,9 @@ public:
15773
15777
  void MoveFile(const string &source, const string &target) override;
15774
15778
  //! Check if a file exists
15775
15779
  bool FileExists(const string &filename) override;
15780
+
15781
+ //! Check if path is a pipe
15782
+ bool IsPipe(const string &filename) override;
15776
15783
  //! Remove a file from disk
15777
15784
  void RemoveFile(const string &filename) override;
15778
15785
  //! Sync a file handle to disk
@@ -15865,8 +15872,10 @@ public:
15865
15872
  } // namespace duckdb
15866
15873
 
15867
15874
  #include <string>
15875
+ #include <io.h>
15868
15876
 
15869
15877
  #ifdef __MINGW32__
15878
+ #include <sys/stat.h>
15870
15879
  // need to manually define this for mingw
15871
15880
  extern "C" WINBASEAPI BOOL WINAPI GetPhysicallyInstalledSystemMemory(PULONGLONG);
15872
15881
  #endif
@@ -15891,6 +15900,90 @@ static void AssertValidFileFlags(uint8_t flags) {
15891
15900
  #endif
15892
15901
  }
15893
15902
 
15903
+ #ifdef __MINGW32__
15904
+ bool LocalFileSystem::FileExists(const string &filename) {
15905
+ auto unicode_path = WindowsUtil::UTF8ToUnicode(filename.c_str());
15906
+ const wchar_t *wpath = unicode_path.c_str();
15907
+ if (_waccess(wpath, 0) == 0) {
15908
+ struct _stat64i32 status;
15909
+ _wstat(wpath, &status);
15910
+ if (status.st_size > 0) {
15911
+ return true;
15912
+ }
15913
+ }
15914
+ return false;
15915
+ }
15916
+ bool LocalFileSystem::IsPipe(const string &filename) {
15917
+ auto unicode_path = WindowsUtil::UTF8ToUnicode(filename.c_str());
15918
+ const wchar_t *wpath = unicode_path.c_str();
15919
+ if (_waccess(wpath, 0) == 0) {
15920
+ struct _stat64i32 status;
15921
+ _wstat(wpath, &status);
15922
+ if (status.st_size == 0) {
15923
+ return true;
15924
+ }
15925
+ }
15926
+ return false;
15927
+ }
15928
+
15929
+ #else
15930
+ #ifndef _WIN32
15931
+ bool LocalFileSystem::FileExists(const string &filename) {
15932
+ if (!filename.empty()) {
15933
+ if (access(filename.c_str(), 0) == 0) {
15934
+ struct stat status;
15935
+ stat(filename.c_str(), &status);
15936
+ if (S_ISREG(status.st_mode)) {
15937
+ return true;
15938
+ }
15939
+ }
15940
+ }
15941
+ // if any condition fails
15942
+ return false;
15943
+ }
15944
+
15945
+ bool LocalFileSystem::IsPipe(const string &filename) {
15946
+ if (!filename.empty()) {
15947
+ if (access(filename.c_str(), 0) == 0) {
15948
+ struct stat status;
15949
+ stat(filename.c_str(), &status);
15950
+ if (S_ISFIFO(status.st_mode)) {
15951
+ return true;
15952
+ }
15953
+ }
15954
+ }
15955
+ // if any condition fails
15956
+ return false;
15957
+ }
15958
+
15959
+ #else
15960
+ bool LocalFileSystem::FileExists(const string &filename) {
15961
+ auto unicode_path = WindowsUtil::UTF8ToUnicode(filename.c_str());
15962
+ const wchar_t *wpath = unicode_path.c_str();
15963
+ if (_waccess(wpath, 0) == 0) {
15964
+ struct _stat64i32 status;
15965
+ _wstat(wpath, &status);
15966
+ if (status.st_mode & S_IFREG) {
15967
+ return true;
15968
+ }
15969
+ }
15970
+ return false;
15971
+ }
15972
+ bool LocalFileSystem::IsPipe(const string &filename) {
15973
+ auto unicode_path = WindowsUtil::UTF8ToUnicode(filename.c_str());
15974
+ const wchar_t *wpath = unicode_path.c_str();
15975
+ if (_waccess(wpath, 0) == 0) {
15976
+ struct _stat64i32 status;
15977
+ _wstat(wpath, &status);
15978
+ if (status.st_mode & _S_IFCHR) {
15979
+ return true;
15980
+ }
15981
+ }
15982
+ return false;
15983
+ }
15984
+ #endif
15985
+ #endif
15986
+
15894
15987
  #ifndef _WIN32
15895
15988
  // somehow sometimes this is missing
15896
15989
  #ifndef O_CLOEXEC
@@ -16127,20 +16220,6 @@ bool LocalFileSystem::DirectoryExists(const string &directory) {
16127
16220
  return false;
16128
16221
  }
16129
16222
 
16130
- bool LocalFileSystem::FileExists(const string &filename) {
16131
- if (!filename.empty()) {
16132
- if (access(filename.c_str(), 0) == 0) {
16133
- struct stat status;
16134
- stat(filename.c_str(), &status);
16135
- if (!(status.st_mode & S_IFDIR)) {
16136
- return true;
16137
- }
16138
- }
16139
- }
16140
- // if any condition fails
16141
- return false;
16142
- }
16143
-
16144
16223
  void LocalFileSystem::CreateDirectory(const string &directory) {
16145
16224
  struct stat st;
16146
16225
 
@@ -16479,11 +16558,6 @@ bool LocalFileSystem::DirectoryExists(const string &directory) {
16479
16558
  return (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY));
16480
16559
  }
16481
16560
 
16482
- bool LocalFileSystem::FileExists(const string &filename) {
16483
- DWORD attrs = WindowsGetFileAttributes(filename);
16484
- return (attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY));
16485
- }
16486
-
16487
16561
  void LocalFileSystem::CreateDirectory(const string &directory) {
16488
16562
  if (DirectoryExists(directory)) {
16489
16563
  return;
@@ -16642,9 +16716,9 @@ vector<string> LocalFileSystem::Glob(const string &path) {
16642
16716
  }
16643
16717
  // first check if the path has a glob at all
16644
16718
  if (!HasGlob(path)) {
16645
- // no glob: return only the file (if it exists)
16719
+ // no glob: return only the file (if it exists or is a pipe)
16646
16720
  vector<string> result;
16647
- if (FileExists(path)) {
16721
+ if (FileExists(path) || IsPipe(path)) {
16648
16722
  result.push_back(path);
16649
16723
  }
16650
16724
  return result;
@@ -45465,6 +45539,9 @@ public:
45465
45539
  return FindFileSystem(filename)->FileExists(filename);
45466
45540
  }
45467
45541
 
45542
+ bool IsPipe(const string &filename) override {
45543
+ return FindFileSystem(filename)->IsPipe(filename);
45544
+ }
45468
45545
  virtual void RemoveFile(const string &filename) override {
45469
45546
  FindFileSystem(filename)->RemoveFile(filename);
45470
45547
  }
@@ -61229,6 +61306,8 @@ public:
61229
61306
 
61230
61307
  CopyFunction function;
61231
61308
  unique_ptr<FunctionData> bind_data;
61309
+ string file_path;
61310
+ bool use_tmp_file;
61232
61311
 
61233
61312
  public:
61234
61313
  // Source interface
@@ -61254,6 +61333,7 @@ public:
61254
61333
 
61255
61334
 
61256
61335
 
61336
+
61257
61337
  #include <algorithm>
61258
61338
 
61259
61339
  namespace duckdb {
@@ -61278,6 +61358,15 @@ public:
61278
61358
  //===--------------------------------------------------------------------===//
61279
61359
  // Sink
61280
61360
  //===--------------------------------------------------------------------===//
61361
+ void MoveTmpFile(ClientContext &context, const string &tmp_file_path) {
61362
+ auto &fs = FileSystem::GetFileSystem(context);
61363
+ auto file_path = tmp_file_path.substr(0, tmp_file_path.length() - 4);
61364
+ if (fs.FileExists(file_path)) {
61365
+ fs.RemoveFile(file_path);
61366
+ }
61367
+ fs.MoveFile(tmp_file_path, file_path);
61368
+ }
61369
+
61281
61370
  PhysicalCopyToFile::PhysicalCopyToFile(vector<LogicalType> types, CopyFunction function_p,
61282
61371
  unique_ptr<FunctionData> bind_data, idx_t estimated_cardinality)
61283
61372
  : PhysicalOperator(PhysicalOperatorType::COPY_TO_FILE, move(types), estimated_cardinality),
@@ -61308,6 +61397,10 @@ SinkFinalizeType PhysicalCopyToFile::Finalize(Pipeline &pipeline, Event &event,
61308
61397
  auto &gstate = (CopyToFunctionGlobalState &)gstate_p;
61309
61398
  if (function.copy_to_finalize) {
61310
61399
  function.copy_to_finalize(context, *bind_data, *gstate.global_state);
61400
+
61401
+ if (use_tmp_file) {
61402
+ MoveTmpFile(context, file_path);
61403
+ }
61311
61404
  }
61312
61405
  return SinkFinalizeType::READY;
61313
61406
  }
@@ -61316,7 +61409,7 @@ unique_ptr<LocalSinkState> PhysicalCopyToFile::GetLocalSinkState(ExecutionContex
61316
61409
  return make_unique<CopyToFunctionLocalState>(function.copy_to_initialize_local(context.client, *bind_data));
61317
61410
  }
61318
61411
  unique_ptr<GlobalSinkState> PhysicalCopyToFile::GetGlobalSinkState(ClientContext &context) const {
61319
- return make_unique<CopyToFunctionGlobalState>(function.copy_to_initialize_global(context, *bind_data));
61412
+ return make_unique<CopyToFunctionGlobalState>(function.copy_to_initialize_global(context, *bind_data, file_path));
61320
61413
  }
61321
61414
 
61322
61415
  //===--------------------------------------------------------------------===//
@@ -65351,6 +65444,7 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalComparison
65351
65444
 
65352
65445
 
65353
65446
 
65447
+
65354
65448
  namespace duckdb {
65355
65449
 
65356
65450
  class LogicalCopyToFile : public LogicalOperator {
@@ -65360,6 +65454,9 @@ public:
65360
65454
  }
65361
65455
  CopyFunction function;
65362
65456
  unique_ptr<FunctionData> bind_data;
65457
+ std::string file_path;
65458
+ bool use_tmp_file;
65459
+ bool is_file_and_exists;
65363
65460
 
65364
65461
  protected:
65365
65462
  void ResolveTypes() override {
@@ -65373,8 +65470,14 @@ namespace duckdb {
65373
65470
 
65374
65471
  unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCopyToFile &op) {
65375
65472
  auto plan = CreatePlan(*op.children[0]);
65473
+ bool use_tmp_file = op.is_file_and_exists && op.use_tmp_file;
65474
+ if (use_tmp_file) {
65475
+ op.file_path += ".tmp";
65476
+ }
65376
65477
  // COPY from select statement to file
65377
65478
  auto copy = make_unique<PhysicalCopyToFile>(op.types, op.function, move(op.bind_data), op.estimated_cardinality);
65479
+ copy->file_path = op.file_path;
65480
+ copy->use_tmp_file = use_tmp_file;
65378
65481
 
65379
65482
  copy->children.push_back(move(plan));
65380
65483
  return move(copy);
@@ -95093,10 +95196,11 @@ static unique_ptr<LocalFunctionData> WriteCSVInitializeLocal(ClientContext &cont
95093
95196
  return move(local_data);
95094
95197
  }
95095
95198
 
95096
- static unique_ptr<GlobalFunctionData> WriteCSVInitializeGlobal(ClientContext &context, FunctionData &bind_data) {
95199
+ static unique_ptr<GlobalFunctionData> WriteCSVInitializeGlobal(ClientContext &context, FunctionData &bind_data,
95200
+ const string &file_path) {
95097
95201
  auto &csv_data = (WriteCSVData &)bind_data;
95098
95202
  auto &options = csv_data.options;
95099
- auto global_data = make_unique<GlobalWriteCSVData>(FileSystem::GetFileSystem(context), csv_data.files[0],
95203
+ auto global_data = make_unique<GlobalWriteCSVData>(FileSystem::GetFileSystem(context), file_path,
95100
95204
  FileSystem::GetFileOpener(context), options.compression);
95101
95205
 
95102
95206
  if (options.header) {
@@ -95190,6 +95294,7 @@ static void WriteCSVCombine(ClientContext &context, FunctionData &bind_data, Glo
95190
95294
  //===--------------------------------------------------------------------===//
95191
95295
  void WriteCSVFinalize(ClientContext &context, FunctionData &bind_data, GlobalFunctionData &gstate) {
95192
95296
  auto &global_state = (GlobalWriteCSVData &)gstate;
95297
+
95193
95298
  global_state.handle->Close();
95194
95299
  global_state.handle.reset();
95195
95300
  }
@@ -114098,6 +114203,9 @@ bool QueryResult::Equals(QueryResult &other) { // LCOV_EXCL_START
114098
114203
  for (idx_t row = 0; row < rchunk->size(); row++) {
114099
114204
  auto lvalue = lchunk->GetValue(col, row);
114100
114205
  auto rvalue = rchunk->GetValue(col, row);
114206
+ if (lvalue.IsNull() && rvalue.IsNull()) {
114207
+ continue;
114208
+ }
114101
114209
  if (lvalue != rvalue) {
114102
114210
  return false;
114103
114211
  }
@@ -115597,7 +115705,7 @@ string ProjectionRelation::ToString(idx_t depth) {
115597
115705
  if (i != 0) {
115598
115706
  str += ", ";
115599
115707
  }
115600
- str += expressions[i]->ToString();
115708
+ str += expressions[i]->ToString() + " as " + expressions[i]->alias;
115601
115709
  }
115602
115710
  str += "]\n";
115603
115711
  return str + child->ToString(depth + 1);
@@ -150267,6 +150375,8 @@ BoundStatement Binder::Bind(CallStatement &stmt) {
150267
150375
 
150268
150376
 
150269
150377
 
150378
+
150379
+
150270
150380
  #include <algorithm>
150271
150381
 
150272
150382
  namespace duckdb {
@@ -150290,11 +150400,24 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
150290
150400
  if (!copy_function->function.copy_to_bind) {
150291
150401
  throw NotImplementedException("COPY TO is not supported for FORMAT \"%s\"", stmt.info->format);
150292
150402
  }
150293
-
150403
+ bool use_tmp_file = true;
150404
+ for (auto &option : stmt.info->options) {
150405
+ auto loption = StringUtil::Lower(option.first);
150406
+ if (loption == "use_tmp_file") {
150407
+ use_tmp_file = option.second[0].CastAs(LogicalType::BOOLEAN).GetValue<bool>();
150408
+ stmt.info->options.erase(option.first);
150409
+ break;
150410
+ }
150411
+ }
150294
150412
  auto function_data =
150295
150413
  copy_function->function.copy_to_bind(context, *stmt.info, select_node.names, select_node.types);
150296
150414
  // now create the copy information
150297
150415
  auto copy = make_unique<LogicalCopyToFile>(copy_function->function, move(function_data));
150416
+ copy->file_path = stmt.info->file_path;
150417
+ copy->use_tmp_file = use_tmp_file;
150418
+ LocalFileSystem fs;
150419
+ copy->is_file_and_exists = fs.FileExists(copy->file_path);
150420
+
150298
150421
  copy->AddChild(move(select_node.plan));
150299
150422
 
150300
150423
  result.plan = move(copy);
package/src/duckdb.hpp CHANGED
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
11
11
  #pragma once
12
12
  #define DUCKDB_AMALGAMATION 1
13
13
  #define DUCKDB_AMALGAMATION_EXTENDED 1
14
- #define DUCKDB_SOURCE_ID "452c18973"
15
- #define DUCKDB_VERSION "v0.3.3-dev382"
14
+ #define DUCKDB_SOURCE_ID "851e8cfd3"
15
+ #define DUCKDB_VERSION "v0.3.3-dev432"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //
@@ -1930,11 +1930,12 @@ public:
1930
1930
  DUCKDB_API virtual void MoveFile(const string &source, const string &target);
1931
1931
  //! Check if a file exists
1932
1932
  DUCKDB_API virtual bool FileExists(const string &filename);
1933
+ //! Check if path is pipe
1934
+ DUCKDB_API virtual bool IsPipe(const string &filename);
1933
1935
  //! Remove a file from disk
1934
1936
  DUCKDB_API virtual void RemoveFile(const string &filename);
1935
1937
  //! Sync a file handle to disk
1936
1938
  DUCKDB_API virtual void FileSync(FileHandle &handle);
1937
-
1938
1939
  //! Sets the working directory
1939
1940
  DUCKDB_API static void SetWorkingDirectory(const string &path);
1940
1941
  //! Gets the working directory
@@ -8710,7 +8711,7 @@ public:
8710
8711
  virtual string GetName() const;
8711
8712
  virtual string ParamsToString() const;
8712
8713
  virtual string ToString() const;
8713
- void Print();
8714
+ DUCKDB_API void Print();
8714
8715
  //! Debug method: verify that the integrity of expressions & child nodes are maintained
8715
8716
  virtual void Verify();
8716
8717
 
@@ -18076,7 +18077,8 @@ struct GlobalFunctionData {
18076
18077
  typedef unique_ptr<FunctionData> (*copy_to_bind_t)(ClientContext &context, CopyInfo &info, vector<string> &names,
18077
18078
  vector<LogicalType> &sql_types);
18078
18079
  typedef unique_ptr<LocalFunctionData> (*copy_to_initialize_local_t)(ClientContext &context, FunctionData &bind_data);
18079
- typedef unique_ptr<GlobalFunctionData> (*copy_to_initialize_global_t)(ClientContext &context, FunctionData &bind_data);
18080
+ typedef unique_ptr<GlobalFunctionData> (*copy_to_initialize_global_t)(ClientContext &context, FunctionData &bind_data,
18081
+ const string &file_path);
18080
18082
  typedef void (*copy_to_sink_t)(ClientContext &context, FunctionData &bind_data, GlobalFunctionData &gstate,
18081
18083
  LocalFunctionData &lstate, DataChunk &input);
18082
18084
  typedef void (*copy_to_combine_t)(ClientContext &context, FunctionData &bind_data, GlobalFunctionData &gstate,