duckdb 0.3.2-dev3.0 → 0.3.2-dev31.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.2-dev3.0",
4
+ "version": "0.3.2-dev31.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -18315,7 +18315,7 @@ struct RegexpFun {
18315
18315
 
18316
18316
  struct SubstringFun {
18317
18317
  static void RegisterFunction(BuiltinFunctions &set);
18318
- static string_t SubstringScalarFunction(Vector &result, string_t input, int32_t offset, int32_t length);
18318
+ static string_t SubstringScalarFunction(Vector &result, string_t input, int64_t offset, int64_t length);
18319
18319
  };
18320
18320
 
18321
18321
  struct PrintfFun {
@@ -37228,6 +37228,52 @@ bool Interval::GreaterThanEquals(interval_t left, interval_t right) {
37228
37228
  return GreaterThan(left, right) || Equals(left, right);
37229
37229
  }
37230
37230
 
37231
+ date_t Interval::Add(date_t left, interval_t right) {
37232
+ date_t result;
37233
+ if (right.months != 0) {
37234
+ int32_t year, month, day;
37235
+ Date::Convert(left, year, month, day);
37236
+ int32_t year_diff = right.months / Interval::MONTHS_PER_YEAR;
37237
+ year += year_diff;
37238
+ month += right.months - year_diff * Interval::MONTHS_PER_YEAR;
37239
+ if (month > Interval::MONTHS_PER_YEAR) {
37240
+ year++;
37241
+ month -= Interval::MONTHS_PER_YEAR;
37242
+ } else if (month <= 0) {
37243
+ year--;
37244
+ month += Interval::MONTHS_PER_YEAR;
37245
+ }
37246
+ day = MinValue<int32_t>(day, Date::MonthDays(year, month));
37247
+ result = Date::FromDate(year, month, day);
37248
+ } else {
37249
+ result = left;
37250
+ }
37251
+ if (right.days != 0) {
37252
+ if (!TryAddOperator::Operation(result.days, right.days, result.days)) {
37253
+ throw OutOfRangeException("Date out of range");
37254
+ }
37255
+ }
37256
+ if (right.micros != 0) {
37257
+ if (!TryAddOperator::Operation(result.days, int32_t(right.micros / Interval::MICROS_PER_DAY), result.days)) {
37258
+ throw OutOfRangeException("Date out of range");
37259
+ }
37260
+ }
37261
+ return result;
37262
+ }
37263
+
37264
+ dtime_t Interval::Add(dtime_t left, interval_t right, date_t &date) {
37265
+ int64_t diff = right.micros - ((right.micros / Interval::MICROS_PER_DAY) * Interval::MICROS_PER_DAY);
37266
+ left += diff;
37267
+ if (left.micros >= Interval::MICROS_PER_DAY) {
37268
+ left.micros -= Interval::MICROS_PER_DAY;
37269
+ date.days++;
37270
+ } else if (left.micros < 0) {
37271
+ left.micros += Interval::MICROS_PER_DAY;
37272
+ date.days--;
37273
+ }
37274
+ return left;
37275
+ }
37276
+
37231
37277
  } // namespace duckdb
37232
37278
 
37233
37279
 
@@ -46204,7 +46250,38 @@ void FillEnumResultTemplate(Vector &source, Vector &result, idx_t count) {
46204
46250
  }
46205
46251
  }
46206
46252
 
46207
- static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string *error_message) {
46253
+ void EnumToVarchar(Vector &source, Vector &result, idx_t count, PhysicalType enum_physical_type) {
46254
+ if (source.GetVectorType() == VectorType::CONSTANT_VECTOR) {
46255
+ result.SetVectorType(source.GetVectorType());
46256
+ } else {
46257
+ result.SetVectorType(VectorType::FLAT_VECTOR);
46258
+ }
46259
+ for (idx_t i = 0; i < count; i++) {
46260
+ auto src_val = source.GetValue(i);
46261
+ if (src_val.is_null) {
46262
+ result.SetValue(i, Value());
46263
+ continue;
46264
+ }
46265
+ auto str_vec = EnumType::GetValuesInsertOrder(source.GetType());
46266
+ uint64_t enum_idx;
46267
+ switch (enum_physical_type) {
46268
+ case PhysicalType::UINT8:
46269
+ enum_idx = src_val.value_.utinyint;
46270
+ break;
46271
+ case PhysicalType::UINT16:
46272
+ enum_idx = src_val.value_.usmallint;
46273
+ break;
46274
+ case PhysicalType::UINT32:
46275
+ enum_idx = src_val.value_.uinteger;
46276
+ break;
46277
+ default:
46278
+ throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types");
46279
+ }
46280
+ result.SetValue(i, Value(str_vec[enum_idx]));
46281
+ }
46282
+ }
46283
+
46284
+ static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string *error_message, bool strict) {
46208
46285
  auto enum_physical_type = source.GetType().InternalType();
46209
46286
  switch (result.GetType().id()) {
46210
46287
  case LogicalTypeId::ENUM: {
@@ -46225,38 +46302,17 @@ static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string *
46225
46302
  break;
46226
46303
  }
46227
46304
  case LogicalTypeId::VARCHAR: {
46228
- if (source.GetVectorType() == VectorType::CONSTANT_VECTOR) {
46229
- result.SetVectorType(source.GetVectorType());
46230
- } else {
46231
- result.SetVectorType(VectorType::FLAT_VECTOR);
46232
- }
46233
- for (idx_t i = 0; i < count; i++) {
46234
- auto src_val = source.GetValue(i);
46235
- if (src_val.is_null) {
46236
- result.SetValue(i, Value());
46237
- continue;
46238
- }
46239
- auto str_vec = EnumType::GetValuesInsertOrder(source.GetType());
46240
- uint64_t enum_idx;
46241
- switch (enum_physical_type) {
46242
- case PhysicalType::UINT8:
46243
- enum_idx = src_val.value_.utinyint;
46244
- break;
46245
- case PhysicalType::UINT16:
46246
- enum_idx = src_val.value_.usmallint;
46247
- break;
46248
- case PhysicalType::UINT32:
46249
- enum_idx = src_val.value_.uinteger;
46250
- break;
46251
- default:
46252
- throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types");
46253
- }
46254
- result.SetValue(i, Value(str_vec[enum_idx]));
46255
- }
46305
+ EnumToVarchar(source, result, count, enum_physical_type);
46306
+ break;
46307
+ }
46308
+ default: {
46309
+ // Cast to varchar
46310
+ Vector varchar_cast(LogicalType::VARCHAR, count);
46311
+ EnumToVarchar(source, varchar_cast, count, enum_physical_type);
46312
+ // Try to cast from varchar to whatever we wanted before
46313
+ VectorOperations::TryCast(varchar_cast, result, count, error_message, strict);
46256
46314
  break;
46257
46315
  }
46258
- default:
46259
- throw InternalException("Cast from Enum is not allowed");
46260
46316
  }
46261
46317
  return true;
46262
46318
  }
@@ -46371,7 +46427,7 @@ bool VectorOperations::TryCast(Vector &source, Vector &result, idx_t count, stri
46371
46427
  case LogicalTypeId::LIST:
46372
46428
  return ListCastSwitch(source, result, count, error_message);
46373
46429
  case LogicalTypeId::ENUM:
46374
- return EnumCastSwitch(source, result, count, error_message);
46430
+ return EnumCastSwitch(source, result, count, error_message, strict);
46375
46431
  default:
46376
46432
  return TryVectorNullCast(source, result, count, error_message);
46377
46433
  }
@@ -61172,15 +61228,9 @@ struct BufferedCSVReaderOptions {
61172
61228
  //! Whether or not a type format is specified
61173
61229
  std::map<LogicalTypeId, bool> has_format = {{LogicalTypeId::DATE, false}, {LogicalTypeId::TIMESTAMP, false}};
61174
61230
 
61175
- std::string toString() const {
61176
- return "DELIMITER='" + delimiter + (has_delimiter ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
61177
- ", QUOTE='" + quote + (has_quote ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
61178
- ", ESCAPE='" + escape + (has_escape ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
61179
- ", HEADER=" + std::to_string(header) +
61180
- (has_header ? "" : (auto_detect ? " (auto detected)" : "' (default)")) +
61181
- ", SAMPLE_SIZE=" + std::to_string(sample_chunk_size * sample_chunks) +
61182
- ", ALL_VARCHAR=" + std::to_string(all_varchar);
61183
- }
61231
+ void SetDelimiter(const string &delimiter);
61232
+
61233
+ std::string ToString() const;
61184
61234
  };
61185
61235
 
61186
61236
  enum class ParserMode : uint8_t { PARSING = 0, SNIFFING_DIALECT = 1, SNIFFING_DATATYPES = 2, PARSING_HEADER = 3 };
@@ -61333,6 +61383,24 @@ private:
61333
61383
 
61334
61384
  namespace duckdb {
61335
61385
 
61386
+ void BufferedCSVReaderOptions::SetDelimiter(const string &input) {
61387
+ this->delimiter = StringUtil::Replace(input, "\\t", "\t");
61388
+ this->has_delimiter = true;
61389
+ if (input.empty()) {
61390
+ throw BinderException("DELIM or SEP must not be empty");
61391
+ }
61392
+ }
61393
+
61394
+ std::string BufferedCSVReaderOptions::ToString() const {
61395
+ return "DELIMITER='" + delimiter + (has_delimiter ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
61396
+ ", QUOTE='" + quote + (has_quote ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
61397
+ ", ESCAPE='" + escape + (has_escape ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
61398
+ ", HEADER=" + std::to_string(header) +
61399
+ (has_header ? "" : (auto_detect ? " (auto detected)" : "' (default)")) +
61400
+ ", SAMPLE_SIZE=" + std::to_string(sample_chunk_size * sample_chunks) +
61401
+ ", ALL_VARCHAR=" + std::to_string(all_varchar);
61402
+ }
61403
+
61336
61404
  static string GetLineNumberStr(idx_t linenr, bool linenr_estimated) {
61337
61405
  string estimated = (linenr_estimated ? string(" (estimated)") : string(""));
61338
61406
  return to_string(linenr + 1) + estimated;
@@ -62146,7 +62214,7 @@ vector<LogicalType> BufferedCSVReader::RefineTypeDetection(const vector<LogicalT
62146
62214
  if (requested_types.size() != options.num_cols) {
62147
62215
  throw InvalidInputException(
62148
62216
  "Error while determining column types: found %lld columns but expected %d. (%s)", options.num_cols,
62149
- requested_types.size(), options.toString());
62217
+ requested_types.size(), options.ToString());
62150
62218
  } else {
62151
62219
  detected_types = requested_types;
62152
62220
  }
@@ -62404,7 +62472,7 @@ in_quotes:
62404
62472
  } while (ReadBuffer(start));
62405
62473
  // still in quoted state at the end of the file, error:
62406
62474
  error_message = StringUtil::Format("Error in file \"%s\" on line %s: unterminated quotes. (%s)", options.file_path,
62407
- GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString());
62475
+ GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
62408
62476
  return false;
62409
62477
  unquote:
62410
62478
  /* state: unquote */
@@ -62434,7 +62502,7 @@ unquote:
62434
62502
  error_message = StringUtil::Format(
62435
62503
  "Error in file \"%s\" on line %s: quote should be followed by end of value, end "
62436
62504
  "of row or another quote. (%s)",
62437
- options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString());
62505
+ options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
62438
62506
  return false;
62439
62507
  }
62440
62508
  if (delimiter_pos == options.delimiter.size()) {
@@ -62451,7 +62519,7 @@ unquote:
62451
62519
  } while (ReadBuffer(start));
62452
62520
  error_message = StringUtil::Format(
62453
62521
  "Error in file \"%s\" on line %s: quote should be followed by end of value, end of row or another quote. (%s)",
62454
- options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString());
62522
+ options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
62455
62523
  return false;
62456
62524
  handle_escape:
62457
62525
  escape_pos = 0;
@@ -62466,7 +62534,7 @@ handle_escape:
62466
62534
  if (count > escape_pos && count > quote_pos) {
62467
62535
  error_message = StringUtil::Format(
62468
62536
  "Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)",
62469
- options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString());
62537
+ options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
62470
62538
  return false;
62471
62539
  }
62472
62540
  if (quote_pos == options.quote.size() || escape_pos == options.escape.size()) {
@@ -62477,7 +62545,7 @@ handle_escape:
62477
62545
  } while (ReadBuffer(start));
62478
62546
  error_message =
62479
62547
  StringUtil::Format("Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)",
62480
- options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString());
62548
+ options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
62481
62549
  return false;
62482
62550
  carriage_return:
62483
62551
  /* state: carriage_return */
@@ -62609,7 +62677,7 @@ in_quotes:
62609
62677
  } while (ReadBuffer(start));
62610
62678
  // still in quoted state at the end of the file, error:
62611
62679
  throw InvalidInputException("Error in file \"%s\" on line %s: unterminated quotes. (%s)", options.file_path,
62612
- GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString());
62680
+ GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
62613
62681
  unquote:
62614
62682
  /* state: unquote */
62615
62683
  // this state handles the state directly after we unquote
@@ -62636,7 +62704,7 @@ unquote:
62636
62704
  error_message = StringUtil::Format(
62637
62705
  "Error in file \"%s\" on line %s: quote should be followed by end of value, end of "
62638
62706
  "row or another quote. (%s)",
62639
- options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString());
62707
+ options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
62640
62708
  return false;
62641
62709
  }
62642
62710
  handle_escape:
@@ -62646,13 +62714,13 @@ handle_escape:
62646
62714
  if (position >= buffer_size && !ReadBuffer(start)) {
62647
62715
  error_message = StringUtil::Format(
62648
62716
  "Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)", options.file_path,
62649
- GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString());
62717
+ GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
62650
62718
  return false;
62651
62719
  }
62652
62720
  if (buffer[position] != options.quote[0] && buffer[position] != options.escape[0]) {
62653
62721
  error_message = StringUtil::Format(
62654
62722
  "Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)", options.file_path,
62655
- GetLineNumberStr(linenr, linenr_estimated).c_str(), options.toString());
62723
+ GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
62656
62724
  return false;
62657
62725
  }
62658
62726
  // escape was followed by quote or escape, go back to quoted state
@@ -62792,7 +62860,7 @@ void BufferedCSVReader::AddValue(char *str_val, idx_t length, idx_t &column, vec
62792
62860
  if (column >= sql_types.size()) {
62793
62861
  throw InvalidInputException("Error on line %s: expected %lld values per row, but got more. (%s)",
62794
62862
  GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(),
62795
- options.toString());
62863
+ options.ToString());
62796
62864
  }
62797
62865
 
62798
62866
  // insert the line number into the chunk
@@ -62847,7 +62915,7 @@ bool BufferedCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column) {
62847
62915
  if (column < sql_types.size() && mode != ParserMode::SNIFFING_DIALECT) {
62848
62916
  throw InvalidInputException("Error on line %s: expected %lld values per row, but got %d. (%s)",
62849
62917
  GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(), column,
62850
- options.toString());
62918
+ options.ToString());
62851
62919
  }
62852
62920
 
62853
62921
  if (mode == ParserMode::SNIFFING_DIALECT) {
@@ -62900,7 +62968,7 @@ void BufferedCSVReader::Flush(DataChunk &insert_chunk) {
62900
62968
  throw InvalidInputException("Error in file \"%s\" between line %llu and %llu in column \"%s\": "
62901
62969
  "file is not valid UTF8. Parser options: %s",
62902
62970
  options.file_path, linenr - parse_chunk.size(), linenr, col_name,
62903
- options.toString());
62971
+ options.ToString());
62904
62972
  }
62905
62973
  }
62906
62974
  }
@@ -62934,11 +63002,11 @@ void BufferedCSVReader::Flush(DataChunk &insert_chunk) {
62934
63002
  "(SAMPLE_SIZE=X [X rows] or SAMPLE_SIZE=-1 [all rows]), "
62935
63003
  "or skipping column conversion (ALL_VARCHAR=1)",
62936
63004
  error_message, col_name, linenr - parse_chunk.size() + 1, linenr,
62937
- options.toString());
63005
+ options.ToString());
62938
63006
  } else {
62939
63007
  throw InvalidInputException("%s between line %llu and %llu in column %s. Parser options: %s ",
62940
63008
  error_message, linenr - parse_chunk.size(), linenr, col_name,
62941
- options.toString());
63009
+ options.ToString());
62942
63010
  }
62943
63011
  }
62944
63012
  }
@@ -80733,7 +80801,7 @@ int64_t DatePart::MicrosecondsOperator::Operation(timestamp_t input) {
80733
80801
  template <>
80734
80802
  int64_t DatePart::MicrosecondsOperator::Operation(interval_t input) {
80735
80803
  // remove everything but the second & microsecond part
80736
- return input.micros;
80804
+ return input.micros % Interval::MICROS_PER_MINUTE;
80737
80805
  }
80738
80806
 
80739
80807
  template <>
@@ -80813,8 +80881,17 @@ int64_t DatePart::EpochOperator::Operation(timestamp_t input) {
80813
80881
 
80814
80882
  template <>
80815
80883
  int64_t DatePart::EpochOperator::Operation(interval_t input) {
80816
- auto secs = SecondsOperator::Operation<interval_t, int64_t>(input);
80817
- return (input.months * Interval::DAYS_PER_MONTH + input.days) * Interval::SECS_PER_DAY + secs;
80884
+ int64_t interval_years = input.months / Interval::MONTHS_PER_YEAR;
80885
+ int64_t interval_days;
80886
+ interval_days = Interval::DAYS_PER_YEAR * interval_years;
80887
+ interval_days += Interval::DAYS_PER_MONTH * (input.months % Interval::MONTHS_PER_YEAR);
80888
+ interval_days += input.days;
80889
+ int64_t interval_epoch;
80890
+ interval_epoch = interval_days * Interval::SECS_PER_DAY;
80891
+ // we add 0.25 days per year to sort of account for leap days
80892
+ interval_epoch += interval_years * (Interval::SECS_PER_DAY / 4);
80893
+ interval_epoch += input.micros / Interval::MICROS_PER_SEC;
80894
+ return interval_epoch;
80818
80895
  }
80819
80896
 
80820
80897
  template <>
@@ -86034,36 +86111,7 @@ date_t AddOperator::Operation(int32_t left, date_t right) {
86034
86111
 
86035
86112
  template <>
86036
86113
  date_t AddOperator::Operation(date_t left, interval_t right) {
86037
- date_t result;
86038
- if (right.months != 0) {
86039
- int32_t year, month, day;
86040
- Date::Convert(left, year, month, day);
86041
- int32_t year_diff = right.months / Interval::MONTHS_PER_YEAR;
86042
- year += year_diff;
86043
- month += right.months - year_diff * Interval::MONTHS_PER_YEAR;
86044
- if (month > Interval::MONTHS_PER_YEAR) {
86045
- year++;
86046
- month -= Interval::MONTHS_PER_YEAR;
86047
- } else if (month <= 0) {
86048
- year--;
86049
- month += Interval::MONTHS_PER_YEAR;
86050
- }
86051
- day = MinValue<int32_t>(day, Date::MonthDays(year, month));
86052
- result = Date::FromDate(year, month, day);
86053
- } else {
86054
- result = left;
86055
- }
86056
- if (right.days != 0) {
86057
- if (!TryAddOperator::Operation(result.days, right.days, result.days)) {
86058
- throw OutOfRangeException("Date out of range");
86059
- }
86060
- }
86061
- if (right.micros != 0) {
86062
- if (!TryAddOperator::Operation(result.days, int32_t(right.micros / Interval::MICROS_PER_DAY), result.days)) {
86063
- throw OutOfRangeException("Date out of range");
86064
- }
86065
- }
86066
- return result;
86114
+ return Interval::Add(left, right);
86067
86115
  }
86068
86116
 
86069
86117
  template <>
@@ -86071,26 +86119,13 @@ date_t AddOperator::Operation(interval_t left, date_t right) {
86071
86119
  return AddOperator::Operation<date_t, interval_t, date_t>(right, left);
86072
86120
  }
86073
86121
 
86074
- dtime_t AddIntervalToTimeOperation(dtime_t left, interval_t right, date_t &date) {
86075
- int64_t diff = right.micros - ((right.micros / Interval::MICROS_PER_DAY) * Interval::MICROS_PER_DAY);
86076
- left += diff;
86077
- if (left.micros >= Interval::MICROS_PER_DAY) {
86078
- left.micros -= Interval::MICROS_PER_DAY;
86079
- date.days++;
86080
- } else if (left.micros < 0) {
86081
- left.micros += Interval::MICROS_PER_DAY;
86082
- date.days--;
86083
- }
86084
- return left;
86085
- }
86086
-
86087
86122
  template <>
86088
86123
  timestamp_t AddOperator::Operation(timestamp_t left, interval_t right) {
86089
86124
  date_t date;
86090
86125
  dtime_t time;
86091
86126
  Timestamp::Convert(left, date, time);
86092
- auto new_date = AddOperator::Operation<date_t, interval_t, date_t>(date, right);
86093
- auto new_time = AddIntervalToTimeOperation(time, right, new_date);
86127
+ auto new_date = Interval::Add(date, right);
86128
+ auto new_time = Interval::Add(time, right, new_date);
86094
86129
  return Timestamp::FromDatetime(new_date, new_time);
86095
86130
  }
86096
86131
 
@@ -86223,7 +86258,7 @@ hugeint_t DecimalAddOverflowCheck::Operation(hugeint_t left, hugeint_t right) {
86223
86258
  template <>
86224
86259
  dtime_t AddTimeOperator::Operation(dtime_t left, interval_t right) {
86225
86260
  date_t date(0);
86226
- return AddIntervalToTimeOperation(left, right, date);
86261
+ return Interval::Add(left, right, date);
86227
86262
  }
86228
86263
 
86229
86264
  template <>
@@ -92175,7 +92210,7 @@ string_t SubstringASCII(Vector &result, string_t input, int64_t offset, int64_t
92175
92210
  return SubstringSlice(result, input_data, start, end - start);
92176
92211
  }
92177
92212
 
92178
- string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input, int32_t offset, int32_t length) {
92213
+ string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input, int64_t offset, int64_t length) {
92179
92214
  auto input_data = input.GetDataUnsafe();
92180
92215
  auto input_size = input.GetSize();
92181
92216
 
@@ -92242,16 +92277,16 @@ static void SubstringFunction(DataChunk &args, ExpressionState &state, Vector &r
92242
92277
  if (args.ColumnCount() == 3) {
92243
92278
  auto &length_vector = args.data[2];
92244
92279
 
92245
- TernaryExecutor::Execute<string_t, int32_t, int32_t, string_t>(
92280
+ TernaryExecutor::Execute<string_t, int64_t, int64_t, string_t>(
92246
92281
  input_vector, offset_vector, length_vector, result, args.size(),
92247
- [&](string_t input_string, int32_t offset, int32_t length) {
92282
+ [&](string_t input_string, int64_t offset, int64_t length) {
92248
92283
  return SubstringFun::SubstringScalarFunction(result, input_string, offset, length);
92249
92284
  });
92250
92285
  } else {
92251
- BinaryExecutor::Execute<string_t, int32_t, string_t>(
92252
- input_vector, offset_vector, result, args.size(), [&](string_t input_string, int32_t offset) {
92286
+ BinaryExecutor::Execute<string_t, int64_t, string_t>(
92287
+ input_vector, offset_vector, result, args.size(), [&](string_t input_string, int64_t offset) {
92253
92288
  return SubstringFun::SubstringScalarFunction(result, input_string, offset,
92254
- NumericLimits<int32_t>::Maximum());
92289
+ NumericLimits<int64_t>::Maximum() - offset);
92255
92290
  });
92256
92291
  }
92257
92292
  }
@@ -92262,15 +92297,15 @@ static void SubstringFunctionASCII(DataChunk &args, ExpressionState &state, Vect
92262
92297
  if (args.ColumnCount() == 3) {
92263
92298
  auto &length_vector = args.data[2];
92264
92299
 
92265
- TernaryExecutor::Execute<string_t, int32_t, int32_t, string_t>(
92300
+ TernaryExecutor::Execute<string_t, int64_t, int64_t, string_t>(
92266
92301
  input_vector, offset_vector, length_vector, result, args.size(),
92267
- [&](string_t input_string, int32_t offset, int32_t length) {
92302
+ [&](string_t input_string, int64_t offset, int64_t length) {
92268
92303
  return SubstringASCII(result, input_string, offset, length);
92269
92304
  });
92270
92305
  } else {
92271
- BinaryExecutor::Execute<string_t, int32_t, string_t>(
92272
- input_vector, offset_vector, result, args.size(), [&](string_t input_string, int32_t offset) {
92273
- return SubstringASCII(result, input_string, offset, NumericLimits<int32_t>::Maximum());
92306
+ BinaryExecutor::Execute<string_t, int64_t, string_t>(
92307
+ input_vector, offset_vector, result, args.size(), [&](string_t input_string, int64_t offset) {
92308
+ return SubstringASCII(result, input_string, offset, NumericLimits<int64_t>::Maximum() - offset);
92274
92309
  });
92275
92310
  }
92276
92311
  }
@@ -92292,10 +92327,10 @@ static unique_ptr<BaseStatistics> SubstringPropagateStats(ClientContext &context
92292
92327
 
92293
92328
  void SubstringFun::RegisterFunction(BuiltinFunctions &set) {
92294
92329
  ScalarFunctionSet substr("substring");
92295
- substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::INTEGER, LogicalType::INTEGER},
92330
+ substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT, LogicalType::BIGINT},
92296
92331
  LogicalType::VARCHAR, SubstringFunction, false, nullptr, nullptr,
92297
92332
  SubstringPropagateStats));
92298
- substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::INTEGER}, LogicalType::VARCHAR,
92333
+ substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT}, LogicalType::VARCHAR,
92299
92334
  SubstringFunction, false, nullptr, nullptr, SubstringPropagateStats));
92300
92335
  set.AddFunction(substr);
92301
92336
  substr.name = "substr";
@@ -94477,11 +94512,7 @@ static int64_t ParseInteger(vector<Value> &set) {
94477
94512
  //===--------------------------------------------------------------------===//
94478
94513
  static bool ParseBaseOption(BufferedCSVReaderOptions &options, string &loption, vector<Value> &set) {
94479
94514
  if (StringUtil::StartsWith(loption, "delim") || StringUtil::StartsWith(loption, "sep")) {
94480
- options.delimiter = ParseString(set);
94481
- options.has_delimiter = true;
94482
- if (options.delimiter.length() == 0) {
94483
- throw BinderException("DELIM or SEP must not be empty");
94484
- }
94515
+ options.SetDelimiter(ParseString(set));
94485
94516
  } else if (loption == "quote") {
94486
94517
  options.quote = ParseString(set);
94487
94518
  options.has_quote = true;
@@ -95766,8 +95797,7 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
95766
95797
  if (kv.first == "auto_detect") {
95767
95798
  options.auto_detect = kv.second.value_.boolean;
95768
95799
  } else if (kv.first == "sep" || kv.first == "delim") {
95769
- options.delimiter = kv.second.str_value;
95770
- options.has_delimiter = true;
95800
+ options.SetDelimiter(kv.second.str_value);
95771
95801
  } else if (kv.first == "header") {
95772
95802
  options.header = kv.second.value_.boolean;
95773
95803
  options.has_header = true;
@@ -212116,7 +212146,6 @@ unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);
212116
212146
 
212117
212147
  // max parse tree size approx 100 MB, should be enough
212118
212148
  #define PG_MALLOC_SIZE 10240
212119
- #define PG_MALLOC_LIMIT 1000
212120
212149
 
212121
212150
  namespace duckdb_libpgquery {
212122
212151
 
@@ -212128,7 +212157,8 @@ struct pg_parser_state_str {
212128
212157
 
212129
212158
  size_t malloc_pos;
212130
212159
  size_t malloc_ptr_idx;
212131
- char *malloc_ptrs[PG_MALLOC_LIMIT];
212160
+ char **malloc_ptrs;
212161
+ size_t malloc_ptr_size;
212132
212162
  };
212133
212163
 
212134
212164
  static __thread parser_state pg_parser_state;
@@ -212138,8 +212168,13 @@ __thread PGNode *duckdb_newNodeMacroHolder;
212138
212168
  #endif
212139
212169
 
212140
212170
  static void allocate_new(parser_state *state, size_t n) {
212141
- if (state->malloc_ptr_idx + 1 >= PG_MALLOC_LIMIT) {
212142
- throw std::runtime_error("Memory allocation failure");
212171
+ if (state->malloc_ptr_idx >= state->malloc_ptr_size) {
212172
+ size_t new_size = state->malloc_ptr_size * 2;
212173
+ auto new_malloc_ptrs = (char **) malloc(sizeof(char *) * new_size);
212174
+ memcpy(new_malloc_ptrs, state->malloc_ptrs, state->malloc_ptr_size * sizeof(char*));
212175
+ free(state->malloc_ptrs);
212176
+ state->malloc_ptr_size = new_size;
212177
+ state->malloc_ptrs = new_malloc_ptrs;
212143
212178
  }
212144
212179
  if (n < PG_MALLOC_SIZE) {
212145
212180
  n = PG_MALLOC_SIZE;
@@ -212170,6 +212205,8 @@ void pg_parser_init() {
212170
212205
  pg_parser_state.pg_err_code = PGUNDEFINED;
212171
212206
  pg_parser_state.pg_err_msg[0] = '\0';
212172
212207
 
212208
+ pg_parser_state.malloc_ptr_size = 4;
212209
+ pg_parser_state.malloc_ptrs = (char **) malloc(sizeof(char *) * pg_parser_state.malloc_ptr_size);
212173
212210
  pg_parser_state.malloc_ptr_idx = 0;
212174
212211
  allocate_new(&pg_parser_state, 1);
212175
212212
  }
@@ -212179,8 +212216,16 @@ void pg_parser_parse(const char *query, parse_result *res) {
212179
212216
  try {
212180
212217
  res->parse_tree = duckdb_libpgquery::raw_parser(query);
212181
212218
  res->success = pg_parser_state.pg_err_code == PGUNDEFINED;
212182
- } catch (...) {
212219
+ } catch (std::exception &ex) {
212183
212220
  res->success = false;
212221
+ // copy the error message of the exception
212222
+ auto error_message = ex.what();
212223
+ uint32_t pos = 0;
212224
+ while(pos < 1023 && error_message[pos]) {
212225
+ pg_parser_state.pg_err_msg[pos] = error_message[pos];
212226
+ pos++;
212227
+ }
212228
+ pg_parser_state.pg_err_msg[pos] = '\0';
212184
212229
  }
212185
212230
  res->error_message = pg_parser_state.pg_err_msg;
212186
212231
  res->error_location = pg_parser_state.pg_err_pos;
@@ -212194,6 +212239,7 @@ void pg_parser_cleanup() {
212194
212239
  pg_parser_state.malloc_ptrs[ptr_idx] = nullptr;
212195
212240
  }
212196
212241
  }
212242
+ free(pg_parser_state.malloc_ptrs);
212197
212243
  }
212198
212244
 
212199
212245
  int ereport(int code, ...) {
package/src/duckdb.hpp CHANGED
@@ -10,8 +10,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
10
10
 
11
11
  #pragma once
12
12
  #define DUCKDB_AMALGAMATION 1
13
- #define DUCKDB_SOURCE_ID "8ef7ee22c"
14
- #define DUCKDB_VERSION "0.3.2-dev3"
13
+ #define DUCKDB_SOURCE_ID "275e368e7"
14
+ #define DUCKDB_VERSION "0.3.2-dev31"
15
15
  //===----------------------------------------------------------------------===//
16
16
  // DuckDB
17
17
  //
@@ -6014,8 +6014,9 @@ public:
6014
6014
  static constexpr const int32_t MONTHS_PER_YEAR = 12;
6015
6015
  static constexpr const int32_t MONTHS_PER_QUARTER = 3;
6016
6016
  static constexpr const int32_t DAYS_PER_WEEK = 7;
6017
- static constexpr const int64_t DAYS_PER_MONTH =
6018
- 30; // only used for interval comparison/ordering purposes, in which case a month counts as 30 days
6017
+ //! only used for interval comparison/ordering purposes, in which case a month counts as 30 days
6018
+ static constexpr const int64_t DAYS_PER_MONTH = 30;
6019
+ static constexpr const int64_t DAYS_PER_YEAR = 365;
6019
6020
  static constexpr const int64_t MSECS_PER_SEC = 1000;
6020
6021
  static constexpr const int32_t SECS_PER_MINUTE = 60;
6021
6022
  static constexpr const int32_t MINS_PER_HOUR = 60;
@@ -6066,6 +6067,12 @@ public:
6066
6067
  //! Returns the exact difference between two timestamps (days and seconds)
6067
6068
  static interval_t GetDifference(timestamp_t timestamp_1, timestamp_t timestamp_2);
6068
6069
 
6070
+ //! Add an interval to a date
6071
+ static date_t Add(date_t left, interval_t right);
6072
+ //! Add an interval to a time. In case the time overflows or underflows, modify the date by the overflow.
6073
+ //! For example if we go from 23:00 to 02:00, we add a day to the date
6074
+ static dtime_t Add(dtime_t left, interval_t right, date_t &date);
6075
+
6069
6076
  //! Comparison operators
6070
6077
  static bool Equals(interval_t left, interval_t right);
6071
6078
  static bool GreaterThan(interval_t left, interval_t right);