duckdb 0.5.2-dev484.0 → 0.5.2-dev492.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.5.2-dev484.0",
4
+ "version": "0.5.2-dev492.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -47073,11 +47073,21 @@ hugeint_t ModuloOperator::Operation(hugeint_t left, hugeint_t right);
47073
47073
 
47074
47074
  namespace duckdb {
47075
47075
  struct MapCastInfo;
47076
+ struct MapCastNode;
47076
47077
 
47077
47078
  typedef BoundCastInfo (*bind_cast_function_t)(BindCastInput &input, const LogicalType &source,
47078
47079
  const LogicalType &target);
47079
47080
  typedef int64_t (*implicit_cast_cost_t)(const LogicalType &from, const LogicalType &to);
47080
47081
 
47082
+ struct GetCastFunctionInput {
47083
+ GetCastFunctionInput(ClientContext *context = nullptr) : context(context) {
47084
+ }
47085
+ GetCastFunctionInput(ClientContext &context) : context(&context) {
47086
+ }
47087
+
47088
+ ClientContext *context;
47089
+ };
47090
+
47081
47091
  struct BindCastFunction {
47082
47092
  BindCastFunction(bind_cast_function_t function,
47083
47093
  unique_ptr<BindCastInfo> info = nullptr); // NOLINT: allow implicit cast
@@ -47096,18 +47106,24 @@ public:
47096
47106
 
47097
47107
  //! Returns a cast function (from source -> target)
47098
47108
  //! Note that this always returns a function - since a cast is ALWAYS possible if the value is NULL
47099
- DUCKDB_API BoundCastInfo GetCastFunction(const LogicalType &source, const LogicalType &target);
47109
+ DUCKDB_API BoundCastInfo GetCastFunction(const LogicalType &source, const LogicalType &target,
47110
+ GetCastFunctionInput &input);
47100
47111
  //! Returns the implicit cast cost of casting from source -> target
47101
47112
  //! -1 means an implicit cast is not possible
47102
47113
  DUCKDB_API int64_t ImplicitCastCost(const LogicalType &source, const LogicalType &target);
47103
47114
  //! Register a new cast function from source to target
47104
47115
  DUCKDB_API void RegisterCastFunction(const LogicalType &source, const LogicalType &target, BoundCastInfo function,
47105
47116
  int64_t implicit_cast_cost = -1);
47117
+ DUCKDB_API void RegisterCastFunction(const LogicalType &source, const LogicalType &target,
47118
+ bind_cast_function_t bind, int64_t implicit_cast_cost = -1);
47106
47119
 
47107
47120
  private:
47108
47121
  vector<BindCastFunction> bind_functions;
47109
47122
  //! If any custom cast functions have been defined using RegisterCastFunction, this holds the map
47110
47123
  MapCastInfo *map_info;
47124
+
47125
+ private:
47126
+ void RegisterCastFunction(const LogicalType &source, const LogicalType &target, MapCastNode node);
47111
47127
  };
47112
47128
 
47113
47129
  } // namespace duckdb
@@ -48559,15 +48575,15 @@ bool Value::operator>=(const int64_t &rhs) const {
48559
48575
  return *this >= Value::Numeric(type_, rhs);
48560
48576
  }
48561
48577
 
48562
- bool Value::TryCastAs(CastFunctionSet &set, const LogicalType &target_type, Value &new_value, string *error_message,
48563
- bool strict) const {
48578
+ bool Value::TryCastAs(CastFunctionSet &set, GetCastFunctionInput &get_input, const LogicalType &target_type,
48579
+ Value &new_value, string *error_message, bool strict) const {
48564
48580
  if (type_ == target_type) {
48565
48581
  new_value = Copy();
48566
48582
  return true;
48567
48583
  }
48568
48584
  Vector input(*this);
48569
48585
  Vector result(target_type);
48570
- if (!VectorOperations::TryCast(set, input, result, 1, error_message, strict)) {
48586
+ if (!VectorOperations::TryCast(set, get_input, input, result, 1, error_message, strict)) {
48571
48587
  return false;
48572
48588
  }
48573
48589
  new_value = result.GetValue(0);
@@ -48576,37 +48592,43 @@ bool Value::TryCastAs(CastFunctionSet &set, const LogicalType &target_type, Valu
48576
48592
 
48577
48593
  bool Value::TryCastAs(ClientContext &context, const LogicalType &target_type, Value &new_value, string *error_message,
48578
48594
  bool strict) const {
48579
- return TryCastAs(CastFunctionSet::Get(context), target_type, new_value, error_message, strict);
48595
+ GetCastFunctionInput get_input(context);
48596
+ return TryCastAs(CastFunctionSet::Get(context), get_input, target_type, new_value, error_message, strict);
48580
48597
  }
48581
48598
 
48582
48599
  bool Value::DefaultTryCastAs(const LogicalType &target_type, Value &new_value, string *error_message,
48583
48600
  bool strict) const {
48584
48601
  CastFunctionSet set;
48585
- return TryCastAs(set, target_type, new_value, error_message, strict);
48602
+ GetCastFunctionInput get_input;
48603
+ return TryCastAs(set, get_input, target_type, new_value, error_message, strict);
48586
48604
  }
48587
48605
 
48588
- Value Value::CastAs(CastFunctionSet &set, const LogicalType &target_type, bool strict) const {
48606
+ Value Value::CastAs(CastFunctionSet &set, GetCastFunctionInput &get_input, const LogicalType &target_type,
48607
+ bool strict) const {
48589
48608
  Value new_value;
48590
48609
  string error_message;
48591
- if (!TryCastAs(set, target_type, new_value, &error_message, strict)) {
48610
+ if (!TryCastAs(set, get_input, target_type, new_value, &error_message, strict)) {
48592
48611
  throw InvalidInputException("Failed to cast value: %s", error_message);
48593
48612
  }
48594
48613
  return new_value;
48595
48614
  }
48596
48615
 
48597
48616
  Value Value::CastAs(ClientContext &context, const LogicalType &target_type, bool strict) const {
48598
- return CastAs(CastFunctionSet::Get(context), target_type, strict);
48617
+ GetCastFunctionInput get_input(context);
48618
+ return CastAs(CastFunctionSet::Get(context), get_input, target_type, strict);
48599
48619
  }
48600
48620
 
48601
48621
  Value Value::DefaultCastAs(const LogicalType &target_type, bool strict) const {
48602
48622
  CastFunctionSet set;
48603
- return CastAs(set, target_type, strict);
48623
+ GetCastFunctionInput get_input;
48624
+ return CastAs(set, get_input, target_type, strict);
48604
48625
  }
48605
48626
 
48606
- bool Value::TryCastAs(CastFunctionSet &set, const LogicalType &target_type, bool strict) {
48627
+ bool Value::TryCastAs(CastFunctionSet &set, GetCastFunctionInput &get_input, const LogicalType &target_type,
48628
+ bool strict) {
48607
48629
  Value new_value;
48608
48630
  string error_message;
48609
- if (!TryCastAs(set, target_type, new_value, &error_message, strict)) {
48631
+ if (!TryCastAs(set, get_input, target_type, new_value, &error_message, strict)) {
48610
48632
  return false;
48611
48633
  }
48612
48634
  type_ = target_type;
@@ -48619,12 +48641,14 @@ bool Value::TryCastAs(CastFunctionSet &set, const LogicalType &target_type, bool
48619
48641
  }
48620
48642
 
48621
48643
  bool Value::TryCastAs(ClientContext &context, const LogicalType &target_type, bool strict) {
48622
- return TryCastAs(CastFunctionSet::Get(context), target_type, strict);
48644
+ GetCastFunctionInput get_input(context);
48645
+ return TryCastAs(CastFunctionSet::Get(context), get_input, target_type, strict);
48623
48646
  }
48624
48647
 
48625
48648
  bool Value::DefaultTryCastAs(const LogicalType &target_type, bool strict) {
48626
48649
  CastFunctionSet set;
48627
- return TryCastAs(set, target_type, strict);
48650
+ GetCastFunctionInput get_input;
48651
+ return TryCastAs(set, get_input, target_type, strict);
48628
48652
  }
48629
48653
 
48630
48654
  void Value::Serialize(Serializer &main_serializer) const {
@@ -48759,7 +48783,8 @@ bool Value::NotDistinctFrom(const Value &lvalue, const Value &rvalue) {
48759
48783
  return ValueOperations::NotDistinctFrom(lvalue, rvalue);
48760
48784
  }
48761
48785
 
48762
- bool Value::ValuesAreEqual(CastFunctionSet &set, const Value &result_value, const Value &value) {
48786
+ bool Value::ValuesAreEqual(CastFunctionSet &set, GetCastFunctionInput &get_input, const Value &result_value,
48787
+ const Value &value) {
48763
48788
  if (result_value.IsNull() != value.IsNull()) {
48764
48789
  return false;
48765
48790
  }
@@ -48769,19 +48794,19 @@ bool Value::ValuesAreEqual(CastFunctionSet &set, const Value &result_value, cons
48769
48794
  }
48770
48795
  switch (value.type_.id()) {
48771
48796
  case LogicalTypeId::FLOAT: {
48772
- auto other = result_value.CastAs(set, LogicalType::FLOAT);
48797
+ auto other = result_value.CastAs(set, get_input, LogicalType::FLOAT);
48773
48798
  float ldecimal = value.value_.float_;
48774
48799
  float rdecimal = other.value_.float_;
48775
48800
  return ApproxEqual(ldecimal, rdecimal);
48776
48801
  }
48777
48802
  case LogicalTypeId::DOUBLE: {
48778
- auto other = result_value.CastAs(set, LogicalType::DOUBLE);
48803
+ auto other = result_value.CastAs(set, get_input, LogicalType::DOUBLE);
48779
48804
  double ldecimal = value.value_.double_;
48780
48805
  double rdecimal = other.value_.double_;
48781
48806
  return ApproxEqual(ldecimal, rdecimal);
48782
48807
  }
48783
48808
  case LogicalTypeId::VARCHAR: {
48784
- auto other = result_value.CastAs(set, LogicalType::VARCHAR);
48809
+ auto other = result_value.CastAs(set, get_input, LogicalType::VARCHAR);
48785
48810
  // some results might contain padding spaces, e.g. when rendering
48786
48811
  // VARCHAR(10) and the string only has 6 characters, they will be padded
48787
48812
  // with spaces to 10 in the rendering. We don't do that here yet as we
@@ -48795,18 +48820,20 @@ bool Value::ValuesAreEqual(CastFunctionSet &set, const Value &result_value, cons
48795
48820
  }
48796
48821
  default:
48797
48822
  if (result_value.type_.id() == LogicalTypeId::FLOAT || result_value.type_.id() == LogicalTypeId::DOUBLE) {
48798
- return Value::ValuesAreEqual(set, value, result_value);
48823
+ return Value::ValuesAreEqual(set, get_input, value, result_value);
48799
48824
  }
48800
48825
  return value == result_value;
48801
48826
  }
48802
48827
  }
48803
48828
 
48804
48829
  bool Value::ValuesAreEqual(ClientContext &context, const Value &result_value, const Value &value) {
48805
- return Value::ValuesAreEqual(CastFunctionSet::Get(context), result_value, value);
48830
+ GetCastFunctionInput get_input(context);
48831
+ return Value::ValuesAreEqual(CastFunctionSet::Get(context), get_input, result_value, value);
48806
48832
  }
48807
48833
  bool Value::DefaultValuesAreEqual(const Value &result_value, const Value &value) {
48808
48834
  CastFunctionSet set;
48809
- return Value::ValuesAreEqual(set, result_value, value);
48835
+ GetCastFunctionInput get_input;
48836
+ return Value::ValuesAreEqual(set, get_input, result_value, value);
48810
48837
  }
48811
48838
 
48812
48839
  } // namespace duckdb
@@ -54410,16 +54437,17 @@ void VectorOperations::AddInPlace(Vector &input, int64_t right, idx_t count) {
54410
54437
 
54411
54438
  namespace duckdb {
54412
54439
 
54413
- bool VectorOperations::TryCast(CastFunctionSet &set, Vector &source, Vector &result, idx_t count, string *error_message,
54414
- bool strict) {
54415
- auto cast_function = set.GetCastFunction(source.GetType(), result.GetType());
54440
+ bool VectorOperations::TryCast(CastFunctionSet &set, GetCastFunctionInput &input, Vector &source, Vector &result,
54441
+ idx_t count, string *error_message, bool strict) {
54442
+ auto cast_function = set.GetCastFunction(source.GetType(), result.GetType(), input);
54416
54443
  CastParameters parameters(cast_function.cast_data.get(), strict, error_message);
54417
54444
  return cast_function.function(source, result, count, parameters);
54418
54445
  }
54419
54446
 
54420
54447
  bool VectorOperations::DefaultTryCast(Vector &source, Vector &result, idx_t count, string *error_message, bool strict) {
54421
54448
  CastFunctionSet set;
54422
- return VectorOperations::TryCast(set, source, result, count, error_message, strict);
54449
+ GetCastFunctionInput input;
54450
+ return VectorOperations::TryCast(set, input, source, result, count, error_message, strict);
54423
54451
  }
54424
54452
 
54425
54453
  void VectorOperations::DefaultCast(Vector &source, Vector &result, idx_t count, bool strict) {
@@ -54430,7 +54458,8 @@ bool VectorOperations::TryCast(ClientContext &context, Vector &source, Vector &r
54430
54458
  string *error_message, bool strict) {
54431
54459
  auto &config = DBConfig::GetConfig(context);
54432
54460
  auto &set = config.GetCastFunctions();
54433
- return VectorOperations::TryCast(set, source, result, count, error_message, strict);
54461
+ GetCastFunctionInput get_input(context);
54462
+ return VectorOperations::TryCast(set, get_input, source, result, count, error_message, strict);
54434
54463
  }
54435
54464
 
54436
54465
  void VectorOperations::Cast(ClientContext &context, Vector &source, Vector &result, idx_t count, bool strict) {
@@ -76716,6 +76745,7 @@ bool BufferedCSVReader::TryParseComplexCSV(DataChunk &insert_chunk, string &erro
76716
76745
  bool finished_chunk = false;
76717
76746
  idx_t column = 0;
76718
76747
  vector<idx_t> escape_positions;
76748
+ bool has_quotes = false;
76719
76749
  uint8_t delimiter_pos = 0, escape_pos = 0, quote_pos = 0;
76720
76750
  idx_t offset = 0;
76721
76751
 
@@ -76778,9 +76808,10 @@ normal:
76778
76808
  } while (ReadBuffer(start));
76779
76809
  goto final_state;
76780
76810
  add_value:
76781
- AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
76811
+ AddValue(buffer.get() + start, position - start - offset, column, escape_positions, has_quotes);
76782
76812
  // increase position by 1 and move start to the new position
76783
76813
  offset = 0;
76814
+ has_quotes = false;
76784
76815
  start = ++position;
76785
76816
  if (position >= buffer_size && !ReadBuffer(start)) {
76786
76817
  // file ends right after delimiter, go to final state
@@ -76790,10 +76821,11 @@ add_value:
76790
76821
  add_row : {
76791
76822
  // check type of newline (\r or \n)
76792
76823
  bool carriage_return = buffer[position] == '\r';
76793
- AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
76824
+ AddValue(buffer.get() + start, position - start - offset, column, escape_positions, has_quotes);
76794
76825
  finished_chunk = AddRow(insert_chunk, column);
76795
76826
  // increase position by 1 and move start to the new position
76796
76827
  offset = 0;
76828
+ has_quotes = false;
76797
76829
  start = ++position;
76798
76830
  if (position >= buffer_size && !ReadBuffer(start)) {
76799
76831
  // file ends right after newline, go to final state
@@ -76815,6 +76847,7 @@ in_quotes:
76815
76847
  // this state parses the remainder of a quoted value
76816
76848
  quote_pos = 0;
76817
76849
  escape_pos = 0;
76850
+ has_quotes = true;
76818
76851
  position++;
76819
76852
  do {
76820
76853
  for (; position < buffer_size; position++) {
@@ -76926,7 +76959,7 @@ final_state:
76926
76959
  }
76927
76960
  if (column > 0 || position > start) {
76928
76961
  // remaining values to be added to the chunk
76929
- AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
76962
+ AddValue(buffer.get() + start, position - start - offset, column, escape_positions, has_quotes);
76930
76963
  finished_chunk = AddRow(insert_chunk, column);
76931
76964
  }
76932
76965
  // final stage, only reached after parsing the file is finished
@@ -76944,6 +76977,7 @@ bool BufferedCSVReader::TryParseSimpleCSV(DataChunk &insert_chunk, string &error
76944
76977
  bool finished_chunk = false;
76945
76978
  idx_t column = 0;
76946
76979
  idx_t offset = 0;
76980
+ bool has_quotes = false;
76947
76981
  vector<idx_t> escape_positions;
76948
76982
 
76949
76983
  // read values into the buffer (if any)
@@ -76985,9 +77019,10 @@ normal:
76985
77019
  // file ends during normal scan: go to end state
76986
77020
  goto final_state;
76987
77021
  add_value:
76988
- AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
77022
+ AddValue(buffer.get() + start, position - start - offset, column, escape_positions, has_quotes);
76989
77023
  // increase position by 1 and move start to the new position
76990
77024
  offset = 0;
77025
+ has_quotes = false;
76991
77026
  start = ++position;
76992
77027
  if (position >= buffer_size && !ReadBuffer(start)) {
76993
77028
  // file ends right after delimiter, go to final state
@@ -76997,10 +77032,11 @@ add_value:
76997
77032
  add_row : {
76998
77033
  // check type of newline (\r or \n)
76999
77034
  bool carriage_return = buffer[position] == '\r';
77000
- AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
77035
+ AddValue(buffer.get() + start, position - start - offset, column, escape_positions, has_quotes);
77001
77036
  finished_chunk = AddRow(insert_chunk, column);
77002
77037
  // increase position by 1 and move start to the new position
77003
77038
  offset = 0;
77039
+ has_quotes = false;
77004
77040
  start = ++position;
77005
77041
  if (position >= buffer_size && !ReadBuffer(start)) {
77006
77042
  // file ends right after delimiter, go to final state
@@ -77020,6 +77056,7 @@ add_row : {
77020
77056
  in_quotes:
77021
77057
  /* state: in_quotes */
77022
77058
  // this state parses the remainder of a quoted value
77059
+ has_quotes = true;
77023
77060
  position++;
77024
77061
  do {
77025
77062
  for (; position < buffer_size; position++) {
@@ -77106,7 +77143,7 @@ final_state:
77106
77143
 
77107
77144
  if (column > 0 || position > start) {
77108
77145
  // remaining values to be added to the chunk
77109
- AddValue(buffer.get() + start, position - start - offset, column, escape_positions);
77146
+ AddValue(buffer.get() + start, position - start - offset, column, escape_positions, has_quotes);
77110
77147
  finished_chunk = AddRow(insert_chunk, column);
77111
77148
  }
77112
77149
 
@@ -77206,7 +77243,8 @@ bool BufferedCSVReader::TryParseCSV(ParserMode parser_mode, DataChunk &insert_ch
77206
77243
  }
77207
77244
  }
77208
77245
 
77209
- void BufferedCSVReader::AddValue(char *str_val, idx_t length, idx_t &column, vector<idx_t> &escape_positions) {
77246
+ void BufferedCSVReader::AddValue(char *str_val, idx_t length, idx_t &column, vector<idx_t> &escape_positions,
77247
+ bool has_quotes) {
77210
77248
  if (length == 0 && column == 0) {
77211
77249
  row_empty = true;
77212
77250
  } else {
@@ -77237,8 +77275,9 @@ void BufferedCSVReader::AddValue(char *str_val, idx_t length, idx_t &column, vec
77237
77275
 
77238
77276
  str_val[length] = '\0';
77239
77277
 
77240
- // test against null string
77241
- if (!options.force_not_null[column] && strcmp(options.null_str.c_str(), str_val) == 0) {
77278
+ // test against null string, but only if the value was not quoted
77279
+ if ((!has_quotes || sql_types[column].id() != LogicalTypeId::VARCHAR) && !options.force_not_null[column] &&
77280
+ strcmp(options.null_str.c_str(), str_val) == 0) {
77242
77281
  FlatVector::SetNull(parse_chunk.data[column], row_entry, true);
77243
77282
  } else {
77244
77283
  auto &v = parse_chunk.data[column];
@@ -95279,6 +95318,15 @@ using type_set_t = unordered_set<LogicalType, LogicalTypeHashFunction, LogicalTy
95279
95318
 
95280
95319
  namespace duckdb {
95281
95320
 
95321
+ BindCastInput::BindCastInput(CastFunctionSet &function_set, BindCastInfo *info, ClientContext *context)
95322
+ : function_set(function_set), info(info), context(context) {
95323
+ }
95324
+
95325
+ BoundCastInfo BindCastInput::GetCastFunction(const LogicalType &source, const LogicalType &target) {
95326
+ GetCastFunctionInput input(context);
95327
+ return function_set.GetCastFunction(source, target, input);
95328
+ }
95329
+
95282
95330
  BindCastFunction::BindCastFunction(bind_cast_function_t function_p, unique_ptr<BindCastInfo> info_p)
95283
95331
  : function(function_p), info(move(info_p)) {
95284
95332
  }
@@ -95295,7 +95343,8 @@ CastFunctionSet &CastFunctionSet::Get(DatabaseInstance &db) {
95295
95343
  return DBConfig::GetConfig(db).GetCastFunctions();
95296
95344
  }
95297
95345
 
95298
- BoundCastInfo CastFunctionSet::GetCastFunction(const LogicalType &source, const LogicalType &target) {
95346
+ BoundCastInfo CastFunctionSet::GetCastFunction(const LogicalType &source, const LogicalType &target,
95347
+ GetCastFunctionInput &get_input) {
95299
95348
  if (source == target) {
95300
95349
  return DefaultCasts::NopCast;
95301
95350
  }
@@ -95303,7 +95352,7 @@ BoundCastInfo CastFunctionSet::GetCastFunction(const LogicalType &source, const
95303
95352
  // we iterate the set of bind functions backwards
95304
95353
  for (idx_t i = bind_functions.size(); i > 0; i--) {
95305
95354
  auto &bind_function = bind_functions[i - 1];
95306
- BindCastInput input(*this, bind_function.info.get());
95355
+ BindCastInput input(*this, bind_function.info.get(), get_input.context);
95307
95356
  auto result = bind_function.function(input, source, target);
95308
95357
  if (result.function) {
95309
95358
  // found a cast function! return it
@@ -95316,10 +95365,14 @@ BoundCastInfo CastFunctionSet::GetCastFunction(const LogicalType &source, const
95316
95365
 
95317
95366
  struct MapCastNode {
95318
95367
  MapCastNode(BoundCastInfo info, int64_t implicit_cast_cost)
95319
- : cast_info(move(info)), implicit_cast_cost(implicit_cast_cost) {
95368
+ : cast_info(move(info)), bind_function(nullptr), implicit_cast_cost(implicit_cast_cost) {
95369
+ }
95370
+ MapCastNode(bind_cast_function_t func, int64_t implicit_cast_cost)
95371
+ : cast_info(nullptr), bind_function(func), implicit_cast_cost(implicit_cast_cost) {
95320
95372
  }
95321
95373
 
95322
95374
  BoundCastInfo cast_info;
95375
+ bind_cast_function_t bind_function;
95323
95376
  int64_t implicit_cast_cost;
95324
95377
  };
95325
95378
 
@@ -95357,18 +95410,30 @@ BoundCastInfo MapCastFunction(BindCastInput &input, const LogicalType &source, c
95357
95410
  // target type not found
95358
95411
  return nullptr;
95359
95412
  }
95413
+ if (target_entry->second.bind_function) {
95414
+ return target_entry->second.bind_function(input, source, target);
95415
+ }
95360
95416
  return target_entry->second.cast_info.Copy();
95361
95417
  }
95362
95418
 
95363
95419
  void CastFunctionSet::RegisterCastFunction(const LogicalType &source, const LogicalType &target, BoundCastInfo function,
95364
95420
  int64_t implicit_cast_cost) {
95421
+ RegisterCastFunction(source, target, MapCastNode(move(function), implicit_cast_cost));
95422
+ }
95423
+
95424
+ void CastFunctionSet::RegisterCastFunction(const LogicalType &source, const LogicalType &target,
95425
+ bind_cast_function_t bind_function, int64_t implicit_cast_cost) {
95426
+ RegisterCastFunction(source, target, MapCastNode(bind_function, implicit_cast_cost));
95427
+ }
95428
+
95429
+ void CastFunctionSet::RegisterCastFunction(const LogicalType &source, const LogicalType &target, MapCastNode node) {
95365
95430
  if (!map_info) {
95366
95431
  // create the cast map and the cast map function
95367
95432
  auto info = make_unique<MapCastInfo>();
95368
95433
  map_info = info.get();
95369
95434
  bind_functions.emplace_back(MapCastFunction, move(info));
95370
95435
  }
95371
- map_info->casts[source].insert(make_pair(target, MapCastNode(move(function), implicit_cast_cost)));
95436
+ map_info->casts[source].insert(make_pair(target, move(node)));
95372
95437
  }
95373
95438
 
95374
95439
  } // namespace duckdb
@@ -95902,8 +95967,8 @@ public:
95902
95967
  };
95903
95968
 
95904
95969
  unique_ptr<BoundCastData> BindEnumCast(BindCastInput &input, const LogicalType &source, const LogicalType &target) {
95905
- auto to_varchar_cast = input.function_set.GetCastFunction(source, LogicalType::VARCHAR);
95906
- auto from_varchar_cast = input.function_set.GetCastFunction(LogicalType::VARCHAR, target);
95970
+ auto to_varchar_cast = input.GetCastFunction(source, LogicalType::VARCHAR);
95971
+ auto from_varchar_cast = input.GetCastFunction(LogicalType::VARCHAR, target);
95907
95972
  return make_unique<EnumBoundCastData>(move(to_varchar_cast), move(from_varchar_cast));
95908
95973
  }
95909
95974
 
@@ -95979,7 +96044,7 @@ unique_ptr<BoundCastData> BindListToListCast(BindCastInput &input, const Logical
95979
96044
  vector<BoundCastInfo> child_cast_info;
95980
96045
  auto &source_child_type = ListType::GetChildType(source);
95981
96046
  auto &result_child_type = ListType::GetChildType(target);
95982
- auto child_cast = input.function_set.GetCastFunction(source_child_type, result_child_type);
96047
+ auto child_cast = input.GetCastFunction(source_child_type, result_child_type);
95983
96048
  return make_unique<ListBoundCastData>(move(child_cast));
95984
96049
  }
95985
96050
 
@@ -96122,8 +96187,8 @@ unique_ptr<BoundCastData> BindMapToMapCast(BindCastInput &input, const LogicalTy
96122
96187
  auto target_key = LogicalType::LIST(MapType::KeyType(target));
96123
96188
  auto source_val = LogicalType::LIST(MapType::ValueType(source));
96124
96189
  auto target_val = LogicalType::LIST(MapType::ValueType(target));
96125
- auto key_cast = input.function_set.GetCastFunction(source_key, target_key);
96126
- auto value_cast = input.function_set.GetCastFunction(source_val, target_val);
96190
+ auto key_cast = input.GetCastFunction(source_key, target_key);
96191
+ auto value_cast = input.GetCastFunction(source_val, target_val);
96127
96192
  return make_unique<MapBoundCastData>(move(key_cast), move(value_cast));
96128
96193
  }
96129
96194
 
@@ -96496,8 +96561,7 @@ unique_ptr<BoundCastData> BindStructToStructCast(BindCastInput &input, const Log
96496
96561
  throw TypeMismatchException(source, target, "Cannot cast STRUCTs of different size");
96497
96562
  }
96498
96563
  for (idx_t i = 0; i < source_child_types.size(); i++) {
96499
- auto child_cast =
96500
- input.function_set.GetCastFunction(source_child_types[i].second, result_child_types[i].second);
96564
+ auto child_cast = input.GetCastFunction(source_child_types[i].second, result_child_types[i].second);
96501
96565
  child_cast_info.push_back(move(child_cast));
96502
96566
  }
96503
96567
  return make_unique<StructBoundCastData>(move(child_cast_info), target);
@@ -185998,11 +186062,13 @@ unique_ptr<Expression> AddCastExpressionInternal(unique_ptr<Expression> expr, co
185998
186062
 
185999
186063
  static BoundCastInfo BindCastFunction(ClientContext &context, const LogicalType &source, const LogicalType &target) {
186000
186064
  auto &cast_functions = DBConfig::GetConfig(context).GetCastFunctions();
186001
- return cast_functions.GetCastFunction(source, target);
186065
+ GetCastFunctionInput input(context);
186066
+ return cast_functions.GetCastFunction(source, target, input);
186002
186067
  }
186003
186068
 
186004
186069
  unique_ptr<Expression> AddCastToTypeInternal(unique_ptr<Expression> expr, const LogicalType &target_type,
186005
- CastFunctionSet &cast_functions, bool try_cast) {
186070
+ CastFunctionSet &cast_functions, GetCastFunctionInput &get_input,
186071
+ bool try_cast) {
186006
186072
  D_ASSERT(expr);
186007
186073
  if (expr->expression_class == ExpressionClass::BOUND_PARAMETER) {
186008
186074
  auto &parameter = (BoundParameterExpression &)*expr;
@@ -186041,20 +186107,23 @@ unique_ptr<Expression> AddCastToTypeInternal(unique_ptr<Expression> expr, const
186041
186107
  if (!target_type.IsValid()) {
186042
186108
  return expr;
186043
186109
  }
186044
- auto cast_function = cast_functions.GetCastFunction(expr->return_type, target_type);
186110
+
186111
+ auto cast_function = cast_functions.GetCastFunction(expr->return_type, target_type, get_input);
186045
186112
  return AddCastExpressionInternal(move(expr), target_type, move(cast_function), try_cast);
186046
186113
  }
186047
186114
 
186048
186115
  unique_ptr<Expression> BoundCastExpression::AddDefaultCastToType(unique_ptr<Expression> expr,
186049
186116
  const LogicalType &target_type, bool try_cast) {
186050
186117
  CastFunctionSet default_set;
186051
- return AddCastToTypeInternal(move(expr), target_type, default_set, try_cast);
186118
+ GetCastFunctionInput get_input;
186119
+ return AddCastToTypeInternal(move(expr), target_type, default_set, get_input, try_cast);
186052
186120
  }
186053
186121
 
186054
186122
  unique_ptr<Expression> BoundCastExpression::AddCastToType(ClientContext &context, unique_ptr<Expression> expr,
186055
186123
  const LogicalType &target_type, bool try_cast) {
186056
186124
  auto &cast_functions = DBConfig::GetConfig(context).GetCastFunctions();
186057
- return AddCastToTypeInternal(move(expr), target_type, cast_functions, try_cast);
186125
+ GetCastFunctionInput get_input(context);
186126
+ return AddCastToTypeInternal(move(expr), target_type, cast_functions, get_input, try_cast);
186058
186127
  }
186059
186128
 
186060
186129
  bool BoundCastExpression::CastIsInvertible(const LogicalType &source_type, const LogicalType &target_type) {
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 "b8cecdfc9"
15
- #define DUCKDB_VERSION "v0.5.2-dev484"
14
+ #define DUCKDB_SOURCE_ID "27a7b4d19"
15
+ #define DUCKDB_VERSION "v0.5.2-dev492"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //
@@ -2875,6 +2875,7 @@ namespace duckdb {
2875
2875
  class CastFunctionSet;
2876
2876
  class Deserializer;
2877
2877
  class Serializer;
2878
+ struct GetCastFunctionInput;
2878
2879
 
2879
2880
  //! The Value object holds a single arbitrary value of any type that can be
2880
2881
  //! stored in the database.
@@ -3054,18 +3055,20 @@ public:
3054
3055
  DUCKDB_API uintptr_t GetPointer() const;
3055
3056
 
3056
3057
  //! Cast this value to another type, throws exception if its not possible
3057
- DUCKDB_API Value CastAs(CastFunctionSet &set, const LogicalType &target_type, bool strict = false) const;
3058
+ DUCKDB_API Value CastAs(CastFunctionSet &set, GetCastFunctionInput &get_input, const LogicalType &target_type,
3059
+ bool strict = false) const;
3058
3060
  DUCKDB_API Value CastAs(ClientContext &context, const LogicalType &target_type, bool strict = false) const;
3059
3061
  DUCKDB_API Value DefaultCastAs(const LogicalType &target_type, bool strict = false) const;
3060
3062
  //! Tries to cast this value to another type, and stores the result in "new_value"
3061
- DUCKDB_API bool TryCastAs(CastFunctionSet &set, const LogicalType &target_type, Value &new_value,
3062
- string *error_message, bool strict = false) const;
3063
+ DUCKDB_API bool TryCastAs(CastFunctionSet &set, GetCastFunctionInput &get_input, const LogicalType &target_type,
3064
+ Value &new_value, string *error_message, bool strict = false) const;
3063
3065
  DUCKDB_API bool TryCastAs(ClientContext &context, const LogicalType &target_type, Value &new_value,
3064
3066
  string *error_message, bool strict = false) const;
3065
3067
  DUCKDB_API bool DefaultTryCastAs(const LogicalType &target_type, Value &new_value, string *error_message,
3066
3068
  bool strict = false) const;
3067
3069
  //! Tries to cast this value to another type, and stores the result in THIS value again
3068
- DUCKDB_API bool TryCastAs(CastFunctionSet &set, const LogicalType &target_type, bool strict = false);
3070
+ DUCKDB_API bool TryCastAs(CastFunctionSet &set, GetCastFunctionInput &get_input, const LogicalType &target_type,
3071
+ bool strict = false);
3069
3072
  DUCKDB_API bool TryCastAs(ClientContext &context, const LogicalType &target_type, bool strict = false);
3070
3073
  DUCKDB_API bool DefaultTryCastAs(const LogicalType &target_type, bool strict = false);
3071
3074
 
@@ -3108,7 +3111,8 @@ public:
3108
3111
 
3109
3112
  //! Returns true if the values are (approximately) equivalent. Note this is NOT the SQL equivalence. For this
3110
3113
  //! function, NULL values are equivalent and floating point values that are close are equivalent.
3111
- DUCKDB_API static bool ValuesAreEqual(CastFunctionSet &set, const Value &result_value, const Value &value);
3114
+ DUCKDB_API static bool ValuesAreEqual(CastFunctionSet &set, GetCastFunctionInput &get_input,
3115
+ const Value &result_value, const Value &value);
3112
3116
  DUCKDB_API static bool ValuesAreEqual(ClientContext &context, const Value &result_value, const Value &value);
3113
3117
  DUCKDB_API static bool DefaultValuesAreEqual(const Value &result_value, const Value &value);
3114
3118
  //! Returns true if the values are not distinct from each other, following SQL semantics for NOT DISTINCT FROM.
@@ -4906,6 +4910,7 @@ private:
4906
4910
 
4907
4911
  namespace duckdb {
4908
4912
  class CastFunctionSet;
4913
+ struct GetCastFunctionInput;
4909
4914
 
4910
4915
  // VectorOperations contains a set of operations that operate on sets of
4911
4916
  // vectors. In general, the operators must all have the same type, otherwise an
@@ -5047,8 +5052,8 @@ struct VectorOperations {
5047
5052
  //! Cast the data from the source type to the target type. Any elements that could not be converted are turned into
5048
5053
  //! NULLs. If any elements cannot be converted, returns false and fills in the error_message. If no error message is
5049
5054
  //! provided, an exception is thrown instead.
5050
- DUCKDB_API static bool TryCast(CastFunctionSet &set, Vector &source, Vector &result, idx_t count,
5051
- string *error_message, bool strict = false);
5055
+ DUCKDB_API static bool TryCast(CastFunctionSet &set, GetCastFunctionInput &input, Vector &source, Vector &result,
5056
+ idx_t count, string *error_message, bool strict = false);
5052
5057
  DUCKDB_API static bool DefaultTryCast(Vector &source, Vector &result, idx_t count, string *error_message,
5053
5058
  bool strict = false);
5054
5059
  DUCKDB_API static bool TryCast(ClientContext &context, Vector &source, Vector &result, idx_t count,
@@ -14995,11 +15000,14 @@ public:
14995
15000
  };
14996
15001
 
14997
15002
  struct BindCastInput {
14998
- BindCastInput(CastFunctionSet &function_set, BindCastInfo *info) : function_set(function_set), info(info) {
14999
- }
15003
+ DUCKDB_API BindCastInput(CastFunctionSet &function_set, BindCastInfo *info, ClientContext *context);
15000
15004
 
15001
15005
  CastFunctionSet &function_set;
15002
15006
  BindCastInfo *info;
15007
+ ClientContext *context;
15008
+
15009
+ public:
15010
+ DUCKDB_API BoundCastInfo GetCastFunction(const LogicalType &source, const LogicalType &target);
15003
15011
  };
15004
15012
 
15005
15013
  struct DefaultCasts {
@@ -27262,7 +27270,7 @@ private:
27262
27270
  bool TryParseComplexCSV(DataChunk &insert_chunk, string &error_message);
27263
27271
 
27264
27272
  //! Adds a value to the current row
27265
- void AddValue(char *str_val, idx_t length, idx_t &column, vector<idx_t> &escape_positions);
27273
+ void AddValue(char *str_val, idx_t length, idx_t &column, vector<idx_t> &escape_positions, bool has_quotes);
27266
27274
  //! Adds a row to the insert_chunk, returns true if the chunk is filled as a result of this row being added
27267
27275
  bool AddRow(DataChunk &insert_chunk, idx_t &column);
27268
27276
  //! Finalizes a chunk, parsing all values that have been added so far and adding them to the insert_chunk