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 +1 -1
- package/src/duckdb.cpp +177 -131
- package/src/duckdb.hpp +11 -4
package/package.json
CHANGED
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,
|
|
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
|
-
|
|
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
|
-
|
|
46229
|
-
|
|
46230
|
-
|
|
46231
|
-
|
|
46232
|
-
|
|
46233
|
-
|
|
46234
|
-
|
|
46235
|
-
|
|
46236
|
-
|
|
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
|
-
|
|
61176
|
-
|
|
61177
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
80817
|
-
|
|
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
|
-
|
|
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 =
|
|
86093
|
-
auto new_time =
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
92252
|
-
input_vector, offset_vector, result, args.size(), [&](string_t input_string,
|
|
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<
|
|
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,
|
|
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,
|
|
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,
|
|
92272
|
-
input_vector, offset_vector, result, args.size(), [&](string_t input_string,
|
|
92273
|
-
return SubstringASCII(result, input_string, offset, NumericLimits<
|
|
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::
|
|
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::
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
212142
|
-
|
|
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 "
|
|
14
|
-
#define DUCKDB_VERSION "0.3.2-
|
|
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
|
-
|
|
6018
|
-
|
|
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);
|