duckdb 0.3.3-dev392.0 → 0.3.3-dev449.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-dev392.0",
4
+ "version": "0.3.3-dev449.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);
@@ -69212,6 +69315,10 @@ struct VarianceFun {
69212
69315
  static void RegisterFunction(BuiltinFunctions &set);
69213
69316
  };
69214
69317
 
69318
+ struct StandardErrorOfTheMeanFun {
69319
+ static void RegisterFunction(BuiltinFunctions &set);
69320
+ };
69321
+
69215
69322
  } // namespace duckdb
69216
69323
 
69217
69324
  //===----------------------------------------------------------------------===//
@@ -69806,6 +69913,20 @@ struct STDDevPopOperation : public STDDevBaseOperation {
69806
69913
  }
69807
69914
  }
69808
69915
  };
69916
+
69917
+ struct StandardErrorOfTheMeanOperation : public STDDevBaseOperation {
69918
+ template <class T, class STATE>
69919
+ static void Finalize(Vector &result, FunctionData *, STATE *state, T *target, ValidityMask &mask, idx_t idx) {
69920
+ if (state->count == 0) {
69921
+ mask.SetInvalid(idx);
69922
+ } else {
69923
+ target[idx] = sqrt(state->dsquared / state->count) / sqrt((state->count));
69924
+ if (!Value::DoubleIsValid(target[idx])) {
69925
+ throw OutOfRangeException("SEM is out of range!");
69926
+ }
69927
+ }
69928
+ }
69929
+ };
69809
69930
  } // namespace duckdb
69810
69931
 
69811
69932
  //===----------------------------------------------------------------------===//
@@ -69967,6 +70088,13 @@ void VarianceFun::RegisterFunction(BuiltinFunctions &set) {
69967
70088
  set.AddFunction(var_samp);
69968
70089
  }
69969
70090
 
70091
+ void StandardErrorOfTheMeanFun::RegisterFunction(BuiltinFunctions &set) {
70092
+ AggregateFunctionSet sem("sem");
70093
+ sem.AddFunction(AggregateFunction::UnaryAggregate<StddevState, double, double, StandardErrorOfTheMeanOperation>(
70094
+ LogicalType::DOUBLE, LogicalType::DOUBLE));
70095
+ set.AddFunction(sem);
70096
+ }
70097
+
69970
70098
  } // namespace duckdb
69971
70099
 
69972
70100
 
@@ -69984,7 +70112,7 @@ void BuiltinFunctions::RegisterAlgebraicAggregates() {
69984
70112
  Register<VarPopFun>();
69985
70113
  Register<VarSampFun>();
69986
70114
  Register<VarianceFun>();
69987
-
70115
+ Register<StandardErrorOfTheMeanFun>();
69988
70116
  Register<Corr>();
69989
70117
  }
69990
70118
 
@@ -95093,10 +95221,11 @@ static unique_ptr<LocalFunctionData> WriteCSVInitializeLocal(ClientContext &cont
95093
95221
  return move(local_data);
95094
95222
  }
95095
95223
 
95096
- static unique_ptr<GlobalFunctionData> WriteCSVInitializeGlobal(ClientContext &context, FunctionData &bind_data) {
95224
+ static unique_ptr<GlobalFunctionData> WriteCSVInitializeGlobal(ClientContext &context, FunctionData &bind_data,
95225
+ const string &file_path) {
95097
95226
  auto &csv_data = (WriteCSVData &)bind_data;
95098
95227
  auto &options = csv_data.options;
95099
- auto global_data = make_unique<GlobalWriteCSVData>(FileSystem::GetFileSystem(context), csv_data.files[0],
95228
+ auto global_data = make_unique<GlobalWriteCSVData>(FileSystem::GetFileSystem(context), file_path,
95100
95229
  FileSystem::GetFileOpener(context), options.compression);
95101
95230
 
95102
95231
  if (options.header) {
@@ -95190,6 +95319,7 @@ static void WriteCSVCombine(ClientContext &context, FunctionData &bind_data, Glo
95190
95319
  //===--------------------------------------------------------------------===//
95191
95320
  void WriteCSVFinalize(ClientContext &context, FunctionData &bind_data, GlobalFunctionData &gstate) {
95192
95321
  auto &global_state = (GlobalWriteCSVData &)gstate;
95322
+
95193
95323
  global_state.handle->Close();
95194
95324
  global_state.handle.reset();
95195
95325
  }
@@ -100231,6 +100361,7 @@ void BaseAppender::Close() {
100231
100361
 
100232
100362
 
100233
100363
 
100364
+
100234
100365
  #include <cstring>
100235
100366
  #include <cassert>
100236
100367
 
@@ -100265,6 +100396,10 @@ duckdb_type ConvertCPPTypeToC(const LogicalType &type);
100265
100396
  idx_t GetCTypeSize(duckdb_type type);
100266
100397
  duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_result *out);
100267
100398
 
100399
+ struct DuckDBColumnData {
100400
+ LogicalType type;
100401
+ };
100402
+
100268
100403
  } // namespace duckdb
100269
100404
 
100270
100405
 
@@ -100810,6 +100945,8 @@ duckdb_type ConvertCPPTypeToC(const LogicalType &sql_type) {
100810
100945
  return DUCKDB_TYPE_BLOB;
100811
100946
  case LogicalTypeId::INTERVAL:
100812
100947
  return DUCKDB_TYPE_INTERVAL;
100948
+ case LogicalTypeId::DECIMAL:
100949
+ return DUCKDB_TYPE_DECIMAL;
100813
100950
  default: // LCOV_EXCL_START
100814
100951
  D_ASSERT(0);
100815
100952
  return DUCKDB_TYPE_INVALID;
@@ -100853,6 +100990,8 @@ idx_t GetCTypeSize(duckdb_type type) {
100853
100990
  return sizeof(duckdb_blob);
100854
100991
  case DUCKDB_TYPE_INTERVAL:
100855
100992
  return sizeof(duckdb_interval);
100993
+ case DUCKDB_TYPE_DECIMAL:
100994
+ return sizeof(duckdb_hugeint);
100856
100995
  default: // LCOV_EXCL_START
100857
100996
  // unsupported type
100858
100997
  D_ASSERT(0);
@@ -100872,6 +101011,8 @@ void duckdb_free(void *ptr) {
100872
101011
 
100873
101012
 
100874
101013
 
101014
+
101015
+
100875
101016
  using duckdb::Hugeint;
100876
101017
  using duckdb::hugeint_t;
100877
101018
  using duckdb::Value;
@@ -100896,6 +101037,15 @@ duckdb_hugeint duckdb_double_to_hugeint(double val) {
100896
101037
  return result;
100897
101038
  }
100898
101039
 
101040
+ double duckdb_decimal_to_double(duckdb_decimal val) {
101041
+ double result;
101042
+ hugeint_t value;
101043
+ value.lower = val.value.lower;
101044
+ value.upper = val.value.upper;
101045
+ duckdb::TryCastFromDecimal::Operation<hugeint_t, double>(value, result, nullptr, val.width, val.scale);
101046
+ return result;
101047
+ }
101048
+
100899
101049
 
100900
101050
 
100901
101051
 
@@ -101133,6 +101283,9 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
101133
101283
  // zero initialize the columns (so we can cleanly delete it in case a malloc fails)
101134
101284
  memset(out->__deprecated_columns, 0, sizeof(duckdb_column) * out->__deprecated_column_count);
101135
101285
  for (idx_t i = 0; i < out->__deprecated_column_count; i++) {
101286
+ auto column_data = new DuckDBColumnData();
101287
+ column_data->type = result->types[i];
101288
+ out->__deprecated_columns[i].internal_data = column_data;
101136
101289
  out->__deprecated_columns[i].__deprecated_type = ConvertCPPTypeToC(result->types[i]);
101137
101290
  out->__deprecated_columns[i].__deprecated_name = strdup(result->names[i].c_str());
101138
101291
  out->__deprecated_columns[i].__deprecated_nullmask =
@@ -101295,9 +101448,72 @@ duckdb_state duckdb_translate_result(MaterializedQueryResult *result, duckdb_res
101295
101448
  }
101296
101449
  break;
101297
101450
  }
101451
+ case LogicalTypeId::DECIMAL: {
101452
+ // get data
101453
+ idx_t row = 0;
101454
+ auto target = (hugeint_t *)out->__deprecated_columns[col].__deprecated_data;
101455
+ switch (result->types[col].InternalType()) {
101456
+ case PhysicalType::INT16: {
101457
+ for (auto &chunk : result->collection.Chunks()) {
101458
+ auto source = FlatVector::GetData<int16_t>(chunk->data[col]);
101459
+ for (idx_t k = 0; k < chunk->size(); k++) {
101460
+ if (!FlatVector::IsNull(chunk->data[col], k)) {
101461
+ target[row].lower = source[k];
101462
+ target[row].upper = 0;
101463
+ }
101464
+ row++;
101465
+ }
101466
+ }
101467
+ break;
101468
+ }
101469
+ case PhysicalType::INT32: {
101470
+ for (auto &chunk : result->collection.Chunks()) {
101471
+ auto source = FlatVector::GetData<int32_t>(chunk->data[col]);
101472
+ for (idx_t k = 0; k < chunk->size(); k++) {
101473
+ if (!FlatVector::IsNull(chunk->data[col], k)) {
101474
+ target[row].lower = source[k];
101475
+ target[row].upper = 0;
101476
+ }
101477
+ row++;
101478
+ }
101479
+ }
101480
+ break;
101481
+ }
101482
+ case PhysicalType::INT64: {
101483
+ for (auto &chunk : result->collection.Chunks()) {
101484
+ auto source = FlatVector::GetData<int64_t>(chunk->data[col]);
101485
+ for (idx_t k = 0; k < chunk->size(); k++) {
101486
+ if (!FlatVector::IsNull(chunk->data[col], k)) {
101487
+ target[row].lower = source[k];
101488
+ target[row].upper = 0;
101489
+ }
101490
+ row++;
101491
+ }
101492
+ }
101493
+ break;
101494
+ }
101495
+ case PhysicalType::INT128: {
101496
+ for (auto &chunk : result->collection.Chunks()) {
101497
+ auto source = FlatVector::GetData<hugeint_t>(chunk->data[col]);
101498
+ for (idx_t k = 0; k < chunk->size(); k++) {
101499
+ if (!FlatVector::IsNull(chunk->data[col], k)) {
101500
+ target[row].lower = source[k].lower;
101501
+ target[row].upper = source[k].upper;
101502
+ }
101503
+ row++;
101504
+ }
101505
+ }
101506
+ break;
101507
+ }
101508
+ default:
101509
+ throw std::runtime_error("Unsupported physical type for Decimal" +
101510
+ TypeIdToString(result->types[col].InternalType()));
101511
+ }
101512
+ break;
101513
+ }
101298
101514
  default: // LCOV_EXCL_START
101299
- // unsupported type for C API
101300
- D_ASSERT(0);
101515
+ std::string err_msg = "Unsupported type for C API: " + result->types[col].ToString();
101516
+ out->__deprecated_error_message = strdup(err_msg.c_str());
101301
101517
  return DuckDBError;
101302
101518
  } // LCOV_EXCL_STOP
101303
101519
  }
@@ -101333,6 +101549,10 @@ static void DuckdbDestroyColumn(duckdb_column column, idx_t count) {
101333
101549
  if (column.__deprecated_name) {
101334
101550
  duckdb_free(column.__deprecated_name);
101335
101551
  }
101552
+ if (column.internal_data) {
101553
+ auto column_data = (duckdb::DuckDBColumnData *)column.internal_data;
101554
+ delete column_data;
101555
+ }
101336
101556
  }
101337
101557
 
101338
101558
  void duckdb_destroy_result(duckdb_result *result) {
@@ -101547,7 +101767,12 @@ using duckdb::UnsafeFetch;
101547
101767
  template <class SOURCE_TYPE, class RESULT_TYPE, class OP>
101548
101768
  RESULT_TYPE TryCastCInternal(duckdb_result *result, idx_t col, idx_t row) {
101549
101769
  RESULT_TYPE result_value;
101550
- if (!OP::template Operation<SOURCE_TYPE, RESULT_TYPE>(UnsafeFetch<SOURCE_TYPE>(result, col, row), result_value)) {
101770
+ try {
101771
+ if (!OP::template Operation<SOURCE_TYPE, RESULT_TYPE>(UnsafeFetch<SOURCE_TYPE>(result, col, row),
101772
+ result_value)) {
101773
+ return FetchDefaultValue::Operation<RESULT_TYPE>();
101774
+ }
101775
+ } catch (...) {
101551
101776
  return FetchDefaultValue::Operation<RESULT_TYPE>();
101552
101777
  }
101553
101778
  return result_value;
@@ -101599,6 +101824,8 @@ static RESULT_TYPE GetInternalCValue(duckdb_result *result, idx_t col, idx_t row
101599
101824
  return TryCastCInternal<timestamp_t, RESULT_TYPE, OP>(result, col, row);
101600
101825
  case DUCKDB_TYPE_HUGEINT:
101601
101826
  return TryCastCInternal<hugeint_t, RESULT_TYPE, OP>(result, col, row);
101827
+ case DUCKDB_TYPE_DECIMAL:
101828
+ return TryCastCInternal<hugeint_t, RESULT_TYPE, OP>(result, col, row);
101602
101829
  case DUCKDB_TYPE_INTERVAL:
101603
101830
  return TryCastCInternal<interval_t, RESULT_TYPE, OP>(result, col, row);
101604
101831
  case DUCKDB_TYPE_VARCHAR:
@@ -101635,6 +101862,18 @@ int64_t duckdb_value_int64(duckdb_result *result, idx_t col, idx_t row) {
101635
101862
  return GetInternalCValue<int64_t>(result, col, row);
101636
101863
  }
101637
101864
 
101865
+ duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row) {
101866
+ duckdb_decimal result_value;
101867
+
101868
+ auto column_data = (duckdb::DuckDBColumnData *)result->__deprecated_columns[col].internal_data;
101869
+ column_data->type.GetDecimalProperties(result_value.width, result_value.scale);
101870
+
101871
+ auto internal_value = GetInternalCValue<hugeint_t>(result, col, row);
101872
+ result_value.value.lower = internal_value.lower;
101873
+ result_value.value.upper = internal_value.upper;
101874
+ return result_value;
101875
+ }
101876
+
101638
101877
  duckdb_hugeint duckdb_value_hugeint(duckdb_result *result, idx_t col, idx_t row) {
101639
101878
  duckdb_hugeint result_value;
101640
101879
  auto internal_value = GetInternalCValue<hugeint_t>(result, col, row);
@@ -101728,6 +101967,7 @@ bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row) {
101728
101967
  return result->__deprecated_columns[col].__deprecated_nullmask[row];
101729
101968
  }
101730
101969
 
101970
+
101731
101971
  //===----------------------------------------------------------------------===//
101732
101972
  // DuckDB
101733
101973
  //
@@ -150270,6 +150510,8 @@ BoundStatement Binder::Bind(CallStatement &stmt) {
150270
150510
 
150271
150511
 
150272
150512
 
150513
+
150514
+
150273
150515
  #include <algorithm>
150274
150516
 
150275
150517
  namespace duckdb {
@@ -150293,11 +150535,24 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
150293
150535
  if (!copy_function->function.copy_to_bind) {
150294
150536
  throw NotImplementedException("COPY TO is not supported for FORMAT \"%s\"", stmt.info->format);
150295
150537
  }
150296
-
150538
+ bool use_tmp_file = true;
150539
+ for (auto &option : stmt.info->options) {
150540
+ auto loption = StringUtil::Lower(option.first);
150541
+ if (loption == "use_tmp_file") {
150542
+ use_tmp_file = option.second[0].CastAs(LogicalType::BOOLEAN).GetValue<bool>();
150543
+ stmt.info->options.erase(option.first);
150544
+ break;
150545
+ }
150546
+ }
150297
150547
  auto function_data =
150298
150548
  copy_function->function.copy_to_bind(context, *stmt.info, select_node.names, select_node.types);
150299
150549
  // now create the copy information
150300
150550
  auto copy = make_unique<LogicalCopyToFile>(copy_function->function, move(function_data));
150551
+ copy->file_path = stmt.info->file_path;
150552
+ copy->use_tmp_file = use_tmp_file;
150553
+ LocalFileSystem fs;
150554
+ copy->is_file_and_exists = fs.FileExists(copy->file_path);
150555
+
150301
150556
  copy->AddChild(move(select_node.plan));
150302
150557
 
150303
150558
  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 "27c81ef25"
15
- #define DUCKDB_VERSION "v0.3.3-dev392"
14
+ #define DUCKDB_SOURCE_ID "1355f4f7a"
15
+ #define DUCKDB_VERSION "v0.3.3-dev449"
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
@@ -12069,7 +12070,9 @@ typedef enum DUCKDB_TYPE {
12069
12070
  // const char*
12070
12071
  DUCKDB_TYPE_VARCHAR,
12071
12072
  // duckdb_blob
12072
- DUCKDB_TYPE_BLOB
12073
+ DUCKDB_TYPE_BLOB,
12074
+ // decimal
12075
+ DUCKDB_TYPE_DECIMAL
12073
12076
  } duckdb_type;
12074
12077
 
12075
12078
  //! Days are stored as days since 1970-01-01
@@ -12122,6 +12125,13 @@ typedef struct {
12122
12125
  int64_t upper;
12123
12126
  } duckdb_hugeint;
12124
12127
 
12128
+ typedef struct {
12129
+ uint8_t width;
12130
+ uint8_t scale;
12131
+
12132
+ duckdb_hugeint value;
12133
+ } duckdb_decimal;
12134
+
12125
12135
  typedef struct {
12126
12136
  void *data;
12127
12137
  idx_t size;
@@ -12456,6 +12466,11 @@ DUCKDB_API int64_t duckdb_value_int64(duckdb_result *result, idx_t col, idx_t ro
12456
12466
  */
12457
12467
  DUCKDB_API duckdb_hugeint duckdb_value_hugeint(duckdb_result *result, idx_t col, idx_t row);
12458
12468
 
12469
+ /*!
12470
+ * returns: The duckdb_decimal value at the specified location, or 0 if the value cannot be converted.
12471
+ */
12472
+ DUCKDB_API duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row);
12473
+
12459
12474
  /*!
12460
12475
  * returns: The uint8_t value at the specified location, or 0 if the value cannot be converted.
12461
12476
  */
@@ -12622,6 +12637,17 @@ If the conversion fails because the double value is too big the result will be 0
12622
12637
  */
12623
12638
  DUCKDB_API duckdb_hugeint duckdb_double_to_hugeint(double val);
12624
12639
 
12640
+ //===--------------------------------------------------------------------===//
12641
+ // Decimal Helpers
12642
+ //===--------------------------------------------------------------------===//
12643
+ /*!
12644
+ Converts a duckdb_decimal object (as obtained from a `DUCKDB_TYPE_DECIMAL` column) into a double.
12645
+
12646
+ * val: The decimal value.
12647
+ * returns: The converted `double` element.
12648
+ */
12649
+ DUCKDB_API double duckdb_decimal_to_double(duckdb_decimal val);
12650
+
12625
12651
  //===--------------------------------------------------------------------===//
12626
12652
  // Prepared Statements
12627
12653
  //===--------------------------------------------------------------------===//
@@ -18076,7 +18102,8 @@ struct GlobalFunctionData {
18076
18102
  typedef unique_ptr<FunctionData> (*copy_to_bind_t)(ClientContext &context, CopyInfo &info, vector<string> &names,
18077
18103
  vector<LogicalType> &sql_types);
18078
18104
  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);
18105
+ typedef unique_ptr<GlobalFunctionData> (*copy_to_initialize_global_t)(ClientContext &context, FunctionData &bind_data,
18106
+ const string &file_path);
18080
18107
  typedef void (*copy_to_sink_t)(ClientContext &context, FunctionData &bind_data, GlobalFunctionData &gstate,
18081
18108
  LocalFunctionData &lstate, DataChunk &input);
18082
18109
  typedef void (*copy_to_combine_t)(ClientContext &context, FunctionData &bind_data, GlobalFunctionData &gstate,