duckdb 0.3.3-dev1397.0 → 0.3.3-dev1404.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-dev1397.0",
4
+ "version": "0.3.3-dev1404.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -71601,17 +71601,21 @@ void RadixPartitionedHashTable::GetData(ExecutionContext &context, DataChunk &ch
71601
71601
  // special case hack to sort out aggregating from empty intermediates
71602
71602
  // for aggregations without groups
71603
71603
  if (gstate.is_empty && grouping_set.empty()) {
71604
- D_ASSERT(chunk.ColumnCount() == op.aggregates.size());
71604
+ D_ASSERT(chunk.ColumnCount() == null_groups.size() + op.aggregates.size());
71605
71605
  // for each column in the aggregates, set to initial state
71606
71606
  chunk.SetCardinality(1);
71607
- for (idx_t i = 0; i < chunk.ColumnCount(); i++) {
71607
+ for (auto null_group : null_groups) {
71608
+ chunk.data[null_group].SetVectorType(VectorType::CONSTANT_VECTOR);
71609
+ ConstantVector::SetNull(chunk.data[null_group], true);
71610
+ }
71611
+ for (idx_t i = 0; i < op.aggregates.size(); i++) {
71608
71612
  D_ASSERT(op.aggregates[i]->GetExpressionClass() == ExpressionClass::BOUND_AGGREGATE);
71609
71613
  auto &aggr = (BoundAggregateExpression &)*op.aggregates[i];
71610
71614
  auto aggr_state = unique_ptr<data_t[]>(new data_t[aggr.function.state_size()]);
71611
71615
  aggr.function.initialize(aggr_state.get());
71612
71616
 
71613
71617
  Vector state_vector(Value::POINTER((uintptr_t)aggr_state.get()));
71614
- aggr.function.finalize(state_vector, aggr.bind_info.get(), chunk.data[i], 1, 0);
71618
+ aggr.function.finalize(state_vector, aggr.bind_info.get(), chunk.data[null_groups.size() + i], 1, 0);
71615
71619
  if (aggr.function.destructor) {
71616
71620
  aggr.function.destructor(state_vector, 1);
71617
71621
  }
@@ -84399,7 +84403,7 @@ char *StrfTimeFormat::Write2(char *target, uint8_t value) {
84399
84403
  }
84400
84404
 
84401
84405
  // write a value in the range of 0..99 padded to 2 digits
84402
- char *StrfTimeFormat::WritePadded2(char *target, int32_t value) {
84406
+ char *StrfTimeFormat::WritePadded2(char *target, uint32_t value) {
84403
84407
  D_ASSERT(value < 100);
84404
84408
  auto index = static_cast<unsigned>(value * 2);
84405
84409
  *target++ = duckdb_fmt::internal::data::digits[index];
@@ -84422,9 +84426,9 @@ char *StrfTimeFormat::WritePadded3(char *target, uint32_t value) {
84422
84426
  }
84423
84427
 
84424
84428
  // write a value in the range of 0..999999 padded to 6 digits
84425
- char *StrfTimeFormat::WritePadded(char *target, int32_t value, int32_t padding) {
84429
+ char *StrfTimeFormat::WritePadded(char *target, uint32_t value, size_t padding) {
84426
84430
  D_ASSERT(padding % 2 == 0);
84427
- for (int i = 0; i < padding / 2; i++) {
84431
+ for (size_t i = 0; i < padding / 2; i++) {
84428
84432
  int decimals = value % 100;
84429
84433
  WritePadded2(target + padding - 2 * (i + 1), decimals);
84430
84434
  value /= 100;
@@ -84599,6 +84603,7 @@ char *StrfTimeFormat::WriteStandardSpecifier(StrTimeSpecifier specifier, int32_t
84599
84603
  }
84600
84604
 
84601
84605
  void StrfTimeFormat::FormatString(date_t date, int32_t data[7], char *target) {
84606
+ D_ASSERT(specifiers.size() + 1 == literals.size());
84602
84607
  idx_t i;
84603
84608
  for (i = 0; i < specifiers.size(); i++) {
84604
84609
  // first copy the current literal
@@ -84819,12 +84824,12 @@ struct StrfTimeBindData : public FunctionData {
84819
84824
  template <bool REVERSED>
84820
84825
  static unique_ptr<FunctionData> StrfTimeBindFunction(ClientContext &context, ScalarFunction &bound_function,
84821
84826
  vector<unique_ptr<Expression>> &arguments) {
84822
- if (!arguments[1]->IsFoldable()) {
84827
+ if (!arguments[REVERSED ? 0 : 1]->IsFoldable()) {
84823
84828
  throw InvalidInputException("strftime format must be a constant");
84824
84829
  }
84825
84830
  Value options_str = ExpressionExecutor::EvaluateScalar(*arguments[REVERSED ? 0 : 1]);
84826
84831
  StrfTimeFormat format;
84827
- if (!options_str.IsNull() && options_str.type().id() == LogicalTypeId::VARCHAR) {
84832
+ if (!options_str.IsNull()) {
84828
84833
  auto format_string = options_str.GetValue<string>();
84829
84834
  string error = StrTimeFormat::ParseFormatSpecifier(format_string, format);
84830
84835
  if (!error.empty()) {
@@ -155791,6 +155796,7 @@ public:
155791
155796
 
155792
155797
 
155793
155798
 
155799
+
155794
155800
  namespace duckdb {
155795
155801
 
155796
155802
  SchemaCatalogEntry *Binder::BindSchema(CreateInfo &info) {
@@ -156005,10 +156011,18 @@ BoundStatement Binder::Bind(CreateStatement &stmt) {
156005
156011
  for (auto &keyname : fk.pk_columns) {
156006
156012
  auto entry = pk_table_entry_ptr->name_map.find(keyname);
156007
156013
  if (entry == pk_table_entry_ptr->name_map.end()) {
156008
- throw ParserException("column \"%s\" named in key does not exist", keyname);
156014
+ throw BinderException("column \"%s\" named in key does not exist", keyname);
156009
156015
  }
156010
156016
  fk.info.pk_keys.push_back(entry->second);
156011
156017
  }
156018
+ auto index = pk_table_entry_ptr->storage->info->indexes.FindForeignKeyIndex(
156019
+ fk.info.pk_keys, ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE);
156020
+ if (!index) {
156021
+ auto fk_column_names = StringUtil::Join(fk.pk_columns, ",");
156022
+ throw BinderException("Failed to create foreign key on %s(%s): no UNIQUE or PRIMARY KEY constraint "
156023
+ "present on these columns",
156024
+ pk_table_entry_ptr->name, fk_column_names);
156025
+ }
156012
156026
  }
156013
156027
  }
156014
156028
  // We first check if there are any user types, if yes we check to which custom types they refer.
@@ -156191,7 +156205,7 @@ static void BindConstraints(Binder &binder, BoundCreateTableInfo &info) {
156191
156205
  for (auto &keyname : fk.pk_columns) {
156192
156206
  auto entry = info.name_map.find(keyname);
156193
156207
  if (entry == info.name_map.end()) {
156194
- throw ParserException("column \"%s\" named in key does not exist", keyname);
156208
+ throw BinderException("column \"%s\" named in key does not exist", keyname);
156195
156209
  }
156196
156210
  fk.info.pk_keys.push_back(entry->second);
156197
156211
  }
@@ -156200,7 +156214,7 @@ static void BindConstraints(Binder &binder, BoundCreateTableInfo &info) {
156200
156214
  for (auto &keyname : fk.fk_columns) {
156201
156215
  auto entry = info.name_map.find(keyname);
156202
156216
  if (entry == info.name_map.end()) {
156203
- throw ParserException("column \"%s\" named in key does not exist", keyname);
156217
+ throw BinderException("column \"%s\" named in key does not exist", keyname);
156204
156218
  }
156205
156219
  fk.info.fk_keys.push_back(entry->second);
156206
156220
  }
@@ -170369,11 +170383,17 @@ static void VerifyCheckConstraint(TableCatalogEntry &table, Expression &expr, Da
170369
170383
  }
170370
170384
  }
170371
170385
 
170372
- static bool FindColumnIndex(const vector<idx_t> *keys_ptr, const vector<column_t> &index_column_ids) {
170373
- for (idx_t i = 0; i < keys_ptr->size(); i++) {
170386
+ static bool IsForeignKeyIndex(const vector<idx_t> &fk_keys, Index &index, ForeignKeyType fk_type) {
170387
+ if (fk_type == ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE ? !index.IsUnique() : !index.IsForeign()) {
170388
+ return false;
170389
+ }
170390
+ if (fk_keys.size() != index.column_ids.size()) {
170391
+ return false;
170392
+ }
170393
+ for (auto &fk_key : fk_keys) {
170374
170394
  bool is_found = false;
170375
- for (idx_t j = 0; j < index_column_ids.size(); j++) {
170376
- if ((*keys_ptr)[i] == index_column_ids[j]) {
170395
+ for (auto &index_key : index.column_ids) {
170396
+ if (fk_key == index_key) {
170377
170397
  is_found = true;
170378
170398
  break;
170379
170399
  }
@@ -170382,10 +170402,20 @@ static bool FindColumnIndex(const vector<idx_t> *keys_ptr, const vector<column_t
170382
170402
  return false;
170383
170403
  }
170384
170404
  }
170385
-
170386
170405
  return true;
170387
170406
  }
170388
170407
 
170408
+ Index *TableIndexList::FindForeignKeyIndex(const vector<idx_t> &fk_keys, ForeignKeyType fk_type) {
170409
+ Index *result = nullptr;
170410
+ Scan([&](Index &index) {
170411
+ if (IsForeignKeyIndex(fk_keys, index, fk_type)) {
170412
+ result = &index;
170413
+ }
170414
+ return false;
170415
+ });
170416
+ return result;
170417
+ }
170418
+
170389
170419
  static void VerifyForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, DataChunk &chunk,
170390
170420
  bool is_append) {
170391
170421
  const vector<idx_t> *src_keys_ptr = &bfk.info.fk_keys;
@@ -170424,26 +170454,24 @@ static void VerifyForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, Cli
170424
170454
  err_msgs.resize(count);
170425
170455
  tran_err_msgs.resize(count);
170426
170456
 
170457
+ auto fk_type = is_append ? ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE : ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE;
170427
170458
  // check whether or not the chunk can be inserted or deleted into the referenced table' storage
170428
- TableIndexList &table_indices = data_table->info->indexes;
170429
- table_indices.Scan([&](Index &index) {
170430
- if (FindColumnIndex(dst_keys_ptr, index.column_ids)) {
170431
- if (is_append) {
170432
- index.VerifyAppendForeignKey(dst_chunk, err_msgs.data());
170433
- } else {
170434
- index.VerifyDeleteForeignKey(dst_chunk, err_msgs.data());
170435
- }
170436
- }
170437
- return false;
170438
- });
170439
-
170459
+ auto index = data_table->info->indexes.FindForeignKeyIndex(*dst_keys_ptr, fk_type);
170460
+ if (!index) {
170461
+ throw InternalException("Internal Foreign Key error: could not find index to verify...");
170462
+ }
170463
+ if (is_append) {
170464
+ index->VerifyAppendForeignKey(dst_chunk, err_msgs.data());
170465
+ } else {
170466
+ index->VerifyDeleteForeignKey(dst_chunk, err_msgs.data());
170467
+ }
170440
170468
  // check whether or not the chunk can be inserted or deleted into the referenced table' transaction local storage
170441
170469
  auto &transaction = Transaction::GetTransaction(context);
170442
170470
  bool transaction_check = transaction.storage.Find(data_table);
170443
170471
  if (transaction_check) {
170444
170472
  vector<unique_ptr<Index>> &transact_index_vec = transaction.storage.GetIndexes(data_table);
170445
170473
  for (idx_t i = 0; i < transact_index_vec.size(); i++) {
170446
- if (FindColumnIndex(dst_keys_ptr, transact_index_vec[i]->column_ids)) {
170474
+ if (IsForeignKeyIndex(*dst_keys_ptr, *transact_index_vec[i], fk_type)) {
170447
170475
  if (is_append) {
170448
170476
  transact_index_vec[i]->VerifyAppendForeignKey(dst_chunk, tran_err_msgs.data());
170449
170477
  } else {
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 "c3ba7e5b0"
15
- #define DUCKDB_VERSION "v0.3.3-dev1397"
14
+ #define DUCKDB_SOURCE_ID "514748429"
15
+ #define DUCKDB_VERSION "v0.3.3-dev1404"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //
@@ -20947,6 +20947,8 @@ public:
20947
20947
  return indexes.size();
20948
20948
  }
20949
20949
 
20950
+ Index *FindForeignKeyIndex(const vector<idx_t> &fk_keys, ForeignKeyType fk_type);
20951
+
20950
20952
  private:
20951
20953
  //! Indexes associated with the current table
20952
20954
  mutex indexes_lock;
@@ -21905,9 +21907,9 @@ protected:
21905
21907
  static idx_t GetSpecifierLength(StrTimeSpecifier specifier, date_t date, dtime_t time);
21906
21908
  char *WriteString(char *target, const string_t &str);
21907
21909
  char *Write2(char *target, uint8_t value);
21908
- char *WritePadded2(char *target, int32_t value);
21910
+ char *WritePadded2(char *target, uint32_t value);
21909
21911
  char *WritePadded3(char *target, uint32_t value);
21910
- char *WritePadded(char *target, int32_t value, int32_t padding);
21912
+ char *WritePadded(char *target, uint32_t value, size_t padding);
21911
21913
  bool IsDateSpecifier(StrTimeSpecifier specifier);
21912
21914
  char *WriteDateSpecifier(StrTimeSpecifier specifier, date_t date, char *target);
21913
21915
  char *WriteStandardSpecifier(StrTimeSpecifier specifier, int32_t data[], char *target);