duckdb 0.5.2-dev484.0 → 0.5.2-dev490.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 +120 -51
- package/src/duckdb.hpp +20 -12
- package/src/parquet-amalgamation.cpp +18985 -18985
package/package.json
CHANGED
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,
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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 (!
|
|
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,
|
|
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.
|
|
95906
|
-
auto from_varchar_cast = input.
|
|
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.
|
|
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.
|
|
96126
|
-
auto value_cast = input.
|
|
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
|
-
|
|
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,
|
|
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 ¶meter = (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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 "
|
|
15
|
-
#define DUCKDB_VERSION "v0.5.2-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "04c95fcbd"
|
|
15
|
+
#define DUCKDB_VERSION "v0.5.2-dev490"
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|