duckdb 0.6.2-dev1255.0 → 0.6.2-dev1264.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/src/function/cast/map_cast.cpp +12 -0
- package/src/duckdb/src/function/cast/string_cast.cpp +90 -6
- package/src/duckdb/src/function/cast/vector_cast_helpers.cpp +160 -52
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/function/cast/default_casts.hpp +17 -0
- package/src/duckdb/src/include/duckdb/function/cast/vector_cast_helpers.hpp +11 -2
package/package.json
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
|
|
4
4
|
namespace duckdb {
|
|
5
5
|
|
|
6
|
+
unique_ptr<BoundCastData> MapBoundCastData::BindMapToMapCast(BindCastInput &input, const LogicalType &source,
|
|
7
|
+
const LogicalType &target) {
|
|
8
|
+
vector<BoundCastInfo> child_cast_info;
|
|
9
|
+
auto source_key = MapType::KeyType(source);
|
|
10
|
+
auto target_key = MapType::KeyType(target);
|
|
11
|
+
auto source_val = MapType::ValueType(source);
|
|
12
|
+
auto target_val = MapType::ValueType(target);
|
|
13
|
+
auto key_cast = input.GetCastFunction(source_key, target_key);
|
|
14
|
+
auto value_cast = input.GetCastFunction(source_val, target_val);
|
|
15
|
+
return make_unique<MapBoundCastData>(move(key_cast), move(value_cast));
|
|
16
|
+
}
|
|
17
|
+
|
|
6
18
|
static bool MapToVarcharCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) {
|
|
7
19
|
auto constant = source.GetVectorType() == VectorType::CONSTANT_VECTOR;
|
|
8
20
|
auto varchar_type = LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#include "duckdb/function/cast/vector_cast_helpers.hpp"
|
|
3
3
|
#include "duckdb/common/pair.hpp"
|
|
4
4
|
#include "duckdb/common/vector.hpp"
|
|
5
|
+
#include "duckdb/function/scalar/nested_functions.hpp"
|
|
5
6
|
|
|
6
7
|
namespace duckdb {
|
|
7
8
|
|
|
@@ -114,10 +115,10 @@ static BoundCastInfo VectorStringCastNumericSwitch(BindCastInput &input, const L
|
|
|
114
115
|
}
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
// string -> list casting
|
|
117
119
|
bool VectorStringToList::StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result,
|
|
118
120
|
ValidityMask &result_mask, idx_t count, CastParameters ¶meters,
|
|
119
121
|
const SelectionVector *sel) {
|
|
120
|
-
|
|
121
122
|
idx_t total_list_size = 0;
|
|
122
123
|
for (idx_t i = 0; i < count; i++) {
|
|
123
124
|
idx_t idx = i;
|
|
@@ -127,7 +128,7 @@ bool VectorStringToList::StringToNestedTypeCastLoop(string_t *source_data, Valid
|
|
|
127
128
|
if (!source_mask.RowIsValid(idx)) {
|
|
128
129
|
continue;
|
|
129
130
|
}
|
|
130
|
-
total_list_size += VectorStringToList::
|
|
131
|
+
total_list_size += VectorStringToList::CountPartsList(source_data[idx]);
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
Vector varchar_vector(LogicalType::VARCHAR, total_list_size);
|
|
@@ -151,7 +152,7 @@ bool VectorStringToList::StringToNestedTypeCastLoop(string_t *source_data, Valid
|
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
list_data[i].offset = total;
|
|
154
|
-
if (!VectorStringToList::
|
|
155
|
+
if (!VectorStringToList::SplitStringList(source_data[idx], child_data, total, varchar_vector)) {
|
|
155
156
|
string text = "Type VARCHAR with value '" + source_data[idx].GetString() +
|
|
156
157
|
"' can't be cast to the destination type LIST";
|
|
157
158
|
HandleVectorCastError::Operation<string_t>(text, result_mask, idx, parameters.error_message, all_converted);
|
|
@@ -176,6 +177,7 @@ static LogicalType InitVarcharStructType(const LogicalType &target) {
|
|
|
176
177
|
return LogicalType::STRUCT(child_types);
|
|
177
178
|
}
|
|
178
179
|
|
|
180
|
+
// string -> struct casting
|
|
179
181
|
bool VectorStringToStruct::StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result,
|
|
180
182
|
ValidityMask &result_mask, idx_t count,
|
|
181
183
|
CastParameters ¶meters, const SelectionVector *sel) {
|
|
@@ -220,8 +222,6 @@ bool VectorStringToStruct::StringToNestedTypeCastLoop(string_t *source_data, Val
|
|
|
220
222
|
auto &varchar_vector = *child_vectors[child_idx];
|
|
221
223
|
auto &result_child_vector = *result_children[child_idx];
|
|
222
224
|
auto &child_cast_info = cast_data.child_cast_info[child_idx];
|
|
223
|
-
// get the correct casting function (VARCHAR -> result_child_type) from cast_data
|
|
224
|
-
// casting functions are determined by BindStructtoStructCast
|
|
225
225
|
CastParameters child_parameters(parameters, child_cast_info.cast_data.get());
|
|
226
226
|
if (!child_cast_info.function(varchar_vector, result_child_vector, count, child_parameters)) {
|
|
227
227
|
all_converted = false;
|
|
@@ -230,6 +230,87 @@ bool VectorStringToStruct::StringToNestedTypeCastLoop(string_t *source_data, Val
|
|
|
230
230
|
return all_converted;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
+
// string -> map casting
|
|
234
|
+
bool VectorStringToMap::StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result,
|
|
235
|
+
ValidityMask &result_mask, idx_t count, CastParameters ¶meters,
|
|
236
|
+
const SelectionVector *sel) {
|
|
237
|
+
idx_t total_elements = 0;
|
|
238
|
+
for (idx_t i = 0; i < count; i++) {
|
|
239
|
+
idx_t idx = i;
|
|
240
|
+
if (sel) {
|
|
241
|
+
idx = sel->get_index(i);
|
|
242
|
+
}
|
|
243
|
+
if (!source_mask.RowIsValid(idx)) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
total_elements += (VectorStringToMap::CountPartsMap(source_data[idx]) + 1) / 2;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
Vector varchar_key_vector(LogicalType::VARCHAR, total_elements);
|
|
250
|
+
Vector varchar_val_vector(LogicalType::VARCHAR, total_elements);
|
|
251
|
+
auto child_key_data = FlatVector::GetData<string_t>(varchar_key_vector);
|
|
252
|
+
auto child_val_data = FlatVector::GetData<string_t>(varchar_val_vector);
|
|
253
|
+
|
|
254
|
+
ListVector::Reserve(result, total_elements);
|
|
255
|
+
ListVector::SetListSize(result, total_elements);
|
|
256
|
+
auto list_data = ListVector::GetData(result);
|
|
257
|
+
|
|
258
|
+
bool all_converted = true;
|
|
259
|
+
idx_t total = 0;
|
|
260
|
+
for (idx_t i = 0; i < count; i++) {
|
|
261
|
+
idx_t idx = i;
|
|
262
|
+
if (sel) {
|
|
263
|
+
idx = sel->get_index(i);
|
|
264
|
+
}
|
|
265
|
+
if (!source_mask.RowIsValid(idx)) {
|
|
266
|
+
result_mask.SetInvalid(idx);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
list_data[i].offset = total;
|
|
271
|
+
if (!VectorStringToMap::SplitStringMap(source_data[idx], child_key_data, child_val_data, total,
|
|
272
|
+
varchar_key_vector, varchar_val_vector)) {
|
|
273
|
+
string text = "Type VARCHAR with value '" + source_data[idx].GetString() +
|
|
274
|
+
"' can't be cast to the destination type MAP";
|
|
275
|
+
FlatVector::SetNull(result, idx, true);
|
|
276
|
+
HandleVectorCastError::Operation<string_t>(text, result_mask, idx, parameters.error_message, all_converted);
|
|
277
|
+
}
|
|
278
|
+
list_data[i].length = total - list_data[i].offset;
|
|
279
|
+
}
|
|
280
|
+
D_ASSERT(total_elements == total);
|
|
281
|
+
|
|
282
|
+
auto &result_key_child = MapVector::GetKeys(result);
|
|
283
|
+
auto &result_val_child = MapVector::GetValues(result);
|
|
284
|
+
auto &cast_data = (MapBoundCastData &)*parameters.cast_data;
|
|
285
|
+
|
|
286
|
+
CastParameters key_params(parameters, cast_data.key_cast.cast_data.get());
|
|
287
|
+
if (!cast_data.key_cast.function(varchar_key_vector, result_key_child, total_elements, key_params)) {
|
|
288
|
+
all_converted = false;
|
|
289
|
+
}
|
|
290
|
+
CastParameters val_params(parameters, cast_data.value_cast.cast_data.get());
|
|
291
|
+
if (!cast_data.value_cast.function(varchar_val_vector, result_val_child, total_elements, val_params)) {
|
|
292
|
+
all_converted = false;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
auto &key_validity = FlatVector::Validity(result_key_child);
|
|
296
|
+
if (!all_converted) {
|
|
297
|
+
for (idx_t row_idx = 0; row_idx < count; row_idx++) {
|
|
298
|
+
if (!result_mask.RowIsValid(row_idx)) {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
auto list = list_data[row_idx];
|
|
302
|
+
for (idx_t list_idx = 0; list_idx < list.length; list_idx++) {
|
|
303
|
+
auto idx = list.offset + list_idx;
|
|
304
|
+
if (!key_validity.RowIsValid(idx)) {
|
|
305
|
+
result_mask.SetInvalid(row_idx);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
MapConversionVerify(result, count);
|
|
311
|
+
return all_converted;
|
|
312
|
+
}
|
|
313
|
+
|
|
233
314
|
template <class T>
|
|
234
315
|
bool StringToNestedTypeCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) {
|
|
235
316
|
D_ASSERT(source.GetType().id() == LogicalTypeId::VARCHAR);
|
|
@@ -239,7 +320,6 @@ bool StringToNestedTypeCast(Vector &source, Vector &result, idx_t count, CastPar
|
|
|
239
320
|
auto source_data = ConstantVector::GetData<string_t>(source);
|
|
240
321
|
auto &source_mask = ConstantVector::Validity(source);
|
|
241
322
|
auto &result_mask = FlatVector::Validity(result);
|
|
242
|
-
|
|
243
323
|
auto ret = T::StringToNestedTypeCastLoop(source_data, source_mask, result, result_mask, 1, parameters, nullptr);
|
|
244
324
|
result.SetVectorType(VectorType::CONSTANT_VECTOR);
|
|
245
325
|
return ret;
|
|
@@ -296,6 +376,10 @@ BoundCastInfo DefaultCasts::StringCastSwitch(BindCastInput &input, const Logical
|
|
|
296
376
|
case LogicalTypeId::STRUCT:
|
|
297
377
|
return BoundCastInfo(&StringToNestedTypeCast<VectorStringToStruct>,
|
|
298
378
|
StructBoundCastData::BindStructToStructCast(input, InitVarcharStructType(target), target));
|
|
379
|
+
case LogicalTypeId::MAP:
|
|
380
|
+
return BoundCastInfo(&StringToNestedTypeCast<VectorStringToMap>,
|
|
381
|
+
MapBoundCastData::BindMapToMapCast(
|
|
382
|
+
input, LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR), target));
|
|
299
383
|
default:
|
|
300
384
|
return VectorStringCastNumericSwitch(input, source, target);
|
|
301
385
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
namespace duckdb {
|
|
4
4
|
|
|
5
|
+
// ------- Helper functions for splitting string nested types -------
|
|
5
6
|
static bool IsNull(const char *buf, idx_t start_pos, Vector &child, idx_t row_idx) {
|
|
6
7
|
if (buf[start_pos] == 'N' && buf[start_pos + 1] == 'U' && buf[start_pos + 2] == 'L' && buf[start_pos + 3] == 'L') {
|
|
7
8
|
FlatVector::SetNull(child, row_idx, true);
|
|
@@ -16,46 +17,6 @@ inline static void SkipWhitespace(const char *buf, idx_t &pos, idx_t len) {
|
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
static idx_t StringTrim(const char *buf, idx_t &start_pos, idx_t pos) {
|
|
20
|
-
idx_t trailing_whitespace = 0;
|
|
21
|
-
while (StringUtil::CharacterIsSpace(buf[pos - trailing_whitespace - 1])) {
|
|
22
|
-
trailing_whitespace++;
|
|
23
|
-
}
|
|
24
|
-
if ((buf[start_pos] == '"' && buf[pos - trailing_whitespace - 1] == '"') ||
|
|
25
|
-
(buf[start_pos] == '\'' && buf[pos - trailing_whitespace - 1] == '\'')) {
|
|
26
|
-
start_pos++;
|
|
27
|
-
trailing_whitespace++;
|
|
28
|
-
}
|
|
29
|
-
return (pos - trailing_whitespace);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
struct CountPartOperation {
|
|
33
|
-
idx_t count = 0;
|
|
34
|
-
|
|
35
|
-
void HandleValue(const char *buf, idx_t start_pos, idx_t pos) {
|
|
36
|
-
count++;
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
struct SplitStringOperation {
|
|
41
|
-
SplitStringOperation(string_t *child_data, idx_t &child_start, Vector &child)
|
|
42
|
-
: child_data(child_data), child_start(child_start), child(child) {
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
string_t *child_data;
|
|
46
|
-
idx_t &child_start;
|
|
47
|
-
Vector &child;
|
|
48
|
-
|
|
49
|
-
void HandleValue(const char *buf, idx_t start_pos, idx_t pos) {
|
|
50
|
-
if ((pos - start_pos) == 4 && IsNull(buf, start_pos, child, child_start)) {
|
|
51
|
-
child_start++;
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
child_data[child_start] = StringVector::AddString(child, buf + start_pos, pos - start_pos);
|
|
55
|
-
child_start++;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
20
|
static bool SkipToCloseQuotes(idx_t &pos, const char *buf, idx_t &len) {
|
|
60
21
|
char quote = buf[pos];
|
|
61
22
|
pos++;
|
|
@@ -97,8 +58,53 @@ static bool SkipToClose(idx_t &idx, const char *buf, idx_t &len, idx_t &lvl, cha
|
|
|
97
58
|
return false;
|
|
98
59
|
}
|
|
99
60
|
|
|
61
|
+
static idx_t StringTrim(const char *buf, idx_t &start_pos, idx_t pos) {
|
|
62
|
+
idx_t trailing_whitespace = 0;
|
|
63
|
+
while (StringUtil::CharacterIsSpace(buf[pos - trailing_whitespace - 1])) {
|
|
64
|
+
trailing_whitespace++;
|
|
65
|
+
}
|
|
66
|
+
if ((buf[start_pos] == '"' && buf[pos - trailing_whitespace - 1] == '"') ||
|
|
67
|
+
(buf[start_pos] == '\'' && buf[pos - trailing_whitespace - 1] == '\'')) {
|
|
68
|
+
start_pos++;
|
|
69
|
+
trailing_whitespace++;
|
|
70
|
+
}
|
|
71
|
+
return (pos - trailing_whitespace);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
struct CountPartOperation {
|
|
75
|
+
idx_t count = 0;
|
|
76
|
+
|
|
77
|
+
bool HandleKey(const char *buf, idx_t start_pos, idx_t pos) {
|
|
78
|
+
count++;
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
void HandleValue(const char *buf, idx_t start_pos, idx_t pos) {
|
|
82
|
+
count++;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// ------- LIST SPLIT -------
|
|
87
|
+
struct SplitStringListOperation {
|
|
88
|
+
SplitStringListOperation(string_t *child_data, idx_t &child_start, Vector &child)
|
|
89
|
+
: child_data(child_data), child_start(child_start), child(child) {
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
string_t *child_data;
|
|
93
|
+
idx_t &child_start;
|
|
94
|
+
Vector &child;
|
|
95
|
+
|
|
96
|
+
void HandleValue(const char *buf, idx_t start_pos, idx_t pos) {
|
|
97
|
+
if ((pos - start_pos) == 4 && IsNull(buf, start_pos, child, child_start)) {
|
|
98
|
+
child_start++;
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
child_data[child_start] = StringVector::AddString(child, buf + start_pos, pos - start_pos);
|
|
102
|
+
child_start++;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
100
106
|
template <class OP>
|
|
101
|
-
static bool
|
|
107
|
+
static bool SplitStringListInternal(const string_t &input, OP &state) {
|
|
102
108
|
const char *buf = input.GetDataUnsafe();
|
|
103
109
|
idx_t len = input.GetSize();
|
|
104
110
|
idx_t lvl = 1;
|
|
@@ -143,19 +149,121 @@ static bool SplitStringifiedListInternal(const string_t &input, OP &state) {
|
|
|
143
149
|
return (pos == len && lvl == 0);
|
|
144
150
|
}
|
|
145
151
|
|
|
146
|
-
bool VectorStringToList::
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
return
|
|
152
|
+
bool VectorStringToList::SplitStringList(const string_t &input, string_t *child_data, idx_t &child_start,
|
|
153
|
+
Vector &child) {
|
|
154
|
+
SplitStringListOperation state(child_data, child_start, child);
|
|
155
|
+
return SplitStringListInternal<SplitStringListOperation>(input, state);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
idx_t VectorStringToList::CountPartsList(const string_t &input) {
|
|
159
|
+
CountPartOperation state;
|
|
160
|
+
SplitStringListInternal<CountPartOperation>(input, state);
|
|
161
|
+
return state.count;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ------- MAP SPLIT -------
|
|
165
|
+
struct SplitStringMapOperation {
|
|
166
|
+
SplitStringMapOperation(string_t *child_key_data, string_t *child_val_data, idx_t &child_start, Vector &varchar_key,
|
|
167
|
+
Vector &varchar_val)
|
|
168
|
+
: child_key_data(child_key_data), child_val_data(child_val_data), child_start(child_start),
|
|
169
|
+
varchar_key(varchar_key), varchar_val(varchar_val) {
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
string_t *child_key_data;
|
|
173
|
+
string_t *child_val_data;
|
|
174
|
+
idx_t &child_start;
|
|
175
|
+
Vector &varchar_key;
|
|
176
|
+
Vector &varchar_val;
|
|
177
|
+
|
|
178
|
+
bool HandleKey(const char *buf, idx_t start_pos, idx_t pos) {
|
|
179
|
+
if ((pos - start_pos) == 4 && IsNull(buf, start_pos, varchar_key, child_start)) {
|
|
180
|
+
FlatVector::SetNull(varchar_val, child_start, true);
|
|
181
|
+
child_start++;
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
child_key_data[child_start] = StringVector::AddString(varchar_key, buf + start_pos, pos - start_pos);
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
void HandleValue(const char *buf, idx_t start_pos, idx_t pos) {
|
|
189
|
+
if ((pos - start_pos) == 4 && IsNull(buf, start_pos, varchar_val, child_start)) {
|
|
190
|
+
child_start++;
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
child_val_data[child_start] = StringVector::AddString(varchar_val, buf + start_pos, pos - start_pos);
|
|
194
|
+
child_start++;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
template <class OP>
|
|
199
|
+
static bool FindKeyOrValueMap(const char *buf, idx_t len, idx_t &pos, OP &state, bool key) {
|
|
200
|
+
auto start_pos = pos;
|
|
201
|
+
idx_t lvl = 0;
|
|
202
|
+
while (pos < len) {
|
|
203
|
+
if (buf[pos] == '"' || buf[pos] == '\'') {
|
|
204
|
+
SkipToCloseQuotes(pos, buf, len);
|
|
205
|
+
} else if (buf[pos] == '{') {
|
|
206
|
+
SkipToClose(pos, buf, len, lvl, '}');
|
|
207
|
+
} else if (buf[pos] == '[') {
|
|
208
|
+
SkipToClose(pos, buf, len, lvl, ']');
|
|
209
|
+
} else if (key && buf[pos] == '=') {
|
|
210
|
+
idx_t end_pos = StringTrim(buf, start_pos, pos);
|
|
211
|
+
return state.HandleKey(buf, start_pos, end_pos); // put string in KEY_child_vector
|
|
212
|
+
} else if (!key && (buf[pos] == ',' || buf[pos] == '}')) {
|
|
213
|
+
idx_t end_pos = StringTrim(buf, start_pos, pos);
|
|
214
|
+
state.HandleValue(buf, start_pos, end_pos); // put string in VALUE_child_vector
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
pos++;
|
|
218
|
+
}
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
template <class OP>
|
|
223
|
+
static bool SplitStringMapInternal(const string_t &input, OP &state) {
|
|
224
|
+
const char *buf = input.GetDataUnsafe();
|
|
225
|
+
idx_t len = input.GetSize();
|
|
226
|
+
idx_t pos = 0;
|
|
227
|
+
|
|
228
|
+
SkipWhitespace(buf, pos, len);
|
|
229
|
+
if (pos == len || buf[pos] != '{') {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
SkipWhitespace(buf, ++pos, len);
|
|
233
|
+
if (pos == len) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
if (buf[pos] == '}') {
|
|
237
|
+
SkipWhitespace(buf, ++pos, len);
|
|
238
|
+
return (pos == len);
|
|
239
|
+
}
|
|
240
|
+
while (pos < len) {
|
|
241
|
+
if (!FindKeyOrValueMap(buf, len, pos, state, true)) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
SkipWhitespace(buf, ++pos, len);
|
|
245
|
+
if (!FindKeyOrValueMap(buf, len, pos, state, false)) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
SkipWhitespace(buf, ++pos, len);
|
|
249
|
+
}
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
bool VectorStringToMap::SplitStringMap(const string_t &input, string_t *child_key_data, string_t *child_val_data,
|
|
254
|
+
idx_t &child_start, Vector &varchar_key, Vector &varchar_val) {
|
|
255
|
+
SplitStringMapOperation state(child_key_data, child_val_data, child_start, varchar_key, varchar_val);
|
|
256
|
+
return SplitStringMapInternal<SplitStringMapOperation>(input, state);
|
|
150
257
|
}
|
|
151
258
|
|
|
152
|
-
idx_t
|
|
259
|
+
idx_t VectorStringToMap::CountPartsMap(const string_t &input) {
|
|
153
260
|
CountPartOperation state;
|
|
154
|
-
|
|
261
|
+
SplitStringMapInternal<CountPartOperation>(input, state);
|
|
155
262
|
return state.count;
|
|
156
263
|
}
|
|
157
264
|
|
|
158
|
-
|
|
265
|
+
// ------- STRUCT SPLIT -------
|
|
266
|
+
static bool FindKeyStruct(const char *buf, idx_t len, idx_t &pos) {
|
|
159
267
|
while (pos < len) {
|
|
160
268
|
if (buf[pos] == ':') {
|
|
161
269
|
return true;
|
|
@@ -165,8 +273,8 @@ static bool FindKey(const char *buf, idx_t len, idx_t &pos) {
|
|
|
165
273
|
return false;
|
|
166
274
|
}
|
|
167
275
|
|
|
168
|
-
static bool
|
|
169
|
-
|
|
276
|
+
static bool FindValueStruct(const char *buf, idx_t len, idx_t &pos, Vector &varchar_child, idx_t &row_idx,
|
|
277
|
+
ValidityMask *child_mask) {
|
|
170
278
|
auto start_pos = pos;
|
|
171
279
|
idx_t lvl = 0;
|
|
172
280
|
while (pos < len) {
|
|
@@ -209,7 +317,7 @@ bool VectorStringToStruct::SplitStruct(string_t &input, std::vector<std::unique_
|
|
|
209
317
|
} else {
|
|
210
318
|
while (pos < len) {
|
|
211
319
|
auto key_start = pos;
|
|
212
|
-
if (!
|
|
320
|
+
if (!FindKeyStruct(buf, len, pos)) {
|
|
213
321
|
return false;
|
|
214
322
|
}
|
|
215
323
|
auto key_end = StringTrim(buf, key_start, pos);
|
|
@@ -221,7 +329,7 @@ bool VectorStringToStruct::SplitStruct(string_t &input, std::vector<std::unique_
|
|
|
221
329
|
}
|
|
222
330
|
child_idx = it->second;
|
|
223
331
|
SkipWhitespace(buf, ++pos, len);
|
|
224
|
-
if (!
|
|
332
|
+
if (!FindValueStruct(buf, len, pos, *varchar_vectors[child_idx], row_idx, child_masks[child_idx])) {
|
|
225
333
|
return false;
|
|
226
334
|
}
|
|
227
335
|
SkipWhitespace(buf, ++pos, len);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
|
2
|
-
#define DUCKDB_VERSION "0.6.2-
|
|
2
|
+
#define DUCKDB_VERSION "0.6.2-dev1264"
|
|
3
3
|
#endif
|
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
|
5
|
+
#define DUCKDB_SOURCE_ID "19098105dc"
|
|
6
6
|
#endif
|
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
|
8
8
|
#include "duckdb/main/database.hpp"
|
|
@@ -108,6 +108,23 @@ public:
|
|
|
108
108
|
}
|
|
109
109
|
};
|
|
110
110
|
|
|
111
|
+
struct MapBoundCastData : public BoundCastData {
|
|
112
|
+
MapBoundCastData(BoundCastInfo key_cast, BoundCastInfo value_cast)
|
|
113
|
+
: key_cast(move(key_cast)), value_cast(move(value_cast)) {
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
BoundCastInfo key_cast;
|
|
117
|
+
BoundCastInfo value_cast;
|
|
118
|
+
|
|
119
|
+
static unique_ptr<BoundCastData> BindMapToMapCast(BindCastInput &input, const LogicalType &source,
|
|
120
|
+
const LogicalType &target);
|
|
121
|
+
|
|
122
|
+
public:
|
|
123
|
+
unique_ptr<BoundCastData> Copy() const override {
|
|
124
|
+
return make_unique<MapBoundCastData>(key_cast.Copy(), value_cast.Copy());
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
111
128
|
struct DefaultCasts {
|
|
112
129
|
static BoundCastInfo GetDefaultCastFunction(BindCastInput &input, const LogicalType &source,
|
|
113
130
|
const LogicalType &target);
|
|
@@ -199,8 +199,8 @@ struct VectorCastHelpers {
|
|
|
199
199
|
};
|
|
200
200
|
|
|
201
201
|
struct VectorStringToList {
|
|
202
|
-
static idx_t
|
|
203
|
-
static bool
|
|
202
|
+
static idx_t CountPartsList(const string_t &input);
|
|
203
|
+
static bool SplitStringList(const string_t &input, string_t *child_data, idx_t &child_start, Vector &child);
|
|
204
204
|
static bool StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result,
|
|
205
205
|
ValidityMask &result_mask, idx_t count, CastParameters ¶meters,
|
|
206
206
|
const SelectionVector *sel);
|
|
@@ -214,4 +214,13 @@ struct VectorStringToStruct {
|
|
|
214
214
|
const SelectionVector *sel);
|
|
215
215
|
};
|
|
216
216
|
|
|
217
|
+
struct VectorStringToMap {
|
|
218
|
+
static idx_t CountPartsMap(const string_t &input);
|
|
219
|
+
static bool SplitStringMap(const string_t &input, string_t *child_key_data, string_t *child_val_data,
|
|
220
|
+
idx_t &child_start, Vector &varchar_key, Vector &varchar_val);
|
|
221
|
+
static bool StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result,
|
|
222
|
+
ValidityMask &result_mask, idx_t count, CastParameters ¶meters,
|
|
223
|
+
const SelectionVector *sel);
|
|
224
|
+
};
|
|
225
|
+
|
|
217
226
|
} // namespace duckdb
|