duckdb 0.8.2-dev3250.0 → 0.8.2-dev3300.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/extension/parquet/column_reader.cpp +18 -4
- package/src/duckdb/extension/parquet/include/parquet_timestamp.hpp +1 -0
- package/src/duckdb/extension/parquet/include/parquet_writer.hpp +4 -0
- package/src/duckdb/extension/parquet/parquet_extension.cpp +3 -0
- package/src/duckdb/extension/parquet/parquet_statistics.cpp +18 -2
- package/src/duckdb/extension/parquet/parquet_timestamp.cpp +6 -0
- package/src/duckdb/extension/parquet/parquet_writer.cpp +69 -15
- package/src/duckdb/src/common/enum_util.cpp +5 -0
- package/src/duckdb/src/common/operator/cast_operators.cpp +57 -0
- package/src/duckdb/src/common/operator/string_cast.cpp +45 -8
- package/src/duckdb/src/common/types/time.cpp +105 -0
- package/src/duckdb/src/common/types/value.cpp +7 -8
- package/src/duckdb/src/common/types/vector.cpp +1 -1
- package/src/duckdb/src/execution/column_binding_resolver.cpp +7 -0
- package/src/duckdb/src/execution/operator/schema/{physical_create_index.cpp → physical_create_art_index.cpp} +37 -46
- package/src/duckdb/src/execution/physical_plan/plan_create_index.cpp +12 -4
- package/src/duckdb/src/function/cast/string_cast.cpp +2 -1
- package/src/duckdb/src/function/cast/time_casts.cpp +7 -6
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/enums/index_type.hpp +3 -2
- package/src/duckdb/src/include/duckdb/common/operator/cast_operators.hpp +22 -1
- package/src/duckdb/src/include/duckdb/common/operator/string_cast.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/types/datetime.hpp +46 -3
- package/src/duckdb/src/include/duckdb/common/types/time.hpp +5 -0
- package/src/duckdb/src/include/duckdb/common/types/value.hpp +2 -1
- package/src/duckdb/src/include/duckdb/execution/operator/schema/{physical_create_index.hpp → physical_create_art_index.hpp} +5 -5
- package/src/duckdb/src/include/duckdb/function/copy_function.hpp +6 -1
- package/src/duckdb/src/include/duckdb/function/udf_function.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_index_info.hpp +5 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_extension_operator.hpp +3 -0
- package/src/duckdb/src/include/duckdb/storage/data_table.hpp +1 -1
- package/src/duckdb/src/main/appender.cpp +3 -1
- package/src/duckdb/src/main/capi/result-c.cpp +3 -1
- package/src/duckdb/src/parser/parsed_data/create_index_info.cpp +14 -0
- package/src/duckdb/src/parser/transform/statement/transform_create_index.cpp +27 -13
- package/src/duckdb/src/planner/binder/statement/bind_export.cpp +29 -4
- package/src/duckdb/src/planner/operator/logical_extension_operator.cpp +15 -0
- package/src/duckdb/src/storage/index.cpp +3 -25
- package/src/duckdb/src/storage/local_storage.cpp +0 -1
- package/src/duckdb/src/storage/serialization/serialize_create_info.cpp +4 -0
- package/src/duckdb/src/storage/storage_info.cpp +1 -1
- package/src/duckdb/ub_src_execution_operator_schema.cpp +1 -1
- package/test/test_all_types.test.ts +1 -1
@@ -1,4 +1,4 @@
|
|
1
|
-
#include "duckdb/execution/operator/schema/
|
1
|
+
#include "duckdb/execution/operator/schema/physical_create_art_index.hpp"
|
2
2
|
|
3
3
|
#include "duckdb/catalog/catalog_entry/duck_table_entry.hpp"
|
4
4
|
#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp"
|
@@ -14,10 +14,10 @@
|
|
14
14
|
|
15
15
|
namespace duckdb {
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
PhysicalCreateARTIndex::PhysicalCreateARTIndex(LogicalOperator &op, TableCatalogEntry &table_p,
|
18
|
+
const vector<column_t> &column_ids, unique_ptr<CreateIndexInfo> info,
|
19
|
+
vector<unique_ptr<Expression>> unbound_expressions,
|
20
|
+
idx_t estimated_cardinality, const bool sorted)
|
21
21
|
: PhysicalOperator(PhysicalOperatorType::CREATE_INDEX, op.types, estimated_cardinality),
|
22
22
|
table(table_p.Cast<DuckTableEntry>()), info(std::move(info)), unbound_expressions(std::move(unbound_expressions)),
|
23
23
|
sorted(sorted) {
|
@@ -31,15 +31,15 @@ PhysicalCreateIndex::PhysicalCreateIndex(LogicalOperator &op, TableCatalogEntry
|
|
31
31
|
// Sink
|
32
32
|
//===--------------------------------------------------------------------===//
|
33
33
|
|
34
|
-
class
|
34
|
+
class CreateARTIndexGlobalSinkState : public GlobalSinkState {
|
35
35
|
public:
|
36
36
|
//! Global index to be added to the table
|
37
37
|
unique_ptr<Index> global_index;
|
38
38
|
};
|
39
39
|
|
40
|
-
class
|
40
|
+
class CreateARTIndexLocalSinkState : public LocalSinkState {
|
41
41
|
public:
|
42
|
-
explicit
|
42
|
+
explicit CreateARTIndexLocalSinkState(ClientContext &context) : arena_allocator(Allocator::Get(context)) {};
|
43
43
|
|
44
44
|
unique_ptr<Index> local_index;
|
45
45
|
ArenaAllocator arena_allocator;
|
@@ -48,37 +48,26 @@ public:
|
|
48
48
|
vector<column_t> key_column_ids;
|
49
49
|
};
|
50
50
|
|
51
|
-
unique_ptr<GlobalSinkState>
|
52
|
-
auto state = make_uniq<
|
51
|
+
unique_ptr<GlobalSinkState> PhysicalCreateARTIndex::GetGlobalSinkState(ClientContext &context) const {
|
52
|
+
auto state = make_uniq<CreateARTIndexGlobalSinkState>();
|
53
53
|
|
54
54
|
// create the global index
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
info->constraint_type, storage.db);
|
60
|
-
break;
|
61
|
-
}
|
62
|
-
default:
|
63
|
-
throw InternalException("Unimplemented index type");
|
64
|
-
}
|
55
|
+
auto &storage = table.GetStorage();
|
56
|
+
state->global_index = make_uniq<ART>(storage_ids, TableIOManager::Get(storage), unbound_expressions,
|
57
|
+
info->constraint_type, storage.db);
|
58
|
+
|
65
59
|
return (std::move(state));
|
66
60
|
}
|
67
61
|
|
68
|
-
unique_ptr<LocalSinkState>
|
69
|
-
auto state = make_uniq<
|
62
|
+
unique_ptr<LocalSinkState> PhysicalCreateARTIndex::GetLocalSinkState(ExecutionContext &context) const {
|
63
|
+
auto state = make_uniq<CreateARTIndexLocalSinkState>(context.client);
|
70
64
|
|
71
65
|
// create the local index
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
break;
|
78
|
-
}
|
79
|
-
default:
|
80
|
-
throw InternalException("Unimplemented index type");
|
81
|
-
}
|
66
|
+
|
67
|
+
auto &storage = table.GetStorage();
|
68
|
+
state->local_index = make_uniq<ART>(storage_ids, TableIOManager::Get(storage), unbound_expressions,
|
69
|
+
info->constraint_type, storage.db);
|
70
|
+
|
82
71
|
state->keys = vector<ARTKey>(STANDARD_VECTOR_SIZE);
|
83
72
|
state->key_chunk.Initialize(Allocator::Get(context.client), state->local_index->logical_types);
|
84
73
|
|
@@ -88,9 +77,9 @@ unique_ptr<LocalSinkState> PhysicalCreateIndex::GetLocalSinkState(ExecutionConte
|
|
88
77
|
return std::move(state);
|
89
78
|
}
|
90
79
|
|
91
|
-
SinkResultType
|
80
|
+
SinkResultType PhysicalCreateARTIndex::SinkUnsorted(Vector &row_identifiers, OperatorSinkInput &input) const {
|
92
81
|
|
93
|
-
auto &l_state = input.local_state.Cast<
|
82
|
+
auto &l_state = input.local_state.Cast<CreateARTIndexLocalSinkState>();
|
94
83
|
auto count = l_state.key_chunk.size();
|
95
84
|
|
96
85
|
// get the corresponding row IDs
|
@@ -108,9 +97,9 @@ SinkResultType PhysicalCreateIndex::SinkUnsorted(Vector &row_identifiers, Operat
|
|
108
97
|
return SinkResultType::NEED_MORE_INPUT;
|
109
98
|
}
|
110
99
|
|
111
|
-
SinkResultType
|
100
|
+
SinkResultType PhysicalCreateARTIndex::SinkSorted(Vector &row_identifiers, OperatorSinkInput &input) const {
|
112
101
|
|
113
|
-
auto &l_state = input.local_state.Cast<
|
102
|
+
auto &l_state = input.local_state.Cast<CreateARTIndexLocalSinkState>();
|
114
103
|
auto &storage = table.GetStorage();
|
115
104
|
auto &l_index = l_state.local_index;
|
116
105
|
|
@@ -129,12 +118,13 @@ SinkResultType PhysicalCreateIndex::SinkSorted(Vector &row_identifiers, Operator
|
|
129
118
|
return SinkResultType::NEED_MORE_INPUT;
|
130
119
|
}
|
131
120
|
|
132
|
-
SinkResultType
|
121
|
+
SinkResultType PhysicalCreateARTIndex::Sink(ExecutionContext &context, DataChunk &chunk,
|
122
|
+
OperatorSinkInput &input) const {
|
133
123
|
|
134
124
|
D_ASSERT(chunk.ColumnCount() >= 2);
|
135
125
|
|
136
126
|
// generate the keys for the given input
|
137
|
-
auto &l_state = input.local_state.Cast<
|
127
|
+
auto &l_state = input.local_state.Cast<CreateARTIndexLocalSinkState>();
|
138
128
|
l_state.key_chunk.ReferenceColumns(chunk, l_state.key_column_ids);
|
139
129
|
l_state.arena_allocator.Reset();
|
140
130
|
ART::GenerateKeys(l_state.arena_allocator, l_state.key_chunk, l_state.keys);
|
@@ -147,10 +137,11 @@ SinkResultType PhysicalCreateIndex::Sink(ExecutionContext &context, DataChunk &c
|
|
147
137
|
return SinkUnsorted(row_identifiers, input);
|
148
138
|
}
|
149
139
|
|
150
|
-
SinkCombineResultType
|
140
|
+
SinkCombineResultType PhysicalCreateARTIndex::Combine(ExecutionContext &context,
|
141
|
+
OperatorSinkCombineInput &input) const {
|
151
142
|
|
152
|
-
auto &gstate = input.global_state.Cast<
|
153
|
-
auto &lstate = input.local_state.Cast<
|
143
|
+
auto &gstate = input.global_state.Cast<CreateARTIndexGlobalSinkState>();
|
144
|
+
auto &lstate = input.local_state.Cast<CreateARTIndexLocalSinkState>();
|
154
145
|
|
155
146
|
// merge the local index into the global index
|
156
147
|
if (!gstate.global_index->MergeIndexes(*lstate.local_index)) {
|
@@ -160,11 +151,11 @@ SinkCombineResultType PhysicalCreateIndex::Combine(ExecutionContext &context, Op
|
|
160
151
|
return SinkCombineResultType::FINISHED;
|
161
152
|
}
|
162
153
|
|
163
|
-
SinkFinalizeType
|
164
|
-
|
154
|
+
SinkFinalizeType PhysicalCreateARTIndex::Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
155
|
+
OperatorSinkFinalizeInput &input) const {
|
165
156
|
|
166
157
|
// here, we set the resulting global index as the newly created index of the table
|
167
|
-
auto &state = input.global_state.Cast<
|
158
|
+
auto &state = input.global_state.Cast<CreateARTIndexGlobalSinkState>();
|
168
159
|
|
169
160
|
// vacuum excess memory and verify
|
170
161
|
state.global_index->Vacuum();
|
@@ -199,8 +190,8 @@ SinkFinalizeType PhysicalCreateIndex::Finalize(Pipeline &pipeline, Event &event,
|
|
199
190
|
// Source
|
200
191
|
//===--------------------------------------------------------------------===//
|
201
192
|
|
202
|
-
SourceResultType
|
203
|
-
|
193
|
+
SourceResultType PhysicalCreateARTIndex::GetData(ExecutionContext &context, DataChunk &chunk,
|
194
|
+
OperatorSourceInput &input) const {
|
204
195
|
return SourceResultType::FINISHED;
|
205
196
|
}
|
206
197
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp"
|
2
2
|
#include "duckdb/execution/operator/projection/physical_projection.hpp"
|
3
3
|
#include "duckdb/execution/operator/filter/physical_filter.hpp"
|
4
|
-
#include "duckdb/execution/operator/
|
4
|
+
#include "duckdb/execution/operator/scan/physical_table_scan.hpp"
|
5
|
+
#include "duckdb/execution/operator/schema/physical_create_art_index.hpp"
|
5
6
|
#include "duckdb/execution/operator/order/physical_order.hpp"
|
6
7
|
#include "duckdb/execution/physical_plan_generator.hpp"
|
7
8
|
#include "duckdb/planner/operator/logical_create_index.hpp"
|
@@ -19,7 +20,7 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCreateInde
|
|
19
20
|
auto table_scan = CreatePlan(*op.children[0]);
|
20
21
|
|
21
22
|
// validate that all expressions contain valid scalar functions
|
22
|
-
// e.g. get_current_timestamp(), random(), and sequence values are not allowed as
|
23
|
+
// e.g. get_current_timestamp(), random(), and sequence values are not allowed as index keys
|
23
24
|
// because they make deletions and lookups unfeasible
|
24
25
|
for (idx_t i = 0; i < op.unbound_expressions.size(); i++) {
|
25
26
|
auto &expr = op.unbound_expressions[i];
|
@@ -29,6 +30,13 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCreateInde
|
|
29
30
|
}
|
30
31
|
}
|
31
32
|
|
33
|
+
// If we get here without the plan and the index type is not ART, we throw an exception
|
34
|
+
// because we don't support any other index type yet. However an operator extension could have
|
35
|
+
// replaced this part of the plan with a different index creation operator.
|
36
|
+
if (op.info->index_type != IndexType::ART) {
|
37
|
+
throw BinderException("Index type not supported");
|
38
|
+
}
|
39
|
+
|
32
40
|
// table scan operator for index key columns and row IDs
|
33
41
|
dependencies.AddDependency(op.table);
|
34
42
|
|
@@ -80,8 +88,8 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCreateInde
|
|
80
88
|
// actual physical create index operator
|
81
89
|
|
82
90
|
auto physical_create_index =
|
83
|
-
make_uniq<
|
84
|
-
|
91
|
+
make_uniq<PhysicalCreateARTIndex>(op, op.table, op.info->column_ids, std::move(op.info),
|
92
|
+
std::move(op.unbound_expressions), op.estimated_cardinality, perform_sorting);
|
85
93
|
|
86
94
|
if (perform_sorting) {
|
87
95
|
|
@@ -367,8 +367,9 @@ BoundCastInfo DefaultCasts::StringCastSwitch(BindCastInput &input, const Logical
|
|
367
367
|
case LogicalTypeId::DATE:
|
368
368
|
return BoundCastInfo(&VectorCastHelpers::TryCastErrorLoop<string_t, date_t, duckdb::TryCastErrorMessage>);
|
369
369
|
case LogicalTypeId::TIME:
|
370
|
-
case LogicalTypeId::TIME_TZ:
|
371
370
|
return BoundCastInfo(&VectorCastHelpers::TryCastErrorLoop<string_t, dtime_t, duckdb::TryCastErrorMessage>);
|
371
|
+
case LogicalTypeId::TIME_TZ:
|
372
|
+
return BoundCastInfo(&VectorCastHelpers::TryCastErrorLoop<string_t, dtime_tz_t, duckdb::TryCastErrorMessage>);
|
372
373
|
case LogicalTypeId::TIMESTAMP:
|
373
374
|
case LogicalTypeId::TIMESTAMP_TZ:
|
374
375
|
return BoundCastInfo(&VectorCastHelpers::TryCastErrorLoop<string_t, timestamp_t, duckdb::TryCastErrorMessage>);
|
@@ -32,7 +32,7 @@ BoundCastInfo DefaultCasts::TimeCastSwitch(BindCastInput &input, const LogicalTy
|
|
32
32
|
return BoundCastInfo(&VectorCastHelpers::StringCast<dtime_t, duckdb::StringCast>);
|
33
33
|
case LogicalTypeId::TIME_TZ:
|
34
34
|
// time to time with time zone
|
35
|
-
return
|
35
|
+
return BoundCastInfo(&VectorCastHelpers::TemplatedCastLoop<dtime_t, dtime_tz_t, duckdb::Cast>);
|
36
36
|
default:
|
37
37
|
return TryVectorNullCast;
|
38
38
|
}
|
@@ -44,10 +44,10 @@ BoundCastInfo DefaultCasts::TimeTzCastSwitch(BindCastInput &input, const Logical
|
|
44
44
|
switch (target.id()) {
|
45
45
|
case LogicalTypeId::VARCHAR:
|
46
46
|
// time with time zone to varchar
|
47
|
-
return BoundCastInfo(&VectorCastHelpers::StringCast<
|
47
|
+
return BoundCastInfo(&VectorCastHelpers::StringCast<dtime_tz_t, duckdb::StringCastTZ>);
|
48
48
|
case LogicalTypeId::TIME:
|
49
49
|
// time with time zone to time
|
50
|
-
return
|
50
|
+
return BoundCastInfo(&VectorCastHelpers::TemplatedCastLoop<dtime_tz_t, dtime_t, duckdb::Cast>);
|
51
51
|
default:
|
52
52
|
return TryVectorNullCast;
|
53
53
|
}
|
@@ -64,9 +64,11 @@ BoundCastInfo DefaultCasts::TimestampCastSwitch(BindCastInput &input, const Logi
|
|
64
64
|
// timestamp to date
|
65
65
|
return BoundCastInfo(&VectorCastHelpers::TemplatedCastLoop<timestamp_t, date_t, duckdb::Cast>);
|
66
66
|
case LogicalTypeId::TIME:
|
67
|
-
case LogicalTypeId::TIME_TZ:
|
68
67
|
// timestamp to time
|
69
68
|
return BoundCastInfo(&VectorCastHelpers::TemplatedCastLoop<timestamp_t, dtime_t, duckdb::Cast>);
|
69
|
+
case LogicalTypeId::TIME_TZ:
|
70
|
+
// timestamp to time_tz
|
71
|
+
return BoundCastInfo(&VectorCastHelpers::TemplatedCastLoop<timestamp_t, dtime_tz_t, duckdb::Cast>);
|
70
72
|
case LogicalTypeId::TIMESTAMP_TZ:
|
71
73
|
// timestamp (us) to timestamp with time zone
|
72
74
|
return ReinterpretCast;
|
@@ -96,8 +98,7 @@ BoundCastInfo DefaultCasts::TimestampTzCastSwitch(BindCastInput &input, const Lo
|
|
96
98
|
return BoundCastInfo(&VectorCastHelpers::StringCast<timestamp_t, duckdb::StringCastTZ>);
|
97
99
|
case LogicalTypeId::TIME_TZ:
|
98
100
|
// timestamp with time zone to time with time zone.
|
99
|
-
|
100
|
-
return BoundCastInfo(&VectorCastHelpers::TemplatedCastLoop<timestamp_t, dtime_t, duckdb::Cast>);
|
101
|
+
return BoundCastInfo(&VectorCastHelpers::TemplatedCastLoop<timestamp_t, dtime_tz_t, duckdb::Cast>);
|
101
102
|
case LogicalTypeId::TIMESTAMP:
|
102
103
|
// timestamp with time zone to timestamp (us)
|
103
104
|
return ReinterpretCast;
|
@@ -1,8 +1,8 @@
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
2
|
-
#define DUCKDB_VERSION "0.8.2-
|
2
|
+
#define DUCKDB_VERSION "0.8.2-dev3300"
|
3
3
|
#endif
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
5
|
+
#define DUCKDB_SOURCE_ID "26931f7ac6"
|
6
6
|
#endif
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
8
8
|
#include "duckdb/main/database.hpp"
|
@@ -16,8 +16,9 @@ namespace duckdb {
|
|
16
16
|
// Index Types
|
17
17
|
//===--------------------------------------------------------------------===//
|
18
18
|
enum class IndexType : uint8_t {
|
19
|
-
INVALID = 0,
|
20
|
-
ART = 1
|
19
|
+
INVALID = 0, // invalid index type
|
20
|
+
ART = 1, // Adaptive Radix Tree
|
21
|
+
EXTENSION = 100 // Extension index
|
21
22
|
};
|
22
23
|
|
23
24
|
//===--------------------------------------------------------------------===//
|
@@ -73,7 +73,7 @@ struct Cast {
|
|
73
73
|
};
|
74
74
|
|
75
75
|
struct HandleCastError {
|
76
|
-
static void AssignError(string error_message, string *error_message_ptr) {
|
76
|
+
static void AssignError(const string &error_message, string *error_message_ptr) {
|
77
77
|
if (!error_message_ptr) {
|
78
78
|
throw ConversionException(error_message);
|
79
79
|
}
|
@@ -470,6 +470,16 @@ DUCKDB_API bool TryCast::Operation(date_t input, timestamp_t &result, bool stric
|
|
470
470
|
//===--------------------------------------------------------------------===//
|
471
471
|
template <>
|
472
472
|
DUCKDB_API bool TryCast::Operation(dtime_t input, dtime_t &result, bool strict);
|
473
|
+
template <>
|
474
|
+
DUCKDB_API bool TryCast::Operation(dtime_t input, dtime_tz_t &result, bool strict);
|
475
|
+
|
476
|
+
//===--------------------------------------------------------------------===//
|
477
|
+
// Time With Time Zone Casts (Offset)
|
478
|
+
//===--------------------------------------------------------------------===//
|
479
|
+
template <>
|
480
|
+
DUCKDB_API bool TryCast::Operation(dtime_tz_t input, dtime_t &result, bool strict);
|
481
|
+
template <>
|
482
|
+
DUCKDB_API bool TryCast::Operation(dtime_tz_t input, dtime_tz_t &result, bool strict);
|
473
483
|
|
474
484
|
//===--------------------------------------------------------------------===//
|
475
485
|
// Timestamp Casts
|
@@ -479,6 +489,8 @@ DUCKDB_API bool TryCast::Operation(timestamp_t input, date_t &result, bool stric
|
|
479
489
|
template <>
|
480
490
|
DUCKDB_API bool TryCast::Operation(timestamp_t input, dtime_t &result, bool strict);
|
481
491
|
template <>
|
492
|
+
DUCKDB_API bool TryCast::Operation(timestamp_t input, dtime_tz_t &result, bool strict);
|
493
|
+
template <>
|
482
494
|
DUCKDB_API bool TryCast::Operation(timestamp_t input, timestamp_t &result, bool strict);
|
483
495
|
|
484
496
|
//===--------------------------------------------------------------------===//
|
@@ -506,6 +518,15 @@ DUCKDB_API bool TryCast::Operation(string_t input, dtime_t &result, bool strict)
|
|
506
518
|
template <>
|
507
519
|
dtime_t Cast::Operation(string_t input);
|
508
520
|
//===--------------------------------------------------------------------===//
|
521
|
+
// String -> TimeTZ Casts
|
522
|
+
//===--------------------------------------------------------------------===//
|
523
|
+
template <>
|
524
|
+
DUCKDB_API bool TryCastErrorMessage::Operation(string_t input, dtime_tz_t &result, string *error_message, bool strict);
|
525
|
+
template <>
|
526
|
+
DUCKDB_API bool TryCast::Operation(string_t input, dtime_tz_t &result, bool strict);
|
527
|
+
template <>
|
528
|
+
dtime_tz_t Cast::Operation(string_t input);
|
529
|
+
//===--------------------------------------------------------------------===//
|
509
530
|
// String -> Timestamp Casts
|
510
531
|
//===--------------------------------------------------------------------===//
|
511
532
|
template <>
|
@@ -71,7 +71,7 @@ struct StringCastTZ {
|
|
71
71
|
template <>
|
72
72
|
duckdb::string_t StringCastTZ::Operation(date_t input, Vector &result);
|
73
73
|
template <>
|
74
|
-
duckdb::string_t StringCastTZ::Operation(
|
74
|
+
duckdb::string_t StringCastTZ::Operation(dtime_tz_t input, Vector &result);
|
75
75
|
template <>
|
76
76
|
duckdb::string_t StringCastTZ::Operation(timestamp_t input, Vector &result);
|
77
77
|
|
@@ -81,12 +81,54 @@ struct dtime_t { // NOLINT
|
|
81
81
|
};
|
82
82
|
|
83
83
|
// special values
|
84
|
-
static inline dtime_t allballs() {
|
84
|
+
static inline dtime_t allballs() { // NOLINT
|
85
85
|
return dtime_t(0);
|
86
86
|
} // NOLINT
|
87
87
|
};
|
88
88
|
|
89
|
-
struct dtime_tz_t
|
89
|
+
struct dtime_tz_t { // NOLINT
|
90
|
+
static constexpr const int TIME_BITS = 40;
|
91
|
+
static constexpr const int OFFSET_BITS = 24;
|
92
|
+
static constexpr const uint64_t OFFSET_MASK = ~uint64_t(0) >> TIME_BITS;
|
93
|
+
static constexpr const int32_t MAX_OFFSET = 1559 * 60 * 60;
|
94
|
+
static constexpr const int32_t MIN_OFFSET = -MAX_OFFSET;
|
95
|
+
|
96
|
+
uint64_t bits;
|
97
|
+
|
98
|
+
dtime_tz_t() = default;
|
99
|
+
|
100
|
+
inline dtime_tz_t(dtime_t t, int32_t offset)
|
101
|
+
: bits((uint64_t(t.micros) << OFFSET_BITS) | uint64_t(offset + MAX_OFFSET)) {
|
102
|
+
}
|
103
|
+
|
104
|
+
inline dtime_t time() const { // NOLINT
|
105
|
+
return dtime_t(bits >> OFFSET_BITS);
|
106
|
+
}
|
107
|
+
|
108
|
+
inline int32_t offset() const { // NOLINT
|
109
|
+
return int32_t(bits & OFFSET_MASK) - MAX_OFFSET;
|
110
|
+
}
|
111
|
+
|
112
|
+
// comparison operators
|
113
|
+
inline bool operator==(const dtime_tz_t &rhs) const {
|
114
|
+
return bits == rhs.bits;
|
115
|
+
};
|
116
|
+
inline bool operator!=(const dtime_tz_t &rhs) const {
|
117
|
+
return bits != rhs.bits;
|
118
|
+
};
|
119
|
+
inline bool operator<=(const dtime_tz_t &rhs) const {
|
120
|
+
return bits <= rhs.bits;
|
121
|
+
};
|
122
|
+
inline bool operator<(const dtime_tz_t &rhs) const {
|
123
|
+
return bits < rhs.bits;
|
124
|
+
};
|
125
|
+
inline bool operator>(const dtime_tz_t &rhs) const {
|
126
|
+
return bits > rhs.bits;
|
127
|
+
};
|
128
|
+
inline bool operator>=(const dtime_tz_t &rhs) const {
|
129
|
+
return bits >= rhs.bits;
|
130
|
+
};
|
131
|
+
};
|
90
132
|
|
91
133
|
} // namespace duckdb
|
92
134
|
|
@@ -100,11 +142,12 @@ struct hash<duckdb::dtime_t> {
|
|
100
142
|
return hash<int64_t>()((int64_t)k);
|
101
143
|
}
|
102
144
|
};
|
145
|
+
|
103
146
|
template <>
|
104
147
|
struct hash<duckdb::dtime_tz_t> {
|
105
148
|
std::size_t operator()(const duckdb::dtime_tz_t &k) const {
|
106
149
|
using std::hash;
|
107
|
-
return hash<int64_t>()(
|
150
|
+
return hash<int64_t>()(k.bits);
|
108
151
|
}
|
109
152
|
};
|
110
153
|
} // namespace std
|
@@ -15,6 +15,7 @@
|
|
15
15
|
namespace duckdb {
|
16
16
|
|
17
17
|
struct dtime_t;
|
18
|
+
struct dtime_tz_t;
|
18
19
|
|
19
20
|
//! The Time class is a static class that holds helper functions for the Time
|
20
21
|
//! type.
|
@@ -24,6 +25,10 @@ public:
|
|
24
25
|
DUCKDB_API static dtime_t FromString(const string &str, bool strict = false);
|
25
26
|
DUCKDB_API static dtime_t FromCString(const char *buf, idx_t len, bool strict = false);
|
26
27
|
DUCKDB_API static bool TryConvertTime(const char *buf, idx_t len, idx_t &pos, dtime_t &result, bool strict = false);
|
28
|
+
DUCKDB_API static bool TryConvertTimeTZ(const char *buf, idx_t len, idx_t &pos, dtime_tz_t &result,
|
29
|
+
bool strict = false);
|
30
|
+
//! Format is ±[HH]HH[:MM[:SS]]
|
31
|
+
DUCKDB_API static bool TryParseUTCOffset(const char *str, idx_t &pos, idx_t len, int32_t &offset);
|
27
32
|
|
28
33
|
//! Convert a time object to a string in the format "hh:mm:ss"
|
29
34
|
DUCKDB_API static string ToString(dtime_t time);
|
@@ -120,7 +120,7 @@ public:
|
|
120
120
|
DUCKDB_API static Value DATE(int32_t year, int32_t month, int32_t day);
|
121
121
|
//! Create a time Value from a specified time
|
122
122
|
DUCKDB_API static Value TIME(dtime_t time);
|
123
|
-
DUCKDB_API static Value TIMETZ(
|
123
|
+
DUCKDB_API static Value TIMETZ(dtime_tz_t time);
|
124
124
|
//! Create a time Value from a specified time
|
125
125
|
DUCKDB_API static Value TIME(int32_t hour, int32_t min, int32_t sec, int32_t micros);
|
126
126
|
//! Create a timestamp Value from a specified date/time combination
|
@@ -302,6 +302,7 @@ private:
|
|
302
302
|
uint64_t hash;
|
303
303
|
date_t date;
|
304
304
|
dtime_t time;
|
305
|
+
dtime_tz_t timetz;
|
305
306
|
timestamp_t timestamp;
|
306
307
|
interval_t interval;
|
307
308
|
} value_; // NOLINT
|
@@ -1,7 +1,7 @@
|
|
1
1
|
//===----------------------------------------------------------------------===//
|
2
2
|
// DuckDB
|
3
3
|
//
|
4
|
-
// duckdb/execution/operator/schema/
|
4
|
+
// duckdb/execution/operator/schema/physical_create_art_index.hpp
|
5
5
|
//
|
6
6
|
//
|
7
7
|
//===----------------------------------------------------------------------===//
|
@@ -20,14 +20,14 @@ namespace duckdb {
|
|
20
20
|
class DuckTableEntry;
|
21
21
|
|
22
22
|
//! Physical CREATE (UNIQUE) INDEX statement
|
23
|
-
class
|
23
|
+
class PhysicalCreateARTIndex : public PhysicalOperator {
|
24
24
|
public:
|
25
25
|
static constexpr const PhysicalOperatorType TYPE = PhysicalOperatorType::CREATE_INDEX;
|
26
26
|
|
27
27
|
public:
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
PhysicalCreateARTIndex(LogicalOperator &op, TableCatalogEntry &table, const vector<column_t> &column_ids,
|
29
|
+
unique_ptr<CreateIndexInfo> info, vector<unique_ptr<Expression>> unbound_expressions,
|
30
|
+
idx_t estimated_cardinality, const bool sorted);
|
31
31
|
|
32
32
|
//! The table to create the index for
|
33
33
|
DuckTableEntry &table;
|
@@ -99,13 +99,16 @@ typedef void (*copy_flush_batch_t)(ClientContext &context, FunctionData &bind_da
|
|
99
99
|
PreparedBatchData &batch);
|
100
100
|
typedef idx_t (*copy_desired_batch_size_t)(ClientContext &context, FunctionData &bind_data);
|
101
101
|
|
102
|
+
typedef bool (*copy_supports_type_t)(const LogicalType &type);
|
103
|
+
|
102
104
|
class CopyFunction : public Function {
|
103
105
|
public:
|
104
106
|
explicit CopyFunction(string name)
|
105
107
|
: Function(name), plan(nullptr), copy_to_bind(nullptr), copy_to_initialize_local(nullptr),
|
106
108
|
copy_to_initialize_global(nullptr), copy_to_sink(nullptr), copy_to_combine(nullptr),
|
107
109
|
copy_to_finalize(nullptr), execution_mode(nullptr), prepare_batch(nullptr), flush_batch(nullptr),
|
108
|
-
desired_batch_size(nullptr), serialize(nullptr), deserialize(nullptr),
|
110
|
+
desired_batch_size(nullptr), serialize(nullptr), deserialize(nullptr), supports_type(nullptr),
|
111
|
+
copy_from_bind(nullptr) {
|
109
112
|
}
|
110
113
|
|
111
114
|
//! Plan rewrite copy function
|
@@ -126,6 +129,8 @@ public:
|
|
126
129
|
copy_to_serialize_t serialize;
|
127
130
|
copy_to_deserialize_t deserialize;
|
128
131
|
|
132
|
+
copy_supports_type_t supports_type;
|
133
|
+
|
129
134
|
copy_from_bind_t copy_from_bind;
|
130
135
|
TableFunction copy_from_function;
|
131
136
|
|
@@ -318,8 +318,9 @@ private:
|
|
318
318
|
case LogicalTypeId::DATE:
|
319
319
|
return std::is_same<T, date_t>();
|
320
320
|
case LogicalTypeId::TIME:
|
321
|
-
case LogicalTypeId::TIME_TZ:
|
322
321
|
return std::is_same<T, dtime_t>();
|
322
|
+
case LogicalTypeId::TIME_TZ:
|
323
|
+
return std::is_same<T, dtime_tz_t>();
|
323
324
|
case LogicalTypeId::TIMESTAMP:
|
324
325
|
case LogicalTypeId::TIMESTAMP_MS:
|
325
326
|
case LogicalTypeId::TIMESTAMP_NS:
|
@@ -25,6 +25,8 @@ struct CreateIndexInfo : public CreateInfo {
|
|
25
25
|
IndexType index_type;
|
26
26
|
//! Name of the Index
|
27
27
|
string index_name;
|
28
|
+
//! Name of the Index type
|
29
|
+
string index_type_name;
|
28
30
|
//! Index Constraint Type
|
29
31
|
IndexConstraintType constraint_type;
|
30
32
|
//! The table to create the index on
|
@@ -40,6 +42,9 @@ struct CreateIndexInfo : public CreateInfo {
|
|
40
42
|
//! Column IDs needed for index creation
|
41
43
|
vector<column_t> column_ids;
|
42
44
|
|
45
|
+
//! Options values (WITH ...)
|
46
|
+
case_insensitive_map_t<Value> options;
|
47
|
+
|
43
48
|
protected:
|
44
49
|
void SerializeInternal(Serializer &serializer) const override;
|
45
50
|
|
@@ -13,6 +13,8 @@
|
|
13
13
|
|
14
14
|
namespace duckdb {
|
15
15
|
|
16
|
+
class ColumnBindingResolver;
|
17
|
+
|
16
18
|
struct LogicalExtensionOperator : public LogicalOperator {
|
17
19
|
public:
|
18
20
|
static constexpr const LogicalOperatorType TYPE = LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR;
|
@@ -31,6 +33,7 @@ public:
|
|
31
33
|
|
32
34
|
virtual unique_ptr<PhysicalOperator> CreatePlan(ClientContext &context, PhysicalPlanGenerator &generator) = 0;
|
33
35
|
|
36
|
+
virtual void ResolveColumnBindings(ColumnBindingResolver &res, vector<ColumnBinding> &bindings);
|
34
37
|
virtual string GetExtensionName() const;
|
35
38
|
};
|
36
39
|
} // namespace duckdb
|
@@ -125,7 +125,7 @@ public:
|
|
125
125
|
void UpdateColumn(TableCatalogEntry &table, ClientContext &context, Vector &row_ids,
|
126
126
|
const vector<column_t> &column_path, DataChunk &updates);
|
127
127
|
|
128
|
-
//! Add an index to the DataTable. NOTE: for CREATE (UNIQUE) INDEX statements, we use the
|
128
|
+
//! Add an index to the DataTable. NOTE: for CREATE (UNIQUE) INDEX statements, we use the PhysicalCreateARTIndex
|
129
129
|
//! operator. This function is only used during the WAL replay, and is a much less performant index creation
|
130
130
|
//! approach.
|
131
131
|
void WALAddIndex(ClientContext &context, unique_ptr<Index> index,
|
@@ -184,9 +184,11 @@ void BaseAppender::AppendValueInternal(T input) {
|
|
184
184
|
AppendValueInternal<T, timestamp_t>(col, input);
|
185
185
|
break;
|
186
186
|
case LogicalTypeId::TIME:
|
187
|
-
case LogicalTypeId::TIME_TZ:
|
188
187
|
AppendValueInternal<T, dtime_t>(col, input);
|
189
188
|
break;
|
189
|
+
case LogicalTypeId::TIME_TZ:
|
190
|
+
AppendValueInternal<T, dtime_tz_t>(col, input);
|
191
|
+
break;
|
190
192
|
case LogicalTypeId::INTERVAL:
|
191
193
|
AppendValueInternal<T, interval_t>(col, input);
|
192
194
|
break;
|
@@ -182,9 +182,11 @@ duckdb_state deprecated_duckdb_translate_column(MaterializedQueryResult &result,
|
|
182
182
|
WriteData<date_t>(column, collection, column_ids);
|
183
183
|
break;
|
184
184
|
case LogicalTypeId::TIME:
|
185
|
-
case LogicalTypeId::TIME_TZ:
|
186
185
|
WriteData<dtime_t>(column, collection, column_ids);
|
187
186
|
break;
|
187
|
+
case LogicalTypeId::TIME_TZ:
|
188
|
+
WriteData<dtime_tz_t>(column, collection, column_ids);
|
189
|
+
break;
|
188
190
|
case LogicalTypeId::TIMESTAMP:
|
189
191
|
case LogicalTypeId::TIMESTAMP_TZ:
|
190
192
|
WriteData<timestamp_t>(column, collection, column_ids);
|
@@ -22,6 +22,7 @@ unique_ptr<CreateInfo> CreateIndexInfo::Copy() const {
|
|
22
22
|
result->scan_types = scan_types;
|
23
23
|
result->names = names;
|
24
24
|
result->column_ids = column_ids;
|
25
|
+
result->options = options;
|
25
26
|
return std::move(result);
|
26
27
|
}
|
27
28
|
|
@@ -37,6 +38,12 @@ void CreateIndexInfo::SerializeInternal(Serializer &serializer) const {
|
|
37
38
|
writer.WriteRegularSerializableList(scan_types);
|
38
39
|
writer.WriteList<string>(names);
|
39
40
|
writer.WriteList<column_t>(column_ids);
|
41
|
+
writer.WriteString(index_type_name);
|
42
|
+
writer.WriteField((idx_t)options.size());
|
43
|
+
for (auto &kv : options) {
|
44
|
+
writer.WriteString(kv.first);
|
45
|
+
writer.WriteSerializable(kv.second);
|
46
|
+
}
|
40
47
|
writer.Finalize();
|
41
48
|
}
|
42
49
|
|
@@ -55,6 +62,13 @@ unique_ptr<CreateIndexInfo> CreateIndexInfo::Deserialize(Deserializer &deseriali
|
|
55
62
|
result->scan_types = reader.ReadRequiredSerializableList<LogicalType, LogicalType>();
|
56
63
|
result->names = reader.ReadRequiredList<string>();
|
57
64
|
result->column_ids = reader.ReadRequiredList<column_t>();
|
65
|
+
result->index_type_name = reader.ReadRequired<string>();
|
66
|
+
auto options_count = reader.ReadRequired<idx_t>();
|
67
|
+
for (idx_t i = 0; i < options_count; i++) {
|
68
|
+
auto key = reader.ReadRequired<string>();
|
69
|
+
auto value = reader.ReadRequiredSerializable<Value, Value>();
|
70
|
+
result->options[key] = value;
|
71
|
+
}
|
58
72
|
reader.Finalize();
|
59
73
|
return result;
|
60
74
|
}
|