duckdb 0.7.2-dev717.0 → 0.7.2-dev865.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/binding.gyp +2 -0
- package/lib/duckdb.d.ts +12 -1
- package/lib/duckdb.js +19 -0
- package/package.json +1 -1
- package/src/duckdb/extension/json/include/json_common.hpp +1 -0
- package/src/duckdb/extension/json/include/json_functions.hpp +1 -0
- package/src/duckdb/extension/json/include/json_serializer.hpp +77 -0
- package/src/duckdb/extension/json/json_functions/json_serialize_sql.cpp +147 -0
- package/src/duckdb/extension/json/json_functions.cpp +1 -0
- package/src/duckdb/extension/json/json_scan.cpp +2 -2
- package/src/duckdb/extension/json/json_serializer.cpp +217 -0
- package/src/duckdb/src/catalog/catalog.cpp +21 -5
- package/src/duckdb/src/common/enums/expression_type.cpp +8 -222
- package/src/duckdb/src/common/enums/join_type.cpp +3 -22
- package/src/duckdb/src/common/exception.cpp +2 -2
- package/src/duckdb/src/common/serializer/enum_serializer.cpp +1172 -0
- package/src/duckdb/src/common/types/value.cpp +117 -93
- package/src/duckdb/src/common/types/vector.cpp +140 -1
- package/src/duckdb/src/common/types.cpp +166 -89
- package/src/duckdb/src/execution/operator/helper/physical_limit.cpp +3 -0
- package/src/duckdb/src/execution/physical_plan/plan_aggregate.cpp +5 -8
- package/src/duckdb/src/function/scalar/date/date_part.cpp +2 -2
- package/src/duckdb/src/function/scalar/date/date_trunc.cpp +2 -2
- package/src/duckdb/src/function/scalar/list/list_aggregates.cpp +1 -1
- package/src/duckdb/src/function/scalar/list/list_lambdas.cpp +4 -0
- package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +8 -8
- package/src/duckdb/src/function/scalar/string/regexp/regexp_extract_all.cpp +243 -0
- package/src/duckdb/src/function/scalar/string/regexp/regexp_util.cpp +79 -0
- package/src/duckdb/src/function/scalar/string/regexp.cpp +21 -80
- package/src/duckdb/src/function/table/arrow_conversion.cpp +7 -1
- package/src/duckdb/src/function/table/table_scan.cpp +1 -1
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/enums/aggregate_handling.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/enums/expression_type.hpp +2 -3
- package/src/duckdb/src/include/duckdb/common/enums/joinref_type.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/enums/order_type.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/enums/set_operation_type.hpp +2 -1
- package/src/duckdb/src/include/duckdb/common/exception.hpp +40 -9
- package/src/duckdb/src/include/duckdb/common/preserved_error.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/serializer/enum_serializer.hpp +113 -0
- package/src/duckdb/src/include/duckdb/common/serializer/format_deserializer.hpp +336 -0
- package/src/duckdb/src/include/duckdb/common/serializer/format_serializer.hpp +268 -0
- package/src/duckdb/src/include/duckdb/common/serializer/serialization_traits.hpp +126 -0
- package/src/duckdb/src/include/duckdb/common/string_util.hpp +12 -0
- package/src/duckdb/src/include/duckdb/common/types/value.hpp +2 -31
- package/src/duckdb/src/include/duckdb/common/types/vector.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/types.hpp +8 -2
- package/src/duckdb/src/include/duckdb/function/scalar/regexp.hpp +81 -1
- package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/common_table_expression_info.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/between_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/expression/bound_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/case_expression.hpp +5 -0
- package/src/duckdb/src/include/duckdb/parser/expression/cast_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/collate_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/columnref_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/comparison_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/conjunction_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/constant_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/expression/default_expression.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/expression/function_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/lambda_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/operator_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/parameter_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/positional_reference_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/star_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/subquery_expression.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/expression/window_expression.hpp +5 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/sample_options.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_expression.hpp +5 -0
- package/src/duckdb/src/include/duckdb/parser/query_node/recursive_cte_node.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +5 -0
- package/src/duckdb/src/include/duckdb/parser/query_node/set_operation_node.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/query_node.hpp +11 -1
- package/src/duckdb/src/include/duckdb/parser/result_modifier.hpp +24 -1
- package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +6 -1
- package/src/duckdb/src/include/duckdb/parser/tableref/basetableref.hpp +4 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/emptytableref.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/expressionlistref.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/joinref.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/pivotref.hpp +9 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/table_function_ref.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/tableref.hpp +3 -1
- package/src/duckdb/src/include/duckdb/storage/statistics/numeric_stats.hpp +9 -52
- package/src/duckdb/src/include/duckdb/storage/statistics/numeric_stats_union.hpp +62 -0
- package/src/duckdb/src/include/duckdb/storage/table/column_checkpoint_state.hpp +2 -1
- package/src/duckdb/src/include/duckdb/storage/table/column_data.hpp +6 -3
- package/src/duckdb/src/include/duckdb/storage/table/column_data_checkpointer.hpp +3 -2
- package/src/duckdb/src/include/duckdb/storage/table/column_segment.hpp +5 -3
- package/src/duckdb/src/include/duckdb/storage/table/persistent_table_data.hpp +4 -1
- package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +6 -3
- package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +5 -3
- package/src/duckdb/src/include/duckdb/storage/table/row_group_segment_tree.hpp +37 -0
- package/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +8 -1
- package/src/duckdb/src/include/duckdb/storage/table/segment_base.hpp +4 -3
- package/src/duckdb/src/include/duckdb/storage/table/segment_tree.hpp +271 -26
- package/src/duckdb/src/main/extension/extension_install.cpp +7 -2
- package/src/duckdb/src/optimizer/deliminator.cpp +1 -1
- package/src/duckdb/src/optimizer/filter_combiner.cpp +1 -1
- package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +3 -3
- package/src/duckdb/src/optimizer/rule/move_constants.cpp +2 -2
- package/src/duckdb/src/optimizer/statistics/operator/propagate_filter.cpp +1 -1
- package/src/duckdb/src/parser/common_table_expression_info.cpp +19 -0
- package/src/duckdb/src/parser/expression/between_expression.cpp +17 -0
- package/src/duckdb/src/parser/expression/case_expression.cpp +28 -0
- package/src/duckdb/src/parser/expression/cast_expression.cpp +17 -0
- package/src/duckdb/src/parser/expression/collate_expression.cpp +16 -0
- package/src/duckdb/src/parser/expression/columnref_expression.cpp +15 -0
- package/src/duckdb/src/parser/expression/comparison_expression.cpp +16 -0
- package/src/duckdb/src/parser/expression/conjunction_expression.cpp +15 -0
- package/src/duckdb/src/parser/expression/constant_expression.cpp +14 -0
- package/src/duckdb/src/parser/expression/default_expression.cpp +7 -0
- package/src/duckdb/src/parser/expression/function_expression.cpp +35 -0
- package/src/duckdb/src/parser/expression/lambda_expression.cpp +16 -0
- package/src/duckdb/src/parser/expression/operator_expression.cpp +15 -0
- package/src/duckdb/src/parser/expression/parameter_expression.cpp +15 -0
- package/src/duckdb/src/parser/expression/positional_reference_expression.cpp +14 -0
- package/src/duckdb/src/parser/expression/star_expression.cpp +20 -0
- package/src/duckdb/src/parser/expression/subquery_expression.cpp +20 -0
- package/src/duckdb/src/parser/expression/window_expression.cpp +43 -0
- package/src/duckdb/src/parser/parsed_data/sample_options.cpp +22 -10
- package/src/duckdb/src/parser/parsed_expression.cpp +72 -0
- package/src/duckdb/src/parser/query_node/recursive_cte_node.cpp +21 -0
- package/src/duckdb/src/parser/query_node/select_node.cpp +31 -0
- package/src/duckdb/src/parser/query_node/set_operation_node.cpp +17 -0
- package/src/duckdb/src/parser/query_node.cpp +50 -0
- package/src/duckdb/src/parser/result_modifier.cpp +78 -0
- package/src/duckdb/src/parser/statement/select_statement.cpp +12 -0
- package/src/duckdb/src/parser/tableref/basetableref.cpp +21 -0
- package/src/duckdb/src/parser/tableref/emptytableref.cpp +4 -0
- package/src/duckdb/src/parser/tableref/expressionlistref.cpp +17 -0
- package/src/duckdb/src/parser/tableref/joinref.cpp +25 -0
- package/src/duckdb/src/parser/tableref/pivotref.cpp +53 -0
- package/src/duckdb/src/parser/tableref/subqueryref.cpp +15 -0
- package/src/duckdb/src/parser/tableref/table_function.cpp +17 -0
- package/src/duckdb/src/parser/tableref.cpp +46 -0
- package/src/duckdb/src/parser/transform/expression/transform_array_access.cpp +11 -0
- package/src/duckdb/src/parser/transform/expression/transform_bool_expr.cpp +1 -1
- package/src/duckdb/src/parser/transform/expression/transform_operator.cpp +1 -1
- package/src/duckdb/src/parser/transform/expression/transform_subquery.cpp +1 -1
- package/src/duckdb/src/planner/binder/expression/bind_function_expression.cpp +22 -4
- package/src/duckdb/src/planner/binder/expression/bind_subquery_expression.cpp +4 -0
- package/src/duckdb/src/planner/binder/tableref/plan_joinref.cpp +1 -1
- package/src/duckdb/src/planner/expression/bound_expression.cpp +4 -0
- package/src/duckdb/src/storage/checkpoint/table_data_reader.cpp +3 -11
- package/src/duckdb/src/storage/checkpoint/table_data_writer.cpp +6 -0
- package/src/duckdb/src/storage/checkpoint_manager.cpp +1 -0
- package/src/duckdb/src/storage/compression/numeric_constant.cpp +2 -2
- package/src/duckdb/src/storage/data_table.cpp +1 -1
- package/src/duckdb/src/storage/statistics/numeric_stats.cpp +145 -83
- package/src/duckdb/src/storage/statistics/numeric_stats_union.cpp +65 -0
- package/src/duckdb/src/storage/storage_info.cpp +1 -1
- package/src/duckdb/src/storage/table/column_checkpoint_state.cpp +1 -6
- package/src/duckdb/src/storage/table/column_data.cpp +29 -35
- package/src/duckdb/src/storage/table/column_data_checkpointer.cpp +5 -5
- package/src/duckdb/src/storage/table/column_segment.cpp +8 -7
- package/src/duckdb/src/storage/table/list_column_data.cpp +2 -1
- package/src/duckdb/src/storage/table/persistent_table_data.cpp +2 -1
- package/src/duckdb/src/storage/table/row_group.cpp +9 -9
- package/src/duckdb/src/storage/table/row_group_collection.cpp +82 -66
- package/src/duckdb/src/storage/table/scan_state.cpp +22 -3
- package/src/duckdb/src/storage/table/standard_column_data.cpp +1 -0
- package/src/duckdb/src/storage/table/struct_column_data.cpp +1 -0
- package/src/duckdb/src/verification/deserialized_statement_verifier.cpp +0 -1
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +11780 -11512
- package/src/duckdb/third_party/re2/re2/re2.cc +9 -0
- package/src/duckdb/third_party/re2/re2/re2.h +2 -0
- package/src/duckdb/ub_extension_json_json_functions.cpp +2 -0
- package/src/duckdb/ub_src_common_serializer.cpp +2 -0
- package/src/duckdb/ub_src_function_scalar_string_regexp.cpp +4 -0
- package/src/duckdb/ub_src_parser.cpp +2 -0
- package/src/duckdb/ub_src_storage_statistics.cpp +2 -0
- package/src/duckdb/ub_src_storage_table.cpp +0 -2
- package/src/utils.cpp +12 -0
- package/test/extension.test.ts +44 -26
- package/src/duckdb/src/storage/table/segment_tree.cpp +0 -179
@@ -25,10 +25,12 @@ class RowGroupCollection;
|
|
25
25
|
class UpdateSegment;
|
26
26
|
class TableScanState;
|
27
27
|
class ColumnSegment;
|
28
|
+
class ColumnSegmentTree;
|
28
29
|
class ValiditySegment;
|
29
30
|
class TableFilterSet;
|
30
31
|
class ColumnData;
|
31
32
|
class DuckTransaction;
|
33
|
+
class RowGroupSegmentTree;
|
32
34
|
|
33
35
|
struct SegmentScanState {
|
34
36
|
virtual ~SegmentScanState() {
|
@@ -45,6 +47,8 @@ typedef unordered_map<block_id_t, BufferHandle> buffer_handle_set_t;
|
|
45
47
|
struct ColumnScanState {
|
46
48
|
//! The column segment that is currently being scanned
|
47
49
|
ColumnSegment *current = nullptr;
|
50
|
+
//! Column segment tree
|
51
|
+
ColumnSegmentTree *segment_tree = nullptr;
|
48
52
|
//! The current row index of the scan
|
49
53
|
idx_t row_index = 0;
|
50
54
|
//! The internal row index (i.e. the position of the SegmentScanState)
|
@@ -114,10 +118,12 @@ private:
|
|
114
118
|
class CollectionScanState {
|
115
119
|
public:
|
116
120
|
CollectionScanState(TableScanState &parent_p)
|
117
|
-
: row_group_state(*this), max_row(0), batch_index(0), parent(parent_p) {};
|
121
|
+
: row_group_state(*this), row_groups(nullptr), max_row(0), batch_index(0), parent(parent_p) {};
|
118
122
|
|
119
123
|
//! The row_group scan state
|
120
124
|
RowGroupScanState row_group_state;
|
125
|
+
//! Row group segment tree
|
126
|
+
RowGroupSegmentTree *row_groups;
|
121
127
|
//! The total maximum row index
|
122
128
|
idx_t max_row;
|
123
129
|
//! The current batch index
|
@@ -129,6 +135,7 @@ public:
|
|
129
135
|
AdaptiveFilter *GetAdaptiveFilter();
|
130
136
|
bool Scan(DuckTransaction &transaction, DataChunk &result);
|
131
137
|
bool ScanCommitted(DataChunk &result, TableScanType type);
|
138
|
+
bool ScanCommitted(DataChunk &result, SegmentLock &l, TableScanType type);
|
132
139
|
|
133
140
|
private:
|
134
141
|
TableScanState &parent;
|
@@ -13,13 +13,14 @@
|
|
13
13
|
|
14
14
|
namespace duckdb {
|
15
15
|
|
16
|
+
template <class T>
|
16
17
|
class SegmentBase {
|
17
18
|
public:
|
18
19
|
SegmentBase(idx_t start, idx_t count) : start(start), count(count), next(nullptr) {
|
19
20
|
}
|
20
21
|
virtual ~SegmentBase() {
|
21
22
|
}
|
22
|
-
|
23
|
+
T *Next() {
|
23
24
|
#ifndef DUCKDB_R_BUILD
|
24
25
|
return next.load();
|
25
26
|
#else
|
@@ -34,9 +35,9 @@ public:
|
|
34
35
|
//! The next segment after this one
|
35
36
|
|
36
37
|
#ifndef DUCKDB_R_BUILD
|
37
|
-
atomic<
|
38
|
+
atomic<T *> next;
|
38
39
|
#else
|
39
|
-
|
40
|
+
T *next;
|
40
41
|
#endif
|
41
42
|
};
|
42
43
|
|
@@ -10,71 +10,316 @@
|
|
10
10
|
|
11
11
|
#include "duckdb/common/constants.hpp"
|
12
12
|
#include "duckdb/storage/storage_lock.hpp"
|
13
|
-
#include "duckdb/storage/table/segment_base.hpp"
|
14
13
|
#include "duckdb/storage/table/segment_lock.hpp"
|
15
14
|
#include "duckdb/common/vector.hpp"
|
16
15
|
#include "duckdb/common/mutex.hpp"
|
16
|
+
#include "duckdb/common/string_util.hpp"
|
17
17
|
|
18
18
|
namespace duckdb {
|
19
19
|
|
20
|
+
template <class T>
|
20
21
|
struct SegmentNode {
|
21
22
|
idx_t row_start;
|
22
|
-
unique_ptr<
|
23
|
+
unique_ptr<T> node;
|
23
24
|
};
|
24
25
|
|
25
26
|
//! The SegmentTree maintains a list of all segments of a specific column in a table, and allows searching for a segment
|
26
27
|
//! by row number
|
28
|
+
template <class T, bool SUPPORTS_LAZY_LOADING = false>
|
27
29
|
class SegmentTree {
|
30
|
+
private:
|
31
|
+
class SegmentIterationHelper;
|
32
|
+
|
28
33
|
public:
|
34
|
+
explicit SegmentTree() : finished_loading(true) {
|
35
|
+
}
|
36
|
+
virtual ~SegmentTree() {
|
37
|
+
}
|
38
|
+
|
29
39
|
//! Locks the segment tree. All methods to the segment tree either lock the segment tree, or take an already
|
30
40
|
//! obtained lock.
|
31
|
-
SegmentLock Lock()
|
41
|
+
SegmentLock Lock() {
|
42
|
+
return SegmentLock(node_lock);
|
43
|
+
}
|
32
44
|
|
33
|
-
bool IsEmpty(SegmentLock &)
|
45
|
+
bool IsEmpty(SegmentLock &l) {
|
46
|
+
return GetRootSegment(l) == nullptr;
|
47
|
+
}
|
34
48
|
|
35
49
|
//! Gets a pointer to the first segment. Useful for scans.
|
36
|
-
|
37
|
-
|
50
|
+
T *GetRootSegment() {
|
51
|
+
auto l = Lock();
|
52
|
+
return GetRootSegment(l);
|
53
|
+
}
|
54
|
+
|
55
|
+
T *GetRootSegment(SegmentLock &l) {
|
56
|
+
if (nodes.empty()) {
|
57
|
+
LoadNextSegment(l);
|
58
|
+
}
|
59
|
+
return nodes.empty() ? nullptr : nodes[0].node.get();
|
60
|
+
}
|
38
61
|
//! Obtains ownership of the data of the segment tree
|
39
|
-
vector<SegmentNode
|
62
|
+
vector<SegmentNode<T>> MoveSegments(SegmentLock &l) {
|
63
|
+
LoadAllSegments(l);
|
64
|
+
return std::move(nodes);
|
65
|
+
}
|
40
66
|
//! Gets a pointer to the nth segment. Negative numbers start from the back.
|
41
|
-
|
42
|
-
|
67
|
+
T *GetSegmentByIndex(int64_t index) {
|
68
|
+
auto l = Lock();
|
69
|
+
return GetSegmentByIndex(l, index);
|
70
|
+
}
|
71
|
+
T *GetSegmentByIndex(SegmentLock &l, int64_t index) {
|
72
|
+
if (index < 0) {
|
73
|
+
// load all segments
|
74
|
+
LoadAllSegments(l);
|
75
|
+
index = nodes.size() + index;
|
76
|
+
if (index < 0) {
|
77
|
+
return nullptr;
|
78
|
+
}
|
79
|
+
return nodes[index].node.get();
|
80
|
+
} else {
|
81
|
+
// lazily load segments until we reach the specific segment
|
82
|
+
while (idx_t(index) >= nodes.size() && LoadNextSegment(l)) {
|
83
|
+
}
|
84
|
+
if (idx_t(index) >= nodes.size()) {
|
85
|
+
return nullptr;
|
86
|
+
}
|
87
|
+
return nodes[index].node.get();
|
88
|
+
}
|
89
|
+
}
|
90
|
+
//! Gets the next segment
|
91
|
+
T *GetNextSegment(T *segment) {
|
92
|
+
if (!SUPPORTS_LAZY_LOADING) {
|
93
|
+
return segment->Next();
|
94
|
+
}
|
95
|
+
if (finished_loading) {
|
96
|
+
return segment->Next();
|
97
|
+
}
|
98
|
+
auto l = Lock();
|
99
|
+
return GetNextSegment(l, segment);
|
100
|
+
}
|
101
|
+
T *GetNextSegment(SegmentLock &l, T *segment) {
|
102
|
+
if (!segment) {
|
103
|
+
return nullptr;
|
104
|
+
}
|
105
|
+
#ifdef DEBUG
|
106
|
+
D_ASSERT(nodes[segment->index].node.get() == segment);
|
107
|
+
#endif
|
108
|
+
return GetSegmentByIndex(l, segment->index + 1);
|
109
|
+
}
|
43
110
|
|
44
111
|
//! Gets a pointer to the last segment. Useful for appends.
|
45
|
-
|
46
|
-
|
112
|
+
T *GetLastSegment(SegmentLock &l) {
|
113
|
+
LoadAllSegments(l);
|
114
|
+
if (nodes.empty()) {
|
115
|
+
return nullptr;
|
116
|
+
}
|
117
|
+
return nodes.back().node.get();
|
118
|
+
}
|
47
119
|
//! Gets a pointer to a specific column segment for the given row
|
48
|
-
|
49
|
-
|
120
|
+
T *GetSegment(idx_t row_number) {
|
121
|
+
auto l = Lock();
|
122
|
+
return GetSegment(l, row_number);
|
123
|
+
}
|
124
|
+
T *GetSegment(SegmentLock &l, idx_t row_number) {
|
125
|
+
return nodes[GetSegmentIndex(l, row_number)].node.get();
|
126
|
+
}
|
50
127
|
|
51
128
|
//! Append a column segment to the tree
|
52
|
-
void
|
53
|
-
|
129
|
+
void AppendSegmentInternal(SegmentLock &l, unique_ptr<T> segment) {
|
130
|
+
D_ASSERT(segment);
|
131
|
+
// add the node to the list of nodes
|
132
|
+
if (!nodes.empty()) {
|
133
|
+
nodes.back().node->next = segment.get();
|
134
|
+
}
|
135
|
+
SegmentNode<T> node;
|
136
|
+
segment->index = nodes.size();
|
137
|
+
node.row_start = segment->start;
|
138
|
+
node.node = std::move(segment);
|
139
|
+
nodes.push_back(std::move(node));
|
140
|
+
}
|
141
|
+
void AppendSegment(unique_ptr<T> segment) {
|
142
|
+
auto l = Lock();
|
143
|
+
AppendSegment(l, std::move(segment));
|
144
|
+
}
|
145
|
+
void AppendSegment(SegmentLock &l, unique_ptr<T> segment) {
|
146
|
+
LoadAllSegments(l);
|
147
|
+
AppendSegmentInternal(l, std::move(segment));
|
148
|
+
}
|
54
149
|
//! Debug method, check whether the segment is in the segment tree
|
55
|
-
bool HasSegment(
|
56
|
-
|
150
|
+
bool HasSegment(T *segment) {
|
151
|
+
auto l = Lock();
|
152
|
+
return HasSegment(l, segment);
|
153
|
+
}
|
154
|
+
bool HasSegment(SegmentLock &, T *segment) {
|
155
|
+
return segment->index < nodes.size() && nodes[segment->index].node.get() == segment;
|
156
|
+
}
|
57
157
|
|
58
158
|
//! Replace this tree with another tree, taking over its nodes in-place
|
59
|
-
void Replace(SegmentTree &other)
|
60
|
-
|
159
|
+
void Replace(SegmentTree<T> &other) {
|
160
|
+
auto l = Lock();
|
161
|
+
Replace(l, other);
|
162
|
+
}
|
163
|
+
void Replace(SegmentLock &l, SegmentTree<T> &other) {
|
164
|
+
other.LoadAllSegments(l);
|
165
|
+
nodes = std::move(other.nodes);
|
166
|
+
}
|
61
167
|
|
62
168
|
//! Erase all segments after a specific segment
|
63
|
-
void EraseSegments(SegmentLock
|
169
|
+
void EraseSegments(SegmentLock &l, idx_t segment_start) {
|
170
|
+
LoadAllSegments(l);
|
171
|
+
if (segment_start >= nodes.size() - 1) {
|
172
|
+
return;
|
173
|
+
}
|
174
|
+
nodes.erase(nodes.begin() + segment_start + 1, nodes.end());
|
175
|
+
}
|
64
176
|
|
65
177
|
//! Get the segment index of the column segment for the given row
|
66
|
-
idx_t GetSegmentIndex(idx_t row_number)
|
67
|
-
|
68
|
-
|
178
|
+
idx_t GetSegmentIndex(SegmentLock &l, idx_t row_number) {
|
179
|
+
idx_t segment_index;
|
180
|
+
if (TryGetSegmentIndex(l, row_number, segment_index)) {
|
181
|
+
return segment_index;
|
182
|
+
}
|
183
|
+
string error;
|
184
|
+
error = StringUtil::Format("Attempting to find row number \"%lld\" in %lld nodes\n", row_number, nodes.size());
|
185
|
+
for (idx_t i = 0; i < nodes.size(); i++) {
|
186
|
+
error += StringUtil::Format("Node %lld: Start %lld, Count %lld", i, nodes[i].row_start,
|
187
|
+
nodes[i].node->count.load());
|
188
|
+
}
|
189
|
+
throw InternalException("Could not find node in column segment tree!\n%s%s", error, Exception::GetStackTrace());
|
190
|
+
}
|
191
|
+
|
192
|
+
bool TryGetSegmentIndex(SegmentLock &l, idx_t row_number, idx_t &result) {
|
193
|
+
// load segments until the row number is within bounds
|
194
|
+
while (nodes.empty() || (row_number >= (nodes.back().row_start + nodes.back().node->count))) {
|
195
|
+
if (!LoadNextSegment(l)) {
|
196
|
+
break;
|
197
|
+
}
|
198
|
+
}
|
199
|
+
if (nodes.empty()) {
|
200
|
+
return false;
|
201
|
+
}
|
202
|
+
D_ASSERT(!nodes.empty());
|
203
|
+
D_ASSERT(row_number >= nodes[0].row_start);
|
204
|
+
D_ASSERT(row_number < nodes.back().row_start + nodes.back().node->count);
|
205
|
+
idx_t lower = 0;
|
206
|
+
idx_t upper = nodes.size() - 1;
|
207
|
+
// binary search to find the node
|
208
|
+
while (lower <= upper) {
|
209
|
+
idx_t index = (lower + upper) / 2;
|
210
|
+
D_ASSERT(index < nodes.size());
|
211
|
+
auto &entry = nodes[index];
|
212
|
+
D_ASSERT(entry.row_start == entry.node->start);
|
213
|
+
if (row_number < entry.row_start) {
|
214
|
+
upper = index - 1;
|
215
|
+
} else if (row_number >= entry.row_start + entry.node->count) {
|
216
|
+
lower = index + 1;
|
217
|
+
} else {
|
218
|
+
result = index;
|
219
|
+
return true;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
return false;
|
223
|
+
}
|
69
224
|
|
70
|
-
void Verify(SegmentLock &)
|
71
|
-
|
225
|
+
void Verify(SegmentLock &) {
|
226
|
+
#ifdef DEBUG
|
227
|
+
idx_t base_start = nodes.empty() ? 0 : nodes[0].node->start;
|
228
|
+
for (idx_t i = 0; i < nodes.size(); i++) {
|
229
|
+
D_ASSERT(nodes[i].row_start == nodes[i].node->start);
|
230
|
+
D_ASSERT(nodes[i].node->start == base_start);
|
231
|
+
base_start += nodes[i].node->count;
|
232
|
+
}
|
233
|
+
#endif
|
234
|
+
}
|
235
|
+
void Verify() {
|
236
|
+
#ifdef DEBUG
|
237
|
+
auto l = Lock();
|
238
|
+
Verify(l);
|
239
|
+
#endif
|
240
|
+
}
|
241
|
+
|
242
|
+
SegmentIterationHelper Segments() {
|
243
|
+
return SegmentIterationHelper(*this);
|
244
|
+
}
|
245
|
+
|
246
|
+
protected:
|
247
|
+
atomic<bool> finished_loading;
|
248
|
+
|
249
|
+
//! Load the next segment - only used when lazily loading
|
250
|
+
virtual unique_ptr<T> LoadSegment() {
|
251
|
+
return nullptr;
|
252
|
+
}
|
72
253
|
|
73
254
|
private:
|
74
255
|
//! The nodes in the tree, can be binary searched
|
75
|
-
vector<SegmentNode
|
256
|
+
vector<SegmentNode<T>> nodes;
|
76
257
|
//! Lock to access or modify the nodes
|
77
258
|
mutex node_lock;
|
259
|
+
|
260
|
+
private:
|
261
|
+
class SegmentIterationHelper {
|
262
|
+
public:
|
263
|
+
explicit SegmentIterationHelper(SegmentTree &tree) : tree(tree) {
|
264
|
+
}
|
265
|
+
|
266
|
+
private:
|
267
|
+
SegmentTree &tree;
|
268
|
+
|
269
|
+
private:
|
270
|
+
class SegmentIterator {
|
271
|
+
public:
|
272
|
+
SegmentIterator(SegmentTree &tree_p, T *current_p) : tree(tree_p), current(current_p) {
|
273
|
+
}
|
274
|
+
|
275
|
+
SegmentTree &tree;
|
276
|
+
T *current;
|
277
|
+
|
278
|
+
public:
|
279
|
+
void Next() {
|
280
|
+
current = tree.GetNextSegment(current);
|
281
|
+
}
|
282
|
+
|
283
|
+
SegmentIterator &operator++() {
|
284
|
+
Next();
|
285
|
+
return *this;
|
286
|
+
}
|
287
|
+
bool operator!=(const SegmentIterator &other) const {
|
288
|
+
return current != other.current;
|
289
|
+
}
|
290
|
+
T &operator*() const {
|
291
|
+
D_ASSERT(current);
|
292
|
+
return *current;
|
293
|
+
}
|
294
|
+
};
|
295
|
+
|
296
|
+
public:
|
297
|
+
SegmentIterator begin() {
|
298
|
+
return SegmentIterator(tree, tree.GetRootSegment());
|
299
|
+
}
|
300
|
+
SegmentIterator end() {
|
301
|
+
return SegmentIterator(tree, nullptr);
|
302
|
+
}
|
303
|
+
};
|
304
|
+
|
305
|
+
//! Load the next segment, if there are any left to load
|
306
|
+
bool LoadNextSegment(SegmentLock &l) {
|
307
|
+
if (finished_loading) {
|
308
|
+
return false;
|
309
|
+
}
|
310
|
+
auto result = LoadSegment();
|
311
|
+
if (result) {
|
312
|
+
AppendSegmentInternal(l, std::move(result));
|
313
|
+
return true;
|
314
|
+
}
|
315
|
+
return false;
|
316
|
+
}
|
317
|
+
|
318
|
+
//! Load all segments, if there are any left to load
|
319
|
+
void LoadAllSegments(SegmentLock &l) {
|
320
|
+
while (LoadNextSegment(l))
|
321
|
+
;
|
322
|
+
}
|
78
323
|
};
|
79
324
|
|
80
325
|
} // namespace duckdb
|
@@ -206,8 +206,13 @@ void ExtensionHelper::InstallExtensionInternal(DBConfig &config, ClientConfig *c
|
|
206
206
|
if (exact_match) {
|
207
207
|
message += "\nAre you using a development build? In this case, extensions might not (yet) be uploaded.";
|
208
208
|
}
|
209
|
-
|
210
|
-
|
209
|
+
if (res.error() == duckdb_httplib::Error::Success) {
|
210
|
+
throw HTTPException(res.value(), "Failed to download extension \"%s\" at URL \"%s%s\"\n%s", extension_name,
|
211
|
+
url_base, url_local_part, message);
|
212
|
+
} else {
|
213
|
+
throw IOException("Failed to download extension \"%s\" at URL \"%s%s\"\n%s (ERROR %s)", extension_name,
|
214
|
+
url_base, url_local_part, message, to_string(res.error()));
|
215
|
+
}
|
211
216
|
}
|
212
217
|
auto decompressed_body = GZipFileSystem::UncompressGZIPString(res->body);
|
213
218
|
std::ofstream out(temp_path, std::ios::binary);
|
@@ -424,7 +424,7 @@ bool Deliminator::RemoveInequalityCandidate(unique_ptr<LogicalOperator> *plan, u
|
|
424
424
|
parent_expr =
|
425
425
|
make_unique<BoundColumnRefExpression>(parent_expr->alias, parent_expr->return_type, it->first);
|
426
426
|
parent_cond.comparison =
|
427
|
-
parent_delim_get_side == 0 ? child_cond.comparison :
|
427
|
+
parent_delim_get_side == 0 ? child_cond.comparison : FlipComparisonExpression(child_cond.comparison);
|
428
428
|
break;
|
429
429
|
}
|
430
430
|
}
|
@@ -604,7 +604,7 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) {
|
|
604
604
|
|
605
605
|
// create the ExpressionValueInformation
|
606
606
|
ExpressionValueInformation info;
|
607
|
-
info.comparison_type = left_is_scalar ?
|
607
|
+
info.comparison_type = left_is_scalar ? FlipComparisonExpression(comparison.type) : comparison.type;
|
608
608
|
info.constant = constant_value;
|
609
609
|
|
610
610
|
// get the current bucket of constant values
|
@@ -138,7 +138,7 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector<
|
|
138
138
|
std::swap(join.children[0], join.children[1]);
|
139
139
|
for (auto &cond : join.conditions) {
|
140
140
|
std::swap(cond.left, cond.right);
|
141
|
-
cond.comparison =
|
141
|
+
cond.comparison = FlipComparisonExpression(cond.comparison);
|
142
142
|
}
|
143
143
|
}
|
144
144
|
}
|
@@ -769,7 +769,7 @@ JoinOrderOptimizer::GenerateJoins(vector<unique_ptr<LogicalOperator>> &extracted
|
|
769
769
|
|
770
770
|
if (invert) {
|
771
771
|
// reverse comparison expression if we reverse the order of the children
|
772
|
-
cond.comparison =
|
772
|
+
cond.comparison = FlipComparisonExpression(cond.comparison);
|
773
773
|
}
|
774
774
|
join->conditions.push_back(std::move(cond));
|
775
775
|
}
|
@@ -846,7 +846,7 @@ JoinOrderOptimizer::GenerateJoins(vector<unique_ptr<LogicalOperator>> &extracted
|
|
846
846
|
cond.comparison = comparison.type;
|
847
847
|
if (invert) {
|
848
848
|
// reverse comparison expression if we reverse the order of the children
|
849
|
-
cond.comparison =
|
849
|
+
cond.comparison = FlipComparisonExpression(comparison.type);
|
850
850
|
}
|
851
851
|
// now find the join to push it into
|
852
852
|
auto node = result_operator.get();
|
@@ -99,7 +99,7 @@ unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<Expr
|
|
99
99
|
outer_constant->value = std::move(result_value);
|
100
100
|
// in this case, we should also flip the comparison
|
101
101
|
// e.g. if we have [4 - x < 2] then we should have [x > 2]
|
102
|
-
comparison->type =
|
102
|
+
comparison->type = FlipComparisonExpression(comparison->type);
|
103
103
|
}
|
104
104
|
} else {
|
105
105
|
D_ASSERT(op_type == "*");
|
@@ -129,7 +129,7 @@ unique_ptr<Expression> MoveConstantsRule::Apply(LogicalOperator &op, vector<Expr
|
|
129
129
|
}
|
130
130
|
if (inner_value < 0) {
|
131
131
|
// multiply by negative value, need to flip expression
|
132
|
-
comparison->type =
|
132
|
+
comparison->type = FlipComparisonExpression(comparison->type);
|
133
133
|
}
|
134
134
|
// else divide the RHS by the LHS
|
135
135
|
// we need to do a range check on the cast even though we do a division
|
@@ -165,7 +165,7 @@ void StatisticsPropagator::UpdateFilterStatistics(Expression &left, Expression &
|
|
165
165
|
if (left.type == ExpressionType::VALUE_CONSTANT && right.type == ExpressionType::BOUND_COLUMN_REF) {
|
166
166
|
constant = (BoundConstantExpression *)&left;
|
167
167
|
columnref = (BoundColumnRefExpression *)&right;
|
168
|
-
comparison_type =
|
168
|
+
comparison_type = FlipComparisonExpression(comparison_type);
|
169
169
|
} else if (left.type == ExpressionType::BOUND_COLUMN_REF && right.type == ExpressionType::VALUE_CONSTANT) {
|
170
170
|
columnref = (BoundColumnRefExpression *)&left;
|
171
171
|
constant = (BoundConstantExpression *)&right;
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "duckdb/parser/common_table_expression_info.hpp"
|
2
|
+
#include "duckdb/common/serializer/format_serializer.hpp"
|
3
|
+
#include "duckdb/common/serializer/format_deserializer.hpp"
|
4
|
+
|
5
|
+
namespace duckdb {
|
6
|
+
|
7
|
+
void CommonTableExpressionInfo::FormatSerialize(FormatSerializer &serializer) const {
|
8
|
+
serializer.WriteProperty("aliases", aliases);
|
9
|
+
serializer.WriteProperty("query", query);
|
10
|
+
}
|
11
|
+
|
12
|
+
unique_ptr<CommonTableExpressionInfo> CommonTableExpressionInfo::FormatDeserialize(FormatDeserializer &deserializer) {
|
13
|
+
auto result = make_unique<CommonTableExpressionInfo>();
|
14
|
+
result->aliases = deserializer.ReadProperty<vector<string>>("aliases");
|
15
|
+
result->query = deserializer.ReadProperty<unique_ptr<SelectStatement>>("query");
|
16
|
+
return result;
|
17
|
+
}
|
18
|
+
|
19
|
+
} // namespace duckdb
|
@@ -1,5 +1,7 @@
|
|
1
1
|
#include "duckdb/parser/expression/between_expression.hpp"
|
2
2
|
#include "duckdb/common/field_writer.hpp"
|
3
|
+
#include "duckdb/common/serializer/format_serializer.hpp"
|
4
|
+
#include "duckdb/common/serializer/format_deserializer.hpp"
|
3
5
|
|
4
6
|
namespace duckdb {
|
5
7
|
|
@@ -45,4 +47,19 @@ unique_ptr<ParsedExpression> BetweenExpression::Deserialize(ExpressionType type,
|
|
45
47
|
return make_unique<BetweenExpression>(std::move(input), std::move(lower), std::move(upper));
|
46
48
|
}
|
47
49
|
|
50
|
+
void BetweenExpression::FormatSerialize(FormatSerializer &serializer) const {
|
51
|
+
ParsedExpression::FormatSerialize(serializer);
|
52
|
+
serializer.WriteProperty("input", *input);
|
53
|
+
serializer.WriteProperty("lower", *lower);
|
54
|
+
serializer.WriteProperty("upper", *upper);
|
55
|
+
}
|
56
|
+
|
57
|
+
unique_ptr<ParsedExpression> BetweenExpression::FormatDeserialize(ExpressionType type,
|
58
|
+
FormatDeserializer &deserializer) {
|
59
|
+
auto input = deserializer.ReadProperty<unique_ptr<ParsedExpression>>("input");
|
60
|
+
auto lower = deserializer.ReadProperty<unique_ptr<ParsedExpression>>("lower");
|
61
|
+
auto upper = deserializer.ReadProperty<unique_ptr<ParsedExpression>>("upper");
|
62
|
+
return make_unique<BetweenExpression>(std::move(input), std::move(lower), std::move(upper));
|
63
|
+
}
|
64
|
+
|
48
65
|
} // namespace duckdb
|
@@ -3,8 +3,23 @@
|
|
3
3
|
#include "duckdb/common/exception.hpp"
|
4
4
|
#include "duckdb/common/field_writer.hpp"
|
5
5
|
|
6
|
+
#include "duckdb/common/serializer/format_serializer.hpp"
|
7
|
+
#include "duckdb/common/serializer/format_deserializer.hpp"
|
8
|
+
|
6
9
|
namespace duckdb {
|
7
10
|
|
11
|
+
void CaseCheck::FormatSerialize(FormatSerializer &serializer) const {
|
12
|
+
serializer.WriteProperty("when_expr", when_expr);
|
13
|
+
serializer.WriteProperty("then_expr", then_expr);
|
14
|
+
}
|
15
|
+
|
16
|
+
CaseCheck CaseCheck::FormatDeserialize(FormatDeserializer &deserializer) {
|
17
|
+
CaseCheck check;
|
18
|
+
deserializer.ReadProperty("when_expr", check.when_expr);
|
19
|
+
deserializer.ReadProperty("then_expr", check.then_expr);
|
20
|
+
return check;
|
21
|
+
}
|
22
|
+
|
8
23
|
CaseExpression::CaseExpression() : ParsedExpression(ExpressionType::CASE_EXPR, ExpressionClass::CASE) {
|
9
24
|
}
|
10
25
|
|
@@ -69,4 +84,17 @@ unique_ptr<ParsedExpression> CaseExpression::Deserialize(ExpressionType type, Fi
|
|
69
84
|
return std::move(result);
|
70
85
|
}
|
71
86
|
|
87
|
+
void CaseExpression::FormatSerialize(FormatSerializer &serializer) const {
|
88
|
+
ParsedExpression::FormatSerialize(serializer);
|
89
|
+
serializer.WriteProperty("case_checks", case_checks);
|
90
|
+
serializer.WriteProperty("else_expr", *else_expr);
|
91
|
+
}
|
92
|
+
|
93
|
+
unique_ptr<ParsedExpression> CaseExpression::FormatDeserialize(ExpressionType type, FormatDeserializer &deserializer) {
|
94
|
+
auto result = make_unique<CaseExpression>();
|
95
|
+
deserializer.ReadProperty("case_checks", result->case_checks);
|
96
|
+
deserializer.ReadProperty("else_expr", result->else_expr);
|
97
|
+
return std::move(result);
|
98
|
+
}
|
99
|
+
|
72
100
|
} // namespace duckdb
|
@@ -3,6 +3,9 @@
|
|
3
3
|
#include "duckdb/common/exception.hpp"
|
4
4
|
#include "duckdb/common/field_writer.hpp"
|
5
5
|
|
6
|
+
#include "duckdb/common/serializer/format_serializer.hpp"
|
7
|
+
#include "duckdb/common/serializer/format_deserializer.hpp"
|
8
|
+
|
6
9
|
namespace duckdb {
|
7
10
|
|
8
11
|
CastExpression::CastExpression(LogicalType target, unique_ptr<ParsedExpression> child, bool try_cast_p)
|
@@ -48,4 +51,18 @@ unique_ptr<ParsedExpression> CastExpression::Deserialize(ExpressionType type, Fi
|
|
48
51
|
return make_unique_base<ParsedExpression, CastExpression>(cast_type, std::move(child), try_cast);
|
49
52
|
}
|
50
53
|
|
54
|
+
void CastExpression::FormatSerialize(FormatSerializer &serializer) const {
|
55
|
+
ParsedExpression::FormatSerialize(serializer);
|
56
|
+
serializer.WriteProperty("child", *child);
|
57
|
+
serializer.WriteProperty("cast_type", cast_type);
|
58
|
+
serializer.WriteProperty("try_cast", try_cast);
|
59
|
+
}
|
60
|
+
|
61
|
+
unique_ptr<ParsedExpression> CastExpression::FormatDeserialize(ExpressionType type, FormatDeserializer &deserializer) {
|
62
|
+
auto child = deserializer.ReadProperty<unique_ptr<ParsedExpression>>("child");
|
63
|
+
auto cast_type = deserializer.ReadProperty<LogicalType>("cast_type");
|
64
|
+
auto try_cast = deserializer.ReadProperty<bool>("try_cast");
|
65
|
+
return make_unique_base<ParsedExpression, CastExpression>(cast_type, std::move(child), try_cast);
|
66
|
+
}
|
67
|
+
|
51
68
|
} // namespace duckdb
|
@@ -3,6 +3,9 @@
|
|
3
3
|
#include "duckdb/common/exception.hpp"
|
4
4
|
#include "duckdb/common/field_writer.hpp"
|
5
5
|
|
6
|
+
#include "duckdb/common/serializer/format_serializer.hpp"
|
7
|
+
#include "duckdb/common/serializer/format_deserializer.hpp"
|
8
|
+
|
6
9
|
namespace duckdb {
|
7
10
|
|
8
11
|
CollateExpression::CollateExpression(string collation_p, unique_ptr<ParsedExpression> child)
|
@@ -42,4 +45,17 @@ unique_ptr<ParsedExpression> CollateExpression::Deserialize(ExpressionType type,
|
|
42
45
|
return make_unique_base<ParsedExpression, CollateExpression>(collation, std::move(child));
|
43
46
|
}
|
44
47
|
|
48
|
+
void CollateExpression::FormatSerialize(FormatSerializer &serializer) const {
|
49
|
+
ParsedExpression::FormatSerialize(serializer);
|
50
|
+
serializer.WriteProperty("child", *child);
|
51
|
+
serializer.WriteProperty("collation", collation);
|
52
|
+
}
|
53
|
+
|
54
|
+
unique_ptr<ParsedExpression> CollateExpression::FormatDeserialize(ExpressionType type,
|
55
|
+
FormatDeserializer &deserializer) {
|
56
|
+
auto child = deserializer.ReadProperty<unique_ptr<ParsedExpression>>("child");
|
57
|
+
auto collation = deserializer.ReadProperty<string>("collation");
|
58
|
+
return make_unique_base<ParsedExpression, CollateExpression>(collation, std::move(child));
|
59
|
+
}
|
60
|
+
|
45
61
|
} // namespace duckdb
|