duckdb 0.8.2-dev4871.0 → 0.8.2-dev5002.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/common/operator/cast_operators.cpp +18 -0
- package/src/duckdb/src/common/row_operations/row_matcher.cpp +5 -38
- package/src/duckdb/src/common/types/data_chunk.cpp +48 -11
- package/src/duckdb/src/common/types/vector.cpp +0 -1
- package/src/duckdb/src/common/types.cpp +1 -1
- package/src/duckdb/src/core_functions/scalar/list/array_slice.cpp +5 -1
- package/src/duckdb/src/core_functions/scalar/list/list_sort.cpp +10 -1
- package/src/duckdb/src/core_functions/scalar/map/map_concat.cpp +0 -2
- package/src/duckdb/src/execution/nested_loop_join/nested_loop_join_inner.cpp +20 -27
- package/src/duckdb/src/execution/nested_loop_join/nested_loop_join_mark.cpp +21 -9
- package/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp +7 -7
- package/src/duckdb/src/execution/operator/csv_scanner/csv_reader_options.cpp +1 -1
- package/src/duckdb/src/function/cast/time_casts.cpp +12 -0
- package/src/duckdb/src/function/pragma/pragma_queries.cpp +3 -0
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +5 -0
- package/src/duckdb/src/include/duckdb/common/operator/cast_operators.hpp +27 -0
- package/src/duckdb/src/include/duckdb/common/operator/comparison_operators.hpp +38 -2
- package/src/duckdb/src/include/duckdb/core_functions/scalar/bit_functions.hpp +4 -4
- package/src/duckdb/src/include/duckdb/core_functions/scalar/blob_functions.hpp +4 -4
- package/src/duckdb/src/include/duckdb/core_functions/scalar/date_functions.hpp +5 -5
- package/src/duckdb/src/include/duckdb/core_functions/scalar/enum_functions.hpp +7 -7
- package/src/duckdb/src/include/duckdb/core_functions/scalar/generic_functions.hpp +12 -12
- package/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp +12 -12
- package/src/duckdb/src/include/duckdb/core_functions/scalar/map_functions.hpp +3 -3
- package/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp +33 -33
- package/src/duckdb/src/include/duckdb/core_functions/scalar/operators_functions.hpp +2 -2
- package/src/duckdb/src/include/duckdb/core_functions/scalar/random_functions.hpp +3 -3
- package/src/duckdb/src/include/duckdb/core_functions/scalar/string_functions.hpp +12 -12
- package/src/duckdb/src/include/duckdb/core_functions/scalar/struct_functions.hpp +2 -2
- package/src/duckdb/src/include/duckdb/core_functions/scalar/union_functions.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/expression_binder/base_select_binder.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_create_table.hpp +1 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_delete.hpp +1 -1
- package/src/duckdb/src/include/duckdb/planner/operator/logical_insert.hpp +1 -1
- package/src/duckdb/src/include/duckdb/planner/operator/logical_update.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/data_table.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +1 -1
- package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +28 -6
- package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +3 -0
- package/src/duckdb/src/planner/expression_binder/base_select_binder.cpp +14 -6
- package/src/duckdb/src/planner/operator/logical_create_table.cpp +3 -3
- package/src/duckdb/src/planner/operator/logical_delete.cpp +3 -2
- package/src/duckdb/src/planner/operator/logical_insert.cpp +3 -2
- package/src/duckdb/src/planner/operator/logical_update.cpp +3 -2
- package/src/duckdb/src/storage/data_table.cpp +8 -8
- package/src/duckdb/src/storage/local_storage.cpp +2 -3
- package/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp +64 -80
- package/src/duckdb/src/storage/storage_manager.cpp +6 -2
- package/src/duckdb/src/storage/table/row_group.cpp +6 -0
- package/src/duckdb/src/storage/table/row_group_collection.cpp +4 -3
- package/src/duckdb/src/storage/table/struct_column_data.cpp +2 -0
- package/src/duckdb/src/transaction/duck_transaction.cpp +1 -0
package/package.json
CHANGED
@@ -1373,6 +1373,12 @@ timestamp_t CastTimestampMsToUs::Operation(timestamp_t input) {
|
|
1373
1373
|
return Timestamp::FromEpochMs(input.value);
|
1374
1374
|
}
|
1375
1375
|
|
1376
|
+
template <>
|
1377
|
+
timestamp_t CastTimestampMsToNs::Operation(timestamp_t input) {
|
1378
|
+
auto us = CastTimestampMsToUs::Operation<timestamp_t, timestamp_t>(input);
|
1379
|
+
return CastTimestampUsToNs::Operation<timestamp_t, timestamp_t>(us);
|
1380
|
+
}
|
1381
|
+
|
1376
1382
|
template <>
|
1377
1383
|
timestamp_t CastTimestampNsToUs::Operation(timestamp_t input) {
|
1378
1384
|
return Timestamp::FromEpochNanoSeconds(input.value);
|
@@ -1383,6 +1389,18 @@ timestamp_t CastTimestampSecToUs::Operation(timestamp_t input) {
|
|
1383
1389
|
return Timestamp::FromEpochSeconds(input.value);
|
1384
1390
|
}
|
1385
1391
|
|
1392
|
+
template <>
|
1393
|
+
timestamp_t CastTimestampSecToMs::Operation(timestamp_t input) {
|
1394
|
+
auto us = CastTimestampSecToUs::Operation<timestamp_t, timestamp_t>(input);
|
1395
|
+
return CastTimestampUsToMs::Operation<timestamp_t, timestamp_t>(us);
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
template <>
|
1399
|
+
timestamp_t CastTimestampSecToNs::Operation(timestamp_t input) {
|
1400
|
+
auto us = CastTimestampSecToUs::Operation<timestamp_t, timestamp_t>(input);
|
1401
|
+
return CastTimestampUsToNs::Operation<timestamp_t, timestamp_t>(us);
|
1402
|
+
}
|
1403
|
+
|
1386
1404
|
//===--------------------------------------------------------------------===//
|
1387
1405
|
// Cast To Timestamp
|
1388
1406
|
//===--------------------------------------------------------------------===//
|
@@ -8,44 +8,11 @@ namespace duckdb {
|
|
8
8
|
|
9
9
|
using ValidityBytes = TupleDataLayout::ValidityBytes;
|
10
10
|
|
11
|
-
template <class OP>
|
12
|
-
struct RowMatchOperator {
|
13
|
-
static constexpr const bool COMPARE_NULL = false;
|
14
|
-
|
15
|
-
template <class T>
|
16
|
-
static inline bool Operation(const T &left, const T &right, bool left_null, bool right_null) {
|
17
|
-
if (right_null || left_null) {
|
18
|
-
return false;
|
19
|
-
}
|
20
|
-
return OP::template Operation<T>(left, right);
|
21
|
-
}
|
22
|
-
};
|
23
|
-
|
24
|
-
template <>
|
25
|
-
struct RowMatchOperator<DistinctFrom> {
|
26
|
-
static constexpr const bool COMPARE_NULL = true;
|
27
|
-
|
28
|
-
template <class T>
|
29
|
-
static inline bool Operation(const T &left, const T &right, bool left_null, bool right_null) {
|
30
|
-
return DistinctFrom::template Operation<T>(left, right, left_null, right_null);
|
31
|
-
}
|
32
|
-
};
|
33
|
-
|
34
|
-
template <>
|
35
|
-
struct RowMatchOperator<NotDistinctFrom> {
|
36
|
-
static constexpr const bool COMPARE_NULL = true;
|
37
|
-
|
38
|
-
template <class T>
|
39
|
-
static inline bool Operation(const T &left, const T &right, bool left_null, bool right_null) {
|
40
|
-
return NotDistinctFrom::template Operation<T>(left, right, left_null, right_null);
|
41
|
-
}
|
42
|
-
};
|
43
|
-
|
44
11
|
template <bool NO_MATCH_SEL, class T, class OP>
|
45
12
|
static idx_t TemplatedMatch(Vector &, const TupleDataVectorFormat &lhs_format, SelectionVector &sel, const idx_t count,
|
46
13
|
const TupleDataLayout &rhs_layout, Vector &rhs_row_locations, const idx_t col_idx,
|
47
14
|
const vector<MatchFunction> &, SelectionVector *no_match_sel, idx_t &no_match_count) {
|
48
|
-
using
|
15
|
+
using COMPARISON_OP = ComparisonOperationWrapper<OP>;
|
49
16
|
|
50
17
|
// LHS
|
51
18
|
const auto &lhs_sel = *lhs_format.unified.sel;
|
@@ -70,8 +37,8 @@ static idx_t TemplatedMatch(Vector &, const TupleDataVectorFormat &lhs_format, S
|
|
70
37
|
const ValidityBytes rhs_mask(rhs_location);
|
71
38
|
const auto rhs_null = !rhs_mask.RowIsValid(rhs_mask.GetValidityEntryUnsafe(entry_idx), idx_in_entry);
|
72
39
|
|
73
|
-
if (
|
74
|
-
|
40
|
+
if (COMPARISON_OP::template Operation<T>(lhs_data[lhs_idx], Load<T>(rhs_location + rhs_offset_in_row), lhs_null,
|
41
|
+
rhs_null)) {
|
75
42
|
sel.set_index(match_count++, idx);
|
76
43
|
} else if (NO_MATCH_SEL) {
|
77
44
|
no_match_sel->set_index(no_match_count++, idx);
|
@@ -85,7 +52,7 @@ static idx_t StructMatchEquality(Vector &lhs_vector, const TupleDataVectorFormat
|
|
85
52
|
const idx_t count, const TupleDataLayout &rhs_layout, Vector &rhs_row_locations,
|
86
53
|
const idx_t col_idx, const vector<MatchFunction> &child_functions,
|
87
54
|
SelectionVector *no_match_sel, idx_t &no_match_count) {
|
88
|
-
using
|
55
|
+
using COMPARISON_OP = ComparisonOperationWrapper<OP>;
|
89
56
|
|
90
57
|
// LHS
|
91
58
|
const auto &lhs_sel = *lhs_format.unified.sel;
|
@@ -111,7 +78,7 @@ static idx_t StructMatchEquality(Vector &lhs_vector, const TupleDataVectorFormat
|
|
111
78
|
// For structs there is no value to compare, here we match NULLs and let recursion do the rest
|
112
79
|
// So we use the comparison only if rhs or LHS is NULL and COMPARE_NULL is true
|
113
80
|
if (!(lhs_null || rhs_null) ||
|
114
|
-
(
|
81
|
+
(COMPARISON_OP::COMPARE_NULL && COMPARISON_OP::template Operation<uint32_t>(0, 0, lhs_null, rhs_null))) {
|
115
82
|
sel.set_index(match_count++, idx);
|
116
83
|
} else if (NO_MATCH_SEL) {
|
117
84
|
no_match_sel->set_index(no_match_count++, idx);
|
@@ -13,6 +13,10 @@
|
|
13
13
|
#include "duckdb/common/vector_operations/vector_operations.hpp"
|
14
14
|
#include "duckdb/execution/execution_context.hpp"
|
15
15
|
|
16
|
+
#include "duckdb/common/serializer/memory_stream.hpp"
|
17
|
+
#include "duckdb/common/serializer/binary_serializer.hpp"
|
18
|
+
#include "duckdb/common/serializer/binary_deserializer.hpp"
|
19
|
+
|
16
20
|
namespace duckdb {
|
17
21
|
|
18
22
|
DataChunk::DataChunk() : count(0), capacity(STANDARD_VECTOR_SIZE) {
|
@@ -231,16 +235,20 @@ string DataChunk::ToString() const {
|
|
231
235
|
}
|
232
236
|
|
233
237
|
void DataChunk::Serialize(Serializer &serializer) const {
|
238
|
+
|
234
239
|
// write the count
|
235
240
|
auto row_count = size();
|
236
241
|
serializer.WriteProperty<sel_t>(100, "rows", row_count);
|
242
|
+
|
243
|
+
// we should never try to serialize empty data chunks
|
237
244
|
auto column_count = ColumnCount();
|
245
|
+
D_ASSERT(column_count);
|
238
246
|
|
239
|
-
//
|
247
|
+
// write the types
|
240
248
|
serializer.WriteList(101, "types", column_count,
|
241
249
|
[&](Serializer::List &list, idx_t i) { list.WriteElement(data[i].GetType()); });
|
242
250
|
|
243
|
-
//
|
251
|
+
// write the data
|
244
252
|
serializer.WriteList(102, "columns", column_count, [&](Serializer::List &list, idx_t i) {
|
245
253
|
list.WriteObject([&](Serializer &object) {
|
246
254
|
// Reference the vector to avoid potentially mutating it during serialization
|
@@ -252,21 +260,23 @@ void DataChunk::Serialize(Serializer &serializer) const {
|
|
252
260
|
}
|
253
261
|
|
254
262
|
void DataChunk::Deserialize(Deserializer &deserializer) {
|
255
|
-
|
263
|
+
|
264
|
+
// read and set the row count
|
256
265
|
auto row_count = deserializer.ReadProperty<sel_t>(100, "rows");
|
266
|
+
SetCardinality(row_count);
|
257
267
|
|
258
|
-
//
|
268
|
+
// read the types
|
259
269
|
vector<LogicalType> types;
|
260
270
|
deserializer.ReadList(101, "types", [&](Deserializer::List &list, idx_t i) {
|
261
271
|
auto type = list.ReadElement<LogicalType>();
|
262
272
|
types.push_back(type);
|
263
273
|
});
|
264
|
-
Initialize(Allocator::DefaultAllocator(), types);
|
265
274
|
|
266
|
-
//
|
267
|
-
|
275
|
+
// initialize the data chunk
|
276
|
+
D_ASSERT(!types.empty());
|
277
|
+
Initialize(Allocator::DefaultAllocator(), types);
|
268
278
|
|
269
|
-
//
|
279
|
+
// read the data
|
270
280
|
deserializer.ReadList(102, "columns", [&](Deserializer::List &list, idx_t i) {
|
271
281
|
list.ReadObject([&](Deserializer &object) { data[i].Deserialize(object, row_count); });
|
272
282
|
});
|
@@ -296,11 +306,11 @@ void DataChunk::Slice(DataChunk &other, const SelectionVector &sel, idx_t count_
|
|
296
306
|
}
|
297
307
|
|
298
308
|
unsafe_unique_array<UnifiedVectorFormat> DataChunk::ToUnifiedFormat() {
|
299
|
-
auto
|
309
|
+
auto unified_data = make_unsafe_uniq_array<UnifiedVectorFormat>(ColumnCount());
|
300
310
|
for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) {
|
301
|
-
data[col_idx].ToUnifiedFormat(size(),
|
311
|
+
data[col_idx].ToUnifiedFormat(size(), unified_data[col_idx]);
|
302
312
|
}
|
303
|
-
return
|
313
|
+
return unified_data;
|
304
314
|
}
|
305
315
|
|
306
316
|
void DataChunk::Hash(Vector &result) {
|
@@ -324,10 +334,37 @@ void DataChunk::Hash(vector<idx_t> &column_ids, Vector &result) {
|
|
324
334
|
void DataChunk::Verify() {
|
325
335
|
#ifdef DEBUG
|
326
336
|
D_ASSERT(size() <= capacity);
|
337
|
+
|
327
338
|
// verify that all vectors in this chunk have the chunk selection vector
|
328
339
|
for (idx_t i = 0; i < ColumnCount(); i++) {
|
329
340
|
data[i].Verify(size());
|
330
341
|
}
|
342
|
+
|
343
|
+
if (!ColumnCount()) {
|
344
|
+
// don't try to round-trip dummy data chunks with no data
|
345
|
+
// e.g., these exist in queries like 'SELECT distinct(col0, col1) FROM tbl', where we have groups, but no
|
346
|
+
// payload so the payload will be such an empty data chunk
|
347
|
+
return;
|
348
|
+
}
|
349
|
+
|
350
|
+
// verify that we can round-trip chunk serialization
|
351
|
+
MemoryStream mem_stream;
|
352
|
+
BinarySerializer serializer(mem_stream);
|
353
|
+
|
354
|
+
serializer.Begin();
|
355
|
+
Serialize(serializer);
|
356
|
+
serializer.End();
|
357
|
+
|
358
|
+
mem_stream.Rewind();
|
359
|
+
|
360
|
+
BinaryDeserializer deserializer(mem_stream);
|
361
|
+
DataChunk new_chunk;
|
362
|
+
|
363
|
+
deserializer.Begin();
|
364
|
+
new_chunk.Deserialize(deserializer);
|
365
|
+
deserializer.End();
|
366
|
+
|
367
|
+
D_ASSERT(size() == new_chunk.size());
|
331
368
|
#endif
|
332
369
|
}
|
333
370
|
|
@@ -434,7 +434,7 @@ LogicalType TransformStringToLogicalType(const string &str) {
|
|
434
434
|
|
435
435
|
LogicalType GetUserTypeRecursive(const LogicalType &type, ClientContext &context) {
|
436
436
|
if (type.id() == LogicalTypeId::USER && type.HasAlias()) {
|
437
|
-
return Catalog::
|
437
|
+
return Catalog::GetType(context, INVALID_CATALOG, INVALID_SCHEMA, type.GetAlias());
|
438
438
|
}
|
439
439
|
// Look for LogicalTypeId::USER in nested types
|
440
440
|
if (type.id() == LogicalTypeId::STRUCT) {
|
@@ -191,9 +191,11 @@ static void ExecuteConstantSlice(Vector &result, Vector &str_vector, Vector &beg
|
|
191
191
|
}
|
192
192
|
|
193
193
|
auto sel_length = 0;
|
194
|
+
bool sel_valid = false;
|
194
195
|
if (step_vector && step_valid && str_valid && begin_valid && end_valid && step != 1 && end - begin > 0) {
|
195
196
|
sel_length = CalculateSliceLength(begin, end, step, step_valid);
|
196
197
|
sel.Initialize(sel_length);
|
198
|
+
sel_valid = true;
|
197
199
|
}
|
198
200
|
|
199
201
|
// Try to slice
|
@@ -205,8 +207,9 @@ static void ExecuteConstantSlice(Vector &result, Vector &str_vector, Vector &beg
|
|
205
207
|
result_data[0] = SliceValueWithSteps<INPUT_TYPE, INDEX_TYPE>(result, sel, str, begin, end, step, sel_idx);
|
206
208
|
}
|
207
209
|
|
208
|
-
if (
|
210
|
+
if (sel_valid) {
|
209
211
|
result_child_vector->Slice(sel, sel_length);
|
212
|
+
ListVector::SetListSize(result, sel_length);
|
210
213
|
}
|
211
214
|
}
|
212
215
|
|
@@ -276,6 +279,7 @@ static void ExecuteFlatSlice(Vector &result, Vector &list_vector, Vector &begin_
|
|
276
279
|
new_sel.set_index(i, sel.get_index(i));
|
277
280
|
}
|
278
281
|
result_child_vector->Slice(new_sel, sel_length);
|
282
|
+
ListVector::SetListSize(result, sel_length);
|
279
283
|
}
|
280
284
|
}
|
281
285
|
|
@@ -236,9 +236,18 @@ static void ListSortFunction(DataChunk &args, ExpressionState &state, Vector &re
|
|
236
236
|
static unique_ptr<FunctionData> ListSortBind(ClientContext &context, ScalarFunction &bound_function,
|
237
237
|
vector<unique_ptr<Expression>> &arguments, OrderType &order,
|
238
238
|
OrderByNullType &null_order) {
|
239
|
+
|
240
|
+
LogicalType child_type;
|
241
|
+
if (arguments[0]->return_type == LogicalTypeId::UNKNOWN) {
|
242
|
+
bound_function.arguments[0] = LogicalTypeId::UNKNOWN;
|
243
|
+
bound_function.return_type = LogicalType::SQLNULL;
|
244
|
+
child_type = bound_function.return_type;
|
245
|
+
return make_uniq<ListSortBindData>(order, null_order, bound_function.return_type, child_type, context);
|
246
|
+
}
|
247
|
+
|
239
248
|
bound_function.arguments[0] = arguments[0]->return_type;
|
240
249
|
bound_function.return_type = arguments[0]->return_type;
|
241
|
-
|
250
|
+
child_type = ListType::GetChildType(arguments[0]->return_type);
|
242
251
|
|
243
252
|
return make_uniq<ListSortBindData>(order, null_order, bound_function.return_type, child_type, context);
|
244
253
|
}
|
@@ -97,7 +97,6 @@ static void MapConcatFunction(DataChunk &args, ExpressionState &state, Vector &r
|
|
97
97
|
auto &values = MapVector::GetValues(map);
|
98
98
|
values_list.push_back(values.GetValue(mapping.key_index));
|
99
99
|
}
|
100
|
-
idx_t entries_count = keys_list.size();
|
101
100
|
D_ASSERT(values_list.size() == keys_list.size());
|
102
101
|
result_entry.offset = ListVector::GetListSize(result);
|
103
102
|
result_entry.length = values_list.size();
|
@@ -105,7 +104,6 @@ static void MapConcatFunction(DataChunk &args, ExpressionState &state, Vector &r
|
|
105
104
|
for (auto &list_entry : list_entries) {
|
106
105
|
ListVector::PushBack(result, list_entry);
|
107
106
|
}
|
108
|
-
ListVector::SetListSize(result, ListVector::GetListSize(result) + entries_count);
|
109
107
|
}
|
110
108
|
|
111
109
|
if (args.AllConstant()) {
|
@@ -3,21 +3,12 @@
|
|
3
3
|
|
4
4
|
namespace duckdb {
|
5
5
|
|
6
|
-
template <class OP>
|
7
|
-
struct ComparisonOperationWrapper {
|
8
|
-
template <class T>
|
9
|
-
static inline bool Operation(T left, T right, bool left_is_null, bool right_is_null) {
|
10
|
-
if (left_is_null || right_is_null) {
|
11
|
-
return false;
|
12
|
-
}
|
13
|
-
return OP::Operation(left, right);
|
14
|
-
}
|
15
|
-
};
|
16
|
-
|
17
6
|
struct InitialNestedLoopJoin {
|
18
7
|
template <class T, class OP>
|
19
8
|
static idx_t Operation(Vector &left, Vector &right, idx_t left_size, idx_t right_size, idx_t &lpos, idx_t &rpos,
|
20
9
|
SelectionVector &lvector, SelectionVector &rvector, idx_t current_match_count) {
|
10
|
+
using MATCH_OP = ComparisonOperationWrapper<OP>;
|
11
|
+
|
21
12
|
// initialize phase of nested loop join
|
22
13
|
// fill lvector and rvector with matches from the base vectors
|
23
14
|
UnifiedVectorFormat left_data, right_data;
|
@@ -37,7 +28,7 @@ struct InitialNestedLoopJoin {
|
|
37
28
|
}
|
38
29
|
idx_t left_position = left_data.sel->get_index(lpos);
|
39
30
|
bool left_is_valid = left_data.validity.RowIsValid(left_position);
|
40
|
-
if (
|
31
|
+
if (MATCH_OP::Operation(ldata[left_position], rdata[right_position], !left_is_valid, !right_is_valid)) {
|
41
32
|
// emit tuple
|
42
33
|
lvector.set_index(result_count, lpos);
|
43
34
|
rvector.set_index(result_count, rpos);
|
@@ -54,6 +45,8 @@ struct RefineNestedLoopJoin {
|
|
54
45
|
template <class T, class OP>
|
55
46
|
static idx_t Operation(Vector &left, Vector &right, idx_t left_size, idx_t right_size, idx_t &lpos, idx_t &rpos,
|
56
47
|
SelectionVector &lvector, SelectionVector &rvector, idx_t current_match_count) {
|
48
|
+
using MATCH_OP = ComparisonOperationWrapper<OP>;
|
49
|
+
|
57
50
|
UnifiedVectorFormat left_data, right_data;
|
58
51
|
left.ToUnifiedFormat(left_size, left_data);
|
59
52
|
right.ToUnifiedFormat(right_size, right_data);
|
@@ -72,7 +65,7 @@ struct RefineNestedLoopJoin {
|
|
72
65
|
auto right_idx = right_data.sel->get_index(ridx);
|
73
66
|
bool left_is_valid = left_data.validity.RowIsValid(left_idx);
|
74
67
|
bool right_is_valid = right_data.validity.RowIsValid(right_idx);
|
75
|
-
if (
|
68
|
+
if (MATCH_OP::Operation(ldata[left_idx], rdata[right_idx], !left_is_valid, !right_is_valid)) {
|
76
69
|
lvector.set_index(result_count, lidx);
|
77
70
|
rvector.set_index(result_count, ridx);
|
78
71
|
result_count++;
|
@@ -139,26 +132,26 @@ idx_t NestedLoopJoinComparisonSwitch(Vector &left, Vector &right, idx_t left_siz
|
|
139
132
|
D_ASSERT(left.GetType() == right.GetType());
|
140
133
|
switch (comparison_type) {
|
141
134
|
case ExpressionType::COMPARE_EQUAL:
|
142
|
-
return NestedLoopJoinTypeSwitch<NLTYPE,
|
143
|
-
|
135
|
+
return NestedLoopJoinTypeSwitch<NLTYPE, Equals>(left, right, left_size, right_size, lpos, rpos, lvector,
|
136
|
+
rvector, current_match_count);
|
144
137
|
case ExpressionType::COMPARE_NOTEQUAL:
|
145
|
-
return NestedLoopJoinTypeSwitch<NLTYPE,
|
146
|
-
|
138
|
+
return NestedLoopJoinTypeSwitch<NLTYPE, NotEquals>(left, right, left_size, right_size, lpos, rpos, lvector,
|
139
|
+
rvector, current_match_count);
|
147
140
|
case ExpressionType::COMPARE_LESSTHAN:
|
148
|
-
return NestedLoopJoinTypeSwitch<NLTYPE,
|
149
|
-
|
141
|
+
return NestedLoopJoinTypeSwitch<NLTYPE, LessThan>(left, right, left_size, right_size, lpos, rpos, lvector,
|
142
|
+
rvector, current_match_count);
|
150
143
|
case ExpressionType::COMPARE_GREATERTHAN:
|
151
|
-
return NestedLoopJoinTypeSwitch<NLTYPE,
|
152
|
-
|
144
|
+
return NestedLoopJoinTypeSwitch<NLTYPE, GreaterThan>(left, right, left_size, right_size, lpos, rpos, lvector,
|
145
|
+
rvector, current_match_count);
|
153
146
|
case ExpressionType::COMPARE_LESSTHANOREQUALTO:
|
154
|
-
return NestedLoopJoinTypeSwitch<NLTYPE,
|
155
|
-
|
147
|
+
return NestedLoopJoinTypeSwitch<NLTYPE, LessThanEquals>(left, right, left_size, right_size, lpos, rpos, lvector,
|
148
|
+
rvector, current_match_count);
|
156
149
|
case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
|
157
|
-
return NestedLoopJoinTypeSwitch<NLTYPE,
|
158
|
-
|
150
|
+
return NestedLoopJoinTypeSwitch<NLTYPE, GreaterThanEquals>(left, right, left_size, right_size, lpos, rpos,
|
151
|
+
lvector, rvector, current_match_count);
|
159
152
|
case ExpressionType::COMPARE_DISTINCT_FROM:
|
160
|
-
return NestedLoopJoinTypeSwitch<NLTYPE,
|
161
|
-
|
153
|
+
return NestedLoopJoinTypeSwitch<NLTYPE, DistinctFrom>(left, right, left_size, right_size, lpos, rpos, lvector,
|
154
|
+
rvector, current_match_count);
|
162
155
|
default:
|
163
156
|
throw NotImplementedException("Unimplemented comparison type for join!");
|
164
157
|
}
|
@@ -6,6 +6,8 @@ namespace duckdb {
|
|
6
6
|
|
7
7
|
template <class T, class OP>
|
8
8
|
static void TemplatedMarkJoin(Vector &left, Vector &right, idx_t lcount, idx_t rcount, bool found_match[]) {
|
9
|
+
using MATCH_OP = ComparisonOperationWrapper<OP>;
|
10
|
+
|
9
11
|
UnifiedVectorFormat left_data, right_data;
|
10
12
|
left.ToUnifiedFormat(lcount, left_data);
|
11
13
|
right.ToUnifiedFormat(rcount, right_data);
|
@@ -17,15 +19,17 @@ static void TemplatedMarkJoin(Vector &left, Vector &right, idx_t lcount, idx_t r
|
|
17
19
|
continue;
|
18
20
|
}
|
19
21
|
auto lidx = left_data.sel->get_index(i);
|
20
|
-
|
22
|
+
const auto left_null = !left_data.validity.RowIsValid(lidx);
|
23
|
+
if (!MATCH_OP::COMPARE_NULL && left_null) {
|
21
24
|
continue;
|
22
25
|
}
|
23
26
|
for (idx_t j = 0; j < rcount; j++) {
|
24
27
|
auto ridx = right_data.sel->get_index(j);
|
25
|
-
|
28
|
+
const auto right_null = !right_data.validity.RowIsValid(ridx);
|
29
|
+
if (!MATCH_OP::COMPARE_NULL && right_null) {
|
26
30
|
continue;
|
27
31
|
}
|
28
|
-
if (
|
32
|
+
if (MATCH_OP::template Operation<T>(ldata[lidx], rdata[ridx], left_null, right_null)) {
|
29
33
|
found_match[i] = true;
|
30
34
|
break;
|
31
35
|
}
|
@@ -62,6 +66,12 @@ static void MarkJoinNested(Vector &left, Vector &right, idx_t lcount, idx_t rcou
|
|
62
66
|
case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
|
63
67
|
count = VectorOperations::GreaterThanEquals(left_reference, right, nullptr, rcount, nullptr, nullptr);
|
64
68
|
break;
|
69
|
+
case ExpressionType::COMPARE_DISTINCT_FROM:
|
70
|
+
count = VectorOperations::DistinctFrom(left_reference, right, nullptr, rcount, nullptr, nullptr);
|
71
|
+
break;
|
72
|
+
case ExpressionType::COMPARE_NOT_DISTINCT_FROM:
|
73
|
+
count = VectorOperations::NotDistinctFrom(left_reference, right, nullptr, rcount, nullptr, nullptr);
|
74
|
+
break;
|
65
75
|
default:
|
66
76
|
throw InternalException("Unsupported comparison type for MarkJoinNested");
|
67
77
|
}
|
@@ -116,17 +126,19 @@ static void MarkJoinComparisonSwitch(Vector &left, Vector &right, idx_t lcount,
|
|
116
126
|
D_ASSERT(left.GetType() == right.GetType());
|
117
127
|
switch (comparison_type) {
|
118
128
|
case ExpressionType::COMPARE_EQUAL:
|
119
|
-
return MarkJoinSwitch<
|
129
|
+
return MarkJoinSwitch<Equals>(left, right, lcount, rcount, found_match);
|
120
130
|
case ExpressionType::COMPARE_NOTEQUAL:
|
121
|
-
return MarkJoinSwitch<
|
131
|
+
return MarkJoinSwitch<NotEquals>(left, right, lcount, rcount, found_match);
|
122
132
|
case ExpressionType::COMPARE_LESSTHAN:
|
123
|
-
return MarkJoinSwitch<
|
133
|
+
return MarkJoinSwitch<LessThan>(left, right, lcount, rcount, found_match);
|
124
134
|
case ExpressionType::COMPARE_GREATERTHAN:
|
125
|
-
return MarkJoinSwitch<
|
135
|
+
return MarkJoinSwitch<GreaterThan>(left, right, lcount, rcount, found_match);
|
126
136
|
case ExpressionType::COMPARE_LESSTHANOREQUALTO:
|
127
|
-
return MarkJoinSwitch<
|
137
|
+
return MarkJoinSwitch<LessThanEquals>(left, right, lcount, rcount, found_match);
|
128
138
|
case ExpressionType::COMPARE_GREATERTHANOREQUALTO:
|
129
|
-
return MarkJoinSwitch<
|
139
|
+
return MarkJoinSwitch<GreaterThanEquals>(left, right, lcount, rcount, found_match);
|
140
|
+
case ExpressionType::COMPARE_DISTINCT_FROM:
|
141
|
+
return MarkJoinSwitch<DistinctFrom>(left, right, lcount, rcount, found_match);
|
130
142
|
default:
|
131
143
|
throw NotImplementedException("Unimplemented comparison type for join!");
|
132
144
|
}
|
@@ -343,8 +343,8 @@ void PhysicalHashAggregate::SinkDistinct(ExecutionContext &context, DataChunk &c
|
|
343
343
|
|
344
344
|
SinkResultType PhysicalHashAggregate::Sink(ExecutionContext &context, DataChunk &chunk,
|
345
345
|
OperatorSinkInput &input) const {
|
346
|
-
auto &
|
347
|
-
auto &
|
346
|
+
auto &local_state = input.local_state.Cast<HashAggregateLocalSinkState>();
|
347
|
+
auto &global_state = input.global_state.Cast<HashAggregateGlobalSinkState>();
|
348
348
|
|
349
349
|
if (distinct_collection_info) {
|
350
350
|
SinkDistinct(context, chunk, input);
|
@@ -354,8 +354,7 @@ SinkResultType PhysicalHashAggregate::Sink(ExecutionContext &context, DataChunk
|
|
354
354
|
return SinkResultType::NEED_MORE_INPUT;
|
355
355
|
}
|
356
356
|
|
357
|
-
DataChunk &aggregate_input_chunk =
|
358
|
-
|
357
|
+
DataChunk &aggregate_input_chunk = local_state.aggregate_input_chunk;
|
359
358
|
auto &aggregates = grouped_aggregate_data.aggregates;
|
360
359
|
idx_t aggregate_input_idx = 0;
|
361
360
|
|
@@ -385,10 +384,11 @@ SinkResultType PhysicalHashAggregate::Sink(ExecutionContext &context, DataChunk
|
|
385
384
|
|
386
385
|
// For every grouping set there is one radix_table
|
387
386
|
for (idx_t i = 0; i < groupings.size(); i++) {
|
388
|
-
auto &
|
389
|
-
auto &
|
387
|
+
auto &grouping_local_state = global_state.grouping_states[i];
|
388
|
+
auto &grouping_global_state = local_state.grouping_states[i];
|
390
389
|
InterruptState interrupt_state;
|
391
|
-
OperatorSinkInput sink_input {*
|
390
|
+
OperatorSinkInput sink_input {*grouping_local_state.table_state, *grouping_global_state.table_state,
|
391
|
+
interrupt_state};
|
392
392
|
|
393
393
|
auto &grouping = groupings[i];
|
394
394
|
auto &table = grouping.table_data;
|
@@ -437,7 +437,7 @@ void CSVReaderOptions::FromNamedParameters(named_parameter_map_t &in, ClientCont
|
|
437
437
|
}
|
438
438
|
sql_type_list.reserve(sql_type_names.size());
|
439
439
|
for (auto &sql_type : sql_type_names) {
|
440
|
-
auto def_type = TransformStringToLogicalType(sql_type);
|
440
|
+
auto def_type = TransformStringToLogicalType(sql_type, context);
|
441
441
|
if (def_type.id() == LogicalTypeId::USER) {
|
442
442
|
throw BinderException("Unrecognized type \"%s\" for read_csv_auto %s definition", sql_type,
|
443
443
|
kv.first);
|
@@ -134,6 +134,10 @@ BoundCastInfo DefaultCasts::TimestampMsCastSwitch(BindCastInput &input, const Lo
|
|
134
134
|
// timestamp (ms) to timestamp (us)
|
135
135
|
return BoundCastInfo(
|
136
136
|
&VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampMsToUs>);
|
137
|
+
case LogicalTypeId::TIMESTAMP_NS:
|
138
|
+
// timestamp (ms) to timestamp (ns)
|
139
|
+
return BoundCastInfo(
|
140
|
+
&VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampMsToNs>);
|
137
141
|
default:
|
138
142
|
return TryVectorNullCast;
|
139
143
|
}
|
@@ -146,10 +150,18 @@ BoundCastInfo DefaultCasts::TimestampSecCastSwitch(BindCastInput &input, const L
|
|
146
150
|
case LogicalTypeId::VARCHAR:
|
147
151
|
// timestamp (sec) to varchar
|
148
152
|
return BoundCastInfo(&VectorCastHelpers::StringCast<timestamp_t, duckdb::CastFromTimestampSec>);
|
153
|
+
case LogicalTypeId::TIMESTAMP_MS:
|
154
|
+
// timestamp (s) to timestamp (ms)
|
155
|
+
return BoundCastInfo(
|
156
|
+
&VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampSecToMs>);
|
149
157
|
case LogicalTypeId::TIMESTAMP:
|
150
158
|
// timestamp (s) to timestamp (us)
|
151
159
|
return BoundCastInfo(
|
152
160
|
&VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampSecToUs>);
|
161
|
+
case LogicalTypeId::TIMESTAMP_NS:
|
162
|
+
// timestamp (s) to timestamp (ns)
|
163
|
+
return BoundCastInfo(
|
164
|
+
&VectorCastHelpers::TemplatedCastLoop<timestamp_t, timestamp_t, duckdb::CastTimestampSecToNs>);
|
153
165
|
default:
|
154
166
|
return TryVectorNullCast;
|
155
167
|
}
|
@@ -124,12 +124,15 @@ string PragmaShow(ClientContext &context, const FunctionParameters ¶meters)
|
|
124
124
|
ON cols.column_name = pragma_table_info.name
|
125
125
|
AND cols.table_name='%table_name%'
|
126
126
|
AND cols.schema_name='%table_schema%'
|
127
|
+
AND cols.database_name = '%table_database%'
|
127
128
|
ORDER BY column_index;)";
|
128
129
|
// clang-format on
|
129
130
|
|
130
131
|
sql = StringUtil::Replace(sql, "%func_param_table%", parameters.values[0].ToString());
|
131
132
|
sql = StringUtil::Replace(sql, "%table_name%", table.name);
|
132
133
|
sql = StringUtil::Replace(sql, "%table_schema%", table.schema.empty() ? DEFAULT_SCHEMA : table.schema);
|
134
|
+
sql = StringUtil::Replace(sql, "%table_database%",
|
135
|
+
table.catalog.empty() ? DatabaseManager::GetDefaultDatabase(context) : table.catalog);
|
133
136
|
return sql;
|
134
137
|
}
|
135
138
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
2
|
-
#define DUCKDB_VERSION "0.8.2-
|
2
|
+
#define DUCKDB_VERSION "0.8.2-dev5002"
|
3
3
|
#endif
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
5
|
+
#define DUCKDB_SOURCE_ID "239f51293c"
|
6
6
|
#endif
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
8
8
|
#include "duckdb/main/database.hpp"
|
@@ -182,6 +182,11 @@ struct MultiFileReader {
|
|
182
182
|
}
|
183
183
|
}
|
184
184
|
for (idx_t r = 0; r < data.union_readers.size(); r++) {
|
185
|
+
if (!data.union_readers[r]) {
|
186
|
+
data.union_readers.erase(data.union_readers.begin() + r);
|
187
|
+
r--;
|
188
|
+
continue;
|
189
|
+
}
|
185
190
|
// check if the union reader should still be read or not
|
186
191
|
auto entry = file_set.find(data.union_readers[r]->GetFileName());
|
187
192
|
if (entry == file_set.end()) {
|
@@ -632,6 +632,13 @@ struct CastTimestampMsToUs {
|
|
632
632
|
}
|
633
633
|
};
|
634
634
|
|
635
|
+
struct CastTimestampMsToNs {
|
636
|
+
template <class SRC, class DST>
|
637
|
+
static inline DST Operation(SRC input) {
|
638
|
+
throw duckdb::NotImplementedException("Cast to TIMESTAMP_NS could not be performed!");
|
639
|
+
}
|
640
|
+
};
|
641
|
+
|
635
642
|
struct CastTimestampNsToUs {
|
636
643
|
template <class SRC, class DST>
|
637
644
|
static inline DST Operation(SRC input) {
|
@@ -639,6 +646,13 @@ struct CastTimestampNsToUs {
|
|
639
646
|
}
|
640
647
|
};
|
641
648
|
|
649
|
+
struct CastTimestampSecToMs {
|
650
|
+
template <class SRC, class DST>
|
651
|
+
static inline DST Operation(SRC input) {
|
652
|
+
throw duckdb::NotImplementedException("Cast to TIMESTAMP_MS could not be performed!");
|
653
|
+
}
|
654
|
+
};
|
655
|
+
|
642
656
|
struct CastTimestampSecToUs {
|
643
657
|
template <class SRC, class DST>
|
644
658
|
static inline DST Operation(SRC input) {
|
@@ -646,6 +660,13 @@ struct CastTimestampSecToUs {
|
|
646
660
|
}
|
647
661
|
};
|
648
662
|
|
663
|
+
struct CastTimestampSecToNs {
|
664
|
+
template <class SRC, class DST>
|
665
|
+
static inline DST Operation(SRC input) {
|
666
|
+
throw duckdb::NotImplementedException("Cast to TIMESTAMP_NS could not be performed!");
|
667
|
+
}
|
668
|
+
};
|
669
|
+
|
649
670
|
template <>
|
650
671
|
duckdb::timestamp_t CastTimestampUsToMs::Operation(duckdb::timestamp_t input);
|
651
672
|
template <>
|
@@ -655,9 +676,15 @@ duckdb::timestamp_t CastTimestampUsToSec::Operation(duckdb::timestamp_t input);
|
|
655
676
|
template <>
|
656
677
|
duckdb::timestamp_t CastTimestampMsToUs::Operation(duckdb::timestamp_t input);
|
657
678
|
template <>
|
679
|
+
duckdb::timestamp_t CastTimestampMsToNs::Operation(duckdb::timestamp_t input);
|
680
|
+
template <>
|
658
681
|
duckdb::timestamp_t CastTimestampNsToUs::Operation(duckdb::timestamp_t input);
|
659
682
|
template <>
|
683
|
+
duckdb::timestamp_t CastTimestampSecToMs::Operation(duckdb::timestamp_t input);
|
684
|
+
template <>
|
660
685
|
duckdb::timestamp_t CastTimestampSecToUs::Operation(duckdb::timestamp_t input);
|
686
|
+
template <>
|
687
|
+
duckdb::timestamp_t CastTimestampSecToNs::Operation(duckdb::timestamp_t input);
|
661
688
|
|
662
689
|
template <>
|
663
690
|
duckdb::string_t CastFromTimestampNS::Operation(duckdb::timestamp_t input, Vector &result);
|