duckdb 0.6.2-dev2115.0 → 0.6.2-dev2226.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/json/buffered_json_reader.cpp +18 -5
- package/src/duckdb/extension/json/include/buffered_json_reader.hpp +6 -1
- package/src/duckdb/extension/json/include/json_common.hpp +1 -0
- package/src/duckdb/extension/json/include/json_scan.hpp +7 -0
- package/src/duckdb/extension/json/include/json_transform.hpp +25 -10
- package/src/duckdb/extension/json/json_common.cpp +6 -2
- package/src/duckdb/extension/json/json_functions/json_structure.cpp +47 -9
- package/src/duckdb/extension/json/json_functions/json_transform.cpp +183 -106
- package/src/duckdb/extension/json/json_functions/read_json.cpp +35 -22
- package/src/duckdb/extension/json/json_scan.cpp +26 -5
- package/src/duckdb/extension/parquet/parquet-extension.cpp +1 -0
- package/src/duckdb/src/catalog/catalog.cpp +11 -12
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +1 -1
- package/src/duckdb/src/common/box_renderer.cpp +9 -1
- package/src/duckdb/src/common/compressed_file_system.cpp +1 -1
- package/src/duckdb/src/common/enums/relation_type.cpp +2 -0
- package/src/duckdb/src/common/gzip_file_system.cpp +1 -1
- package/src/duckdb/src/common/local_file_system.cpp +1 -1
- package/src/duckdb/src/common/row_operations/row_aggregate.cpp +2 -2
- package/src/duckdb/src/common/types/column_data_allocator.cpp +2 -2
- package/src/duckdb/src/common/types/date.cpp +7 -2
- package/src/duckdb/src/common/types/vector.cpp +3 -2
- package/src/duckdb/src/common/virtual_file_system.cpp +1 -1
- package/src/duckdb/src/execution/index/art/art.cpp +5 -5
- package/src/duckdb/src/execution/join_hashtable.cpp +4 -5
- package/src/duckdb/src/execution/operator/persistent/physical_update.cpp +2 -0
- package/src/duckdb/src/execution/operator/projection/physical_unnest.cpp +182 -123
- package/src/duckdb/src/execution/operator/schema/physical_attach.cpp +22 -18
- package/src/duckdb/src/execution/physical_plan/plan_create_table.cpp +1 -1
- package/src/duckdb/src/function/aggregate/distributive/arg_min_max.cpp +2 -3
- package/src/duckdb/src/function/scalar/math/setseed.cpp +1 -1
- package/src/duckdb/src/function/scalar/string/substring.cpp +8 -0
- package/src/duckdb/src/function/table/read_csv.cpp +1 -1
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/box_renderer.hpp +4 -0
- package/src/duckdb/src/include/duckdb/common/enums/relation_type.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/file_opener.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/http_stats.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/limits.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/types/validity_mask.hpp +1 -9
- package/src/duckdb/src/include/duckdb/common/types/vector.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/executor.hpp +3 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +3 -3
- package/src/duckdb/src/include/duckdb/execution/operator/projection/physical_unnest.hpp +5 -1
- package/src/duckdb/src/include/duckdb/main/client_context.hpp +3 -0
- package/src/duckdb/src/include/duckdb/main/config.hpp +0 -4
- package/src/duckdb/src/include/duckdb/main/database.hpp +6 -0
- package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +5 -5
- package/src/duckdb/src/include/duckdb/main/relation/write_csv_relation.hpp +2 -1
- package/src/duckdb/src/include/duckdb/main/relation/write_parquet_relation.hpp +34 -0
- package/src/duckdb/src/include/duckdb/main/relation.hpp +6 -1
- package/src/duckdb/src/include/duckdb/parser/parsed_data/copy_info.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/index.hpp +4 -3
- package/src/duckdb/src/include/duckdb.h +7 -0
- package/src/duckdb/src/main/capi/threading-c.cpp +8 -0
- package/src/duckdb/src/main/client_context.cpp +7 -0
- package/src/duckdb/src/main/client_context_file_opener.cpp +14 -0
- package/src/duckdb/src/main/database.cpp +57 -40
- package/src/duckdb/src/main/extension/extension_load.cpp +20 -28
- package/src/duckdb/src/main/relation/write_csv_relation.cpp +4 -2
- package/src/duckdb/src/main/relation/write_parquet_relation.cpp +37 -0
- package/src/duckdb/src/main/relation.cpp +12 -2
- package/src/duckdb/src/parallel/executor.cpp +4 -0
- package/src/duckdb/src/parser/statement/copy_statement.cpp +1 -1
- package/src/duckdb/src/parser/transform/statement/transform_show.cpp +4 -3
- package/src/duckdb/src/planner/binder/expression/bind_cast_expression.cpp +1 -1
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +24 -3
- package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +1 -1
- package/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp +2 -0
- package/src/duckdb/src/storage/compression/bitpacking.cpp +2 -1
- package/src/duckdb/src/storage/compression/fixed_size_uncompressed.cpp +1 -1
- package/src/duckdb/src/storage/index.cpp +1 -1
- package/src/duckdb/src/storage/meta_block_writer.cpp +1 -1
- package/src/duckdb/src/storage/table/column_segment.cpp +3 -3
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +1 -2
- package/src/duckdb/third_party/libpg_query/src_backend_parser_scan.cpp +539 -300
- package/src/duckdb/ub_src_main.cpp +0 -2
- package/src/duckdb/ub_src_main_relation.cpp +2 -0
- package/src/duckdb/src/include/duckdb/function/replacement_open.hpp +0 -54
- package/src/duckdb/src/include/duckdb/main/replacement_opens.hpp +0 -20
- package/src/duckdb/src/main/extension_prefix_opener.cpp +0 -55
|
@@ -74,6 +74,7 @@ struct NumericLimits<int32_t> {
|
|
|
74
74
|
return 10;
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
|
+
|
|
77
78
|
template <>
|
|
78
79
|
struct NumericLimits<int64_t> {
|
|
79
80
|
DUCKDB_API static constexpr int64_t Minimum() {
|
|
@@ -104,6 +105,7 @@ struct NumericLimits<hugeint_t> {
|
|
|
104
105
|
return 39;
|
|
105
106
|
}
|
|
106
107
|
};
|
|
108
|
+
|
|
107
109
|
template <>
|
|
108
110
|
struct NumericLimits<uint8_t> {
|
|
109
111
|
DUCKDB_API static constexpr uint8_t Minimum() {
|
|
@@ -119,6 +121,7 @@ struct NumericLimits<uint8_t> {
|
|
|
119
121
|
return 3;
|
|
120
122
|
}
|
|
121
123
|
};
|
|
124
|
+
|
|
122
125
|
template <>
|
|
123
126
|
struct NumericLimits<uint16_t> {
|
|
124
127
|
DUCKDB_API static constexpr uint16_t Minimum() {
|
|
@@ -83,15 +83,7 @@ public:
|
|
|
83
83
|
return !validity_mask;
|
|
84
84
|
}
|
|
85
85
|
inline bool CheckAllValid(idx_t count) const {
|
|
86
|
-
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
idx_t entry_count = ValidityBuffer::EntryCount(count);
|
|
90
|
-
idx_t valid_count = 0;
|
|
91
|
-
for (idx_t i = 0; i < entry_count; i++) {
|
|
92
|
-
valid_count += validity_mask[i] == ValidityBuffer::MAX_ENTRY;
|
|
93
|
-
}
|
|
94
|
-
return valid_count == entry_count;
|
|
86
|
+
return CountValid(count) == count;
|
|
95
87
|
}
|
|
96
88
|
|
|
97
89
|
inline bool CheckAllValid(idx_t to, idx_t from) const {
|
|
@@ -116,10 +116,10 @@ public:
|
|
|
116
116
|
|
|
117
117
|
//! Converts this Vector to a printable string representation
|
|
118
118
|
DUCKDB_API string ToString(idx_t count) const;
|
|
119
|
-
DUCKDB_API void Print(idx_t count);
|
|
119
|
+
DUCKDB_API void Print(idx_t count) const;
|
|
120
120
|
|
|
121
121
|
DUCKDB_API string ToString() const;
|
|
122
|
-
DUCKDB_API void Print();
|
|
122
|
+
DUCKDB_API void Print() const;
|
|
123
123
|
|
|
124
124
|
//! Flatten the vector, removing any compression and turning it into a FLAT_VECTOR
|
|
125
125
|
DUCKDB_API void Flatten(idx_t count);
|
|
@@ -89,6 +89,9 @@ public:
|
|
|
89
89
|
//! Returns the query result - can only be used if `HasResultCollector` returns true
|
|
90
90
|
unique_ptr<QueryResult> GetResult();
|
|
91
91
|
|
|
92
|
+
//! Returns true if all pipelines have been completed
|
|
93
|
+
bool ExecutionIsFinished();
|
|
94
|
+
|
|
92
95
|
private:
|
|
93
96
|
void InitializeInternal(PhysicalOperator *physical_plan);
|
|
94
97
|
|
|
@@ -64,13 +64,13 @@ public:
|
|
|
64
64
|
public:
|
|
65
65
|
//! Initialize a scan on the index with the given expression and column ids
|
|
66
66
|
//! to fetch from the base table for a single predicate
|
|
67
|
-
unique_ptr<IndexScanState> InitializeScanSinglePredicate(Transaction &transaction, Value value,
|
|
67
|
+
unique_ptr<IndexScanState> InitializeScanSinglePredicate(const Transaction &transaction, const Value &value,
|
|
68
68
|
ExpressionType expression_type) override;
|
|
69
69
|
|
|
70
70
|
//! Initialize a scan on the index with the given expression and column ids
|
|
71
71
|
//! to fetch from the base table for two predicates
|
|
72
|
-
unique_ptr<IndexScanState> InitializeScanTwoPredicates(Transaction &transaction, Value low_value,
|
|
73
|
-
ExpressionType low_expression_type, Value high_value,
|
|
72
|
+
unique_ptr<IndexScanState> InitializeScanTwoPredicates(Transaction &transaction, const Value &low_value,
|
|
73
|
+
ExpressionType low_expression_type, const Value &high_value,
|
|
74
74
|
ExpressionType high_expression_type) override;
|
|
75
75
|
|
|
76
76
|
//! Perform a lookup on the index
|
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
|
|
15
15
|
namespace duckdb {
|
|
16
16
|
|
|
17
|
-
//!
|
|
17
|
+
//! PhysicalUnnest implements the physical UNNEST operation
|
|
18
18
|
class PhysicalUnnest : public PhysicalOperator {
|
|
19
19
|
public:
|
|
20
20
|
PhysicalUnnest(vector<LogicalType> types, vector<unique_ptr<Expression>> select_list, idx_t estimated_cardinality,
|
|
21
21
|
PhysicalOperatorType type = PhysicalOperatorType::UNNEST);
|
|
22
22
|
|
|
23
23
|
//! The projection list of the UNNEST
|
|
24
|
+
//! E.g. SELECT 1, UNNEST([1]), UNNEST([2, 3]); has two UNNESTs in its select_list
|
|
24
25
|
vector<unique_ptr<Expression>> select_list;
|
|
25
26
|
|
|
26
27
|
public:
|
|
@@ -35,6 +36,9 @@ public:
|
|
|
35
36
|
public:
|
|
36
37
|
static unique_ptr<OperatorState> GetState(ExecutionContext &context,
|
|
37
38
|
const vector<unique_ptr<Expression>> &select_list);
|
|
39
|
+
//! Executes the UNNEST operator internally and emits a chunk of unnested data. If include_input is set, then
|
|
40
|
+
//! the resulting chunk also contains vectors for all non-UNNEST columns in the projection. If include_input is
|
|
41
|
+
//! not set, then the UNNEST behaves as a table function and only emits the unnested data.
|
|
38
42
|
static OperatorResultType ExecuteInternal(ExecutionContext &context, DataChunk &input, DataChunk &chunk,
|
|
39
43
|
OperatorState &state, const vector<unique_ptr<Expression>> &select_list,
|
|
40
44
|
bool include_input = true);
|
|
@@ -188,6 +188,9 @@ public:
|
|
|
188
188
|
|
|
189
189
|
DUCKDB_API ClientProperties GetClientProperties() const;
|
|
190
190
|
|
|
191
|
+
//! Returns true if execution of the current query is finished
|
|
192
|
+
DUCKDB_API bool ExecutionIsFinished();
|
|
193
|
+
|
|
191
194
|
private:
|
|
192
195
|
//! Parse statements and resolve pragmas from a query
|
|
193
196
|
bool ParseStatements(ClientContextLock &lock, const string &query, vector<unique_ptr<SQLStatement>> &result,
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
#include "duckdb/common/winapi.hpp"
|
|
25
25
|
#include "duckdb/storage/compression/bitpacking.hpp"
|
|
26
26
|
#include "duckdb/function/cast/default_casts.hpp"
|
|
27
|
-
#include "duckdb/function/replacement_open.hpp"
|
|
28
27
|
#include "duckdb/function/replacement_scan.hpp"
|
|
29
28
|
#include "duckdb/function/create_database_extension.hpp"
|
|
30
29
|
#include "duckdb/optimizer/optimizer_extension.hpp"
|
|
@@ -163,9 +162,6 @@ public:
|
|
|
163
162
|
//! Replacement table scans are automatically attempted when a table name cannot be found in the schema
|
|
164
163
|
vector<ReplacementScan> replacement_scans;
|
|
165
164
|
|
|
166
|
-
//! Replacement open handlers are callbacks that run pre and post database initialization
|
|
167
|
-
vector<ReplacementOpen> replacement_opens;
|
|
168
|
-
|
|
169
165
|
//! Extra parameters that can be SET for loaded extensions
|
|
170
166
|
case_insensitive_map_t<ExtensionOption> extension_parameters;
|
|
171
167
|
//! The FileSystem to use, can be overwritten to allow for injecting custom file systems for testing purposes (e.g.
|
|
@@ -23,6 +23,7 @@ class ConnectionManager;
|
|
|
23
23
|
class FileSystem;
|
|
24
24
|
class TaskScheduler;
|
|
25
25
|
class ObjectCache;
|
|
26
|
+
struct AttachInfo;
|
|
26
27
|
|
|
27
28
|
class DatabaseInstance : public std::enable_shared_from_this<DatabaseInstance> {
|
|
28
29
|
friend class DuckDB;
|
|
@@ -48,9 +49,14 @@ public:
|
|
|
48
49
|
DUCKDB_API static DatabaseInstance &GetDatabase(ClientContext &context);
|
|
49
50
|
|
|
50
51
|
DUCKDB_API const unordered_set<std::string> &LoadedExtensions();
|
|
52
|
+
DUCKDB_API bool ExtensionIsLoaded(const std::string &name);
|
|
51
53
|
|
|
52
54
|
DUCKDB_API bool TryGetCurrentSetting(const std::string &key, Value &result);
|
|
53
55
|
|
|
56
|
+
//! Get the database extension type from a given path
|
|
57
|
+
string ExtractDatabaseType(string &path);
|
|
58
|
+
unique_ptr<AttachedDatabase> CreateAttachedDatabase(AttachInfo &info, const string &type, AccessMode access_mode);
|
|
59
|
+
|
|
54
60
|
private:
|
|
55
61
|
void Initialize(const char *path, DBConfig *config);
|
|
56
62
|
|
|
@@ -42,6 +42,7 @@ public:
|
|
|
42
42
|
|
|
43
43
|
static void InstallExtension(ClientContext &context, const string &extension, bool force_install);
|
|
44
44
|
static void LoadExternalExtension(ClientContext &context, const string &extension);
|
|
45
|
+
static void LoadExternalExtension(DatabaseInstance &db, FileOpener *opener, const string &extension);
|
|
45
46
|
|
|
46
47
|
static string ExtensionDirectory(ClientContext &context);
|
|
47
48
|
|
|
@@ -53,13 +54,14 @@ public:
|
|
|
53
54
|
|
|
54
55
|
static const vector<string> GetPublicKeys();
|
|
55
56
|
|
|
56
|
-
static
|
|
57
|
-
static void ReplacementOpenPost(ClientContext &context, const string &extension, DatabaseInstance &instance,
|
|
58
|
-
ReplacementOpenData *open_data);
|
|
57
|
+
static void StorageInit(string &extension, DBConfig &config);
|
|
59
58
|
|
|
60
59
|
// Returns extension name, or empty string if not a replacement open path
|
|
61
60
|
static string ExtractExtensionPrefixFromPath(const string &path);
|
|
62
61
|
|
|
62
|
+
//! Apply any known extension aliases
|
|
63
|
+
static string ApplyExtensionAlias(string extension_name);
|
|
64
|
+
|
|
63
65
|
private:
|
|
64
66
|
static const vector<string> PathComponents();
|
|
65
67
|
static ExtensionInitResult InitialLoad(DBConfig &context, FileOpener *opener, const string &extension);
|
|
@@ -68,8 +70,6 @@ private:
|
|
|
68
70
|
//! Version tags occur with and without 'v', tag in extension path is always with 'v'
|
|
69
71
|
static const string NormalizeVersionTag(const string &version_tag);
|
|
70
72
|
static bool IsRelease(const string &version_tag);
|
|
71
|
-
//! Apply any known extension aliases
|
|
72
|
-
static string ApplyExtensionAlias(string extension_name);
|
|
73
73
|
static bool CreateSuggestions(const string &extension_name, string &message);
|
|
74
74
|
|
|
75
75
|
private:
|
|
@@ -14,11 +14,12 @@ namespace duckdb {
|
|
|
14
14
|
|
|
15
15
|
class WriteCSVRelation : public Relation {
|
|
16
16
|
public:
|
|
17
|
-
WriteCSVRelation(shared_ptr<Relation> child, string csv_file);
|
|
17
|
+
WriteCSVRelation(shared_ptr<Relation> child, string csv_file, case_insensitive_map_t<vector<Value>> options);
|
|
18
18
|
|
|
19
19
|
shared_ptr<Relation> child;
|
|
20
20
|
string csv_file;
|
|
21
21
|
vector<ColumnDefinition> columns;
|
|
22
|
+
case_insensitive_map_t<vector<Value>> options;
|
|
22
23
|
|
|
23
24
|
public:
|
|
24
25
|
BoundStatement Bind(Binder &binder) override;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//===----------------------------------------------------------------------===//
|
|
2
|
+
// DuckDB
|
|
3
|
+
//
|
|
4
|
+
// duckdb/main/relation/write_csv_relation.hpp
|
|
5
|
+
//
|
|
6
|
+
//
|
|
7
|
+
//===----------------------------------------------------------------------===//
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include "duckdb/main/relation.hpp"
|
|
12
|
+
|
|
13
|
+
namespace duckdb {
|
|
14
|
+
|
|
15
|
+
class WriteParquetRelation : public Relation {
|
|
16
|
+
public:
|
|
17
|
+
WriteParquetRelation(shared_ptr<Relation> child, string parquet_file,
|
|
18
|
+
case_insensitive_map_t<vector<Value>> options);
|
|
19
|
+
|
|
20
|
+
shared_ptr<Relation> child;
|
|
21
|
+
string parquet_file;
|
|
22
|
+
vector<ColumnDefinition> columns;
|
|
23
|
+
case_insensitive_map_t<vector<Value>> options;
|
|
24
|
+
|
|
25
|
+
public:
|
|
26
|
+
BoundStatement Bind(Binder &binder) override;
|
|
27
|
+
const vector<ColumnDefinition> &Columns() override;
|
|
28
|
+
string ToString(idx_t depth) override;
|
|
29
|
+
bool IsReadOnly() override {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
} // namespace duckdb
|
|
@@ -126,7 +126,12 @@ public:
|
|
|
126
126
|
DUCKDB_API void Create(const string &schema_name, const string &table_name);
|
|
127
127
|
|
|
128
128
|
//! Write a relation to a CSV file
|
|
129
|
-
DUCKDB_API void WriteCSV(const string &csv_file
|
|
129
|
+
DUCKDB_API void WriteCSV(const string &csv_file,
|
|
130
|
+
case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
|
|
131
|
+
//! Write a relation to a Parquet file
|
|
132
|
+
DUCKDB_API void
|
|
133
|
+
WriteParquet(const string &parquet_file,
|
|
134
|
+
case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
|
|
130
135
|
|
|
131
136
|
//! Update a table, can only be used on a TableRelation
|
|
132
137
|
DUCKDB_API virtual void Update(const string &update, const string &condition = string());
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#include "duckdb/common/vector.hpp"
|
|
13
13
|
#include "duckdb/common/unordered_map.hpp"
|
|
14
14
|
#include "duckdb/common/types/value.hpp"
|
|
15
|
+
#include "duckdb/common/case_insensitive_map.hpp"
|
|
15
16
|
|
|
16
17
|
namespace duckdb {
|
|
17
18
|
|
|
@@ -34,7 +35,7 @@ struct CopyInfo : public ParseInfo {
|
|
|
34
35
|
//! The file path to copy to/from
|
|
35
36
|
string file_path;
|
|
36
37
|
//! Set of (key, value) options
|
|
37
|
-
|
|
38
|
+
case_insensitive_map_t<vector<Value>> options;
|
|
38
39
|
|
|
39
40
|
public:
|
|
40
41
|
unique_ptr<CopyInfo> Copy() const {
|
|
@@ -22,7 +22,7 @@ public:
|
|
|
22
22
|
// The SQL statement used instead of a table when copying data out to a file
|
|
23
23
|
unique_ptr<QueryNode> select_statement;
|
|
24
24
|
string ToString() const override;
|
|
25
|
-
string CopyOptionsToString(const string &format, const
|
|
25
|
+
string CopyOptionsToString(const string &format, const case_insensitive_map_t<vector<Value>> &options) const;
|
|
26
26
|
|
|
27
27
|
protected:
|
|
28
28
|
CopyStatement(const CopyStatement &other);
|
|
@@ -168,7 +168,7 @@ public:
|
|
|
168
168
|
void BindOnConflictClause(LogicalInsert &insert, TableCatalogEntry &table, InsertStatement &stmt);
|
|
169
169
|
|
|
170
170
|
static void BindSchemaOrCatalog(ClientContext &context, string &catalog, string &schema);
|
|
171
|
-
static void BindLogicalType(ClientContext &context, LogicalType &type,
|
|
171
|
+
static void BindLogicalType(ClientContext &context, LogicalType &type, Catalog *catalog = nullptr,
|
|
172
172
|
const string &schema = INVALID_SCHEMA);
|
|
173
173
|
|
|
174
174
|
bool HasMatchingBinding(const string &table_name, const string &column_name, string &error_message);
|
|
@@ -66,12 +66,13 @@ public:
|
|
|
66
66
|
public:
|
|
67
67
|
//! Initialize a scan on the index with the given expression and column ids
|
|
68
68
|
//! to fetch from the base table when we only have one query predicate
|
|
69
|
-
virtual unique_ptr<IndexScanState> InitializeScanSinglePredicate(Transaction &transaction, Value value,
|
|
69
|
+
virtual unique_ptr<IndexScanState> InitializeScanSinglePredicate(const Transaction &transaction, const Value &value,
|
|
70
70
|
ExpressionType expressionType) = 0;
|
|
71
71
|
//! Initialize a scan on the index with the given expression and column ids
|
|
72
72
|
//! to fetch from the base table for two query predicates
|
|
73
|
-
virtual unique_ptr<IndexScanState> InitializeScanTwoPredicates(Transaction &transaction, Value low_value,
|
|
74
|
-
ExpressionType low_expression_type,
|
|
73
|
+
virtual unique_ptr<IndexScanState> InitializeScanTwoPredicates(Transaction &transaction, const Value &low_value,
|
|
74
|
+
ExpressionType low_expression_type,
|
|
75
|
+
const Value &high_value,
|
|
75
76
|
ExpressionType high_expression_type) = 0;
|
|
76
77
|
//! Perform a lookup on the index, fetching up to max_count result ids. Returns true if all row ids were fetched,
|
|
77
78
|
//! and false otherwise.
|
|
@@ -2287,6 +2287,13 @@ on the task state.
|
|
|
2287
2287
|
*/
|
|
2288
2288
|
DUCKDB_API void duckdb_destroy_task_state(duckdb_task_state state);
|
|
2289
2289
|
|
|
2290
|
+
/*!
|
|
2291
|
+
Returns true if execution of the current query is finished.
|
|
2292
|
+
|
|
2293
|
+
* con: The connection on which to check
|
|
2294
|
+
*/
|
|
2295
|
+
DUCKDB_API bool duckdb_execution_is_finished(duckdb_connection con);
|
|
2296
|
+
|
|
2290
2297
|
#ifdef __cplusplus
|
|
2291
2298
|
}
|
|
2292
2299
|
#endif
|
|
@@ -78,3 +78,11 @@ void duckdb_destroy_task_state(duckdb_task_state state_p) {
|
|
|
78
78
|
auto state = (CAPITaskState *)state_p;
|
|
79
79
|
delete state;
|
|
80
80
|
}
|
|
81
|
+
|
|
82
|
+
bool duckdb_execution_is_finished(duckdb_connection con) {
|
|
83
|
+
if (!con) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
duckdb::Connection *conn = (duckdb::Connection *)con;
|
|
87
|
+
return conn->context->ExecutionIsFinished();
|
|
88
|
+
}
|
|
@@ -1151,4 +1151,11 @@ ClientProperties ClientContext::GetClientProperties() const {
|
|
|
1151
1151
|
return properties;
|
|
1152
1152
|
}
|
|
1153
1153
|
|
|
1154
|
+
bool ClientContext::ExecutionIsFinished() {
|
|
1155
|
+
if (!active_query || !active_query->executor) {
|
|
1156
|
+
return false;
|
|
1157
|
+
}
|
|
1158
|
+
return active_query->executor->ExecutionIsFinished();
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1154
1161
|
} // namespace duckdb
|
|
@@ -8,4 +8,18 @@ bool ClientContextFileOpener::TryGetCurrentSetting(const string &key, Value &res
|
|
|
8
8
|
return context.TryGetCurrentSetting(key, result);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
ClientContext *FileOpener::TryGetClientContext(FileOpener *opener) {
|
|
12
|
+
if (!opener) {
|
|
13
|
+
return nullptr;
|
|
14
|
+
}
|
|
15
|
+
return opener->TryGetClientContext();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
bool FileOpener::TryGetCurrentSetting(FileOpener *opener, const string &key, Value &result) {
|
|
19
|
+
if (!opener) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return opener->TryGetCurrentSetting(key, result);
|
|
23
|
+
}
|
|
24
|
+
|
|
11
25
|
} // namespace duckdb
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
#include "duckdb/main/connection_manager.hpp"
|
|
12
12
|
#include "duckdb/function/compression_function.hpp"
|
|
13
13
|
#include "duckdb/main/extension_helper.hpp"
|
|
14
|
-
#include "duckdb/main/replacement_opens.hpp"
|
|
15
14
|
#include "duckdb/function/cast/cast_function_set.hpp"
|
|
16
15
|
#include "duckdb/main/error_manager.hpp"
|
|
17
16
|
#include "duckdb/main/attached_database.hpp"
|
|
18
17
|
#include "duckdb/parser/parsed_data/attach_info.hpp"
|
|
19
18
|
#include "duckdb/storage/magic_bytes.hpp"
|
|
19
|
+
#include "duckdb/storage/storage_extension.hpp"
|
|
20
20
|
|
|
21
21
|
#ifndef DUCKDB_NO_THREADS
|
|
22
22
|
#include "duckdb/common/thread.hpp"
|
|
@@ -26,7 +26,6 @@ namespace duckdb {
|
|
|
26
26
|
|
|
27
27
|
DBConfig::DBConfig() {
|
|
28
28
|
compression_functions = make_unique<CompressionFunctionSet>();
|
|
29
|
-
replacement_opens.push_back(ExtensionPrefixReplacementOpen());
|
|
30
29
|
cast_functions = make_unique<CastFunctionSet>();
|
|
31
30
|
error_manager = make_unique<ErrorManager>();
|
|
32
31
|
}
|
|
@@ -123,6 +122,42 @@ ConnectionManager &ConnectionManager::Get(ClientContext &context) {
|
|
|
123
122
|
return ConnectionManager::Get(DatabaseInstance::GetDatabase(context));
|
|
124
123
|
}
|
|
125
124
|
|
|
125
|
+
string DatabaseInstance::ExtractDatabaseType(string &path) {
|
|
126
|
+
// first check if there is an existing prefix
|
|
127
|
+
auto extension = ExtensionHelper::ExtractExtensionPrefixFromPath(path);
|
|
128
|
+
if (!extension.empty()) {
|
|
129
|
+
// path is prefixed with an extension - remove it
|
|
130
|
+
path = StringUtil::Replace(path, extension + ":", "");
|
|
131
|
+
return extension;
|
|
132
|
+
}
|
|
133
|
+
// if there isn't - check the magic bytes of the file (if any)
|
|
134
|
+
auto file_type = MagicBytes::CheckMagicBytes(config.file_system.get(), path);
|
|
135
|
+
if (file_type == DataFileType::SQLITE_FILE) {
|
|
136
|
+
return "sqlite";
|
|
137
|
+
}
|
|
138
|
+
return string();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
unique_ptr<AttachedDatabase> DatabaseInstance::CreateAttachedDatabase(AttachInfo &info, const string &type,
|
|
142
|
+
AccessMode access_mode) {
|
|
143
|
+
unique_ptr<AttachedDatabase> attached_database;
|
|
144
|
+
if (!type.empty()) {
|
|
145
|
+
// find the storage extensionon database
|
|
146
|
+
auto entry = config.storage_extensions.find(type);
|
|
147
|
+
if (entry == config.storage_extensions.end()) {
|
|
148
|
+
throw BinderException("Unrecognized storage type \"%s\"", type);
|
|
149
|
+
}
|
|
150
|
+
// use storage extension to create the initial database
|
|
151
|
+
attached_database = make_unique<AttachedDatabase>(*this, Catalog::GetSystemCatalog(*this), *entry->second,
|
|
152
|
+
info.name, info, access_mode);
|
|
153
|
+
} else {
|
|
154
|
+
// check if this is an in-memory database or not
|
|
155
|
+
attached_database =
|
|
156
|
+
make_unique<AttachedDatabase>(*this, Catalog::GetSystemCatalog(*this), info.name, info.path, access_mode);
|
|
157
|
+
}
|
|
158
|
+
return attached_database;
|
|
159
|
+
}
|
|
160
|
+
|
|
126
161
|
void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_config) {
|
|
127
162
|
DBConfig default_config;
|
|
128
163
|
DBConfig *config_ptr = &default_config;
|
|
@@ -145,22 +180,6 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf
|
|
|
145
180
|
} else {
|
|
146
181
|
config_ptr->options.database_path.clear();
|
|
147
182
|
}
|
|
148
|
-
|
|
149
|
-
auto file_type = MagicBytes::CheckMagicBytes(config_ptr->file_system.get(), config_ptr->options.database_path);
|
|
150
|
-
if (file_type == DataFileType::SQLITE_FILE) {
|
|
151
|
-
config_ptr->options.database_path = "sqlite:" + config_ptr->options.database_path;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
ReplacementOpen *replacement_open = nullptr;
|
|
155
|
-
for (auto &open : config_ptr->replacement_opens) {
|
|
156
|
-
if (open.pre_func) {
|
|
157
|
-
open.data = open.pre_func(*config_ptr, open.static_data.get());
|
|
158
|
-
if (open.data) {
|
|
159
|
-
replacement_open = &open;
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
183
|
Configure(*config_ptr);
|
|
165
184
|
|
|
166
185
|
if (user_config && !user_config->options.use_temporary_directory) {
|
|
@@ -168,7 +187,6 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf
|
|
|
168
187
|
config.options.temporary_directory = string();
|
|
169
188
|
}
|
|
170
189
|
|
|
171
|
-
auto &config = DBConfig::GetConfig(*this);
|
|
172
190
|
db_manager = make_unique<DatabaseManager>(*this);
|
|
173
191
|
buffer_manager =
|
|
174
192
|
make_unique<BufferManager>(*this, config.options.temporary_directory, config.options.maximum_memory);
|
|
@@ -176,22 +194,16 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf
|
|
|
176
194
|
object_cache = make_unique<ObjectCache>();
|
|
177
195
|
connection_manager = make_unique<ConnectionManager>();
|
|
178
196
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (
|
|
182
|
-
//
|
|
183
|
-
|
|
184
|
-
info.name = database_name;
|
|
185
|
-
info.path = config.options.database_path;
|
|
186
|
-
auto storage_extension = replacement_open->data->GetStorageExtension(info);
|
|
187
|
-
attached_database = make_unique<AttachedDatabase>(*this, Catalog::GetSystemCatalog(*this), *storage_extension,
|
|
188
|
-
database_name, info, config.options.access_mode);
|
|
189
|
-
replacement_open = nullptr;
|
|
190
|
-
} else {
|
|
191
|
-
// check if this is an in-memory database or not
|
|
192
|
-
attached_database = make_unique<AttachedDatabase>(*this, Catalog::GetSystemCatalog(*this), database_name,
|
|
193
|
-
config.options.database_path, config.options.access_mode);
|
|
197
|
+
// check if we are opening a standard DuckDB database or an extension database
|
|
198
|
+
auto database_type = ExtractDatabaseType(config.options.database_path);
|
|
199
|
+
if (!database_type.empty()) {
|
|
200
|
+
// we are opening an extension database, run storage_init
|
|
201
|
+
ExtensionHelper::StorageInit(database_type, config);
|
|
194
202
|
}
|
|
203
|
+
AttachInfo info;
|
|
204
|
+
info.name = AttachedDatabase::ExtractDatabaseName(config.options.database_path);
|
|
205
|
+
info.path = config.options.database_path;
|
|
206
|
+
auto attached_database = CreateAttachedDatabase(info, database_type, config.options.access_mode);
|
|
195
207
|
auto initial_database = attached_database.get();
|
|
196
208
|
{
|
|
197
209
|
Connection con(*this);
|
|
@@ -205,12 +217,13 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf
|
|
|
205
217
|
// initialize the database
|
|
206
218
|
initial_database->Initialize();
|
|
207
219
|
|
|
220
|
+
if (!database_type.empty()) {
|
|
221
|
+
// if we are opening an extension database - load the extension
|
|
222
|
+
ExtensionHelper::LoadExternalExtension(*this, nullptr, database_type);
|
|
223
|
+
}
|
|
224
|
+
|
|
208
225
|
// only increase thread count after storage init because we get races on catalog otherwise
|
|
209
226
|
scheduler->SetThreads(config.options.maximum_threads);
|
|
210
|
-
|
|
211
|
-
if (replacement_open) {
|
|
212
|
-
replacement_open->post_func(*this, replacement_open->data.get());
|
|
213
|
-
}
|
|
214
227
|
}
|
|
215
228
|
|
|
216
229
|
DuckDB::DuckDB(const char *path, DBConfig *new_config) : instance(make_shared<DatabaseInstance>()) {
|
|
@@ -294,7 +307,6 @@ void DatabaseInstance::Configure(DBConfig &new_config) {
|
|
|
294
307
|
config.allocator = make_unique<Allocator>();
|
|
295
308
|
}
|
|
296
309
|
config.replacement_scans = std::move(new_config.replacement_scans);
|
|
297
|
-
config.replacement_opens = std::move(new_config.replacement_opens);
|
|
298
310
|
config.parser_extensions = std::move(new_config.parser_extensions);
|
|
299
311
|
config.error_manager = std::move(new_config.error_manager);
|
|
300
312
|
if (!config.error_manager) {
|
|
@@ -325,9 +337,14 @@ idx_t DuckDB::NumberOfThreads() {
|
|
|
325
337
|
return instance->NumberOfThreads();
|
|
326
338
|
}
|
|
327
339
|
|
|
340
|
+
bool DatabaseInstance::ExtensionIsLoaded(const std::string &name) {
|
|
341
|
+
return loaded_extensions.find(name) != loaded_extensions.end();
|
|
342
|
+
}
|
|
343
|
+
|
|
328
344
|
bool DuckDB::ExtensionIsLoaded(const std::string &name) {
|
|
329
|
-
return instance->
|
|
345
|
+
return instance->ExtensionIsLoaded(name);
|
|
330
346
|
}
|
|
347
|
+
|
|
331
348
|
void DatabaseInstance::SetExtensionLoaded(const std::string &name) {
|
|
332
349
|
loaded_extensions.insert(name);
|
|
333
350
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#include "duckdb/common/dl.hpp"
|
|
2
2
|
#include "duckdb/common/virtual_file_system.hpp"
|
|
3
|
-
#include "duckdb/function/replacement_open.hpp"
|
|
4
3
|
#include "duckdb/main/extension_helper.hpp"
|
|
5
4
|
#include "duckdb/main/error_manager.hpp"
|
|
6
5
|
#include "mbedtls_wrapper.hpp"
|
|
@@ -12,6 +11,7 @@ namespace duckdb {
|
|
|
12
11
|
//===--------------------------------------------------------------------===//
|
|
13
12
|
typedef void (*ext_init_fun_t)(DatabaseInstance &);
|
|
14
13
|
typedef const char *(*ext_version_fun_t)(void);
|
|
14
|
+
typedef void (*ext_storage_init_t)(DBConfig &);
|
|
15
15
|
|
|
16
16
|
template <class T>
|
|
17
17
|
static T LoadFunctionFromDLL(void *dll, const string &function_name, const string &filename) {
|
|
@@ -121,14 +121,13 @@ ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileOpener *o
|
|
|
121
121
|
return res;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
void ExtensionHelper::LoadExternalExtension(
|
|
125
|
-
auto &db = DatabaseInstance::GetDatabase(context);
|
|
124
|
+
void ExtensionHelper::LoadExternalExtension(DatabaseInstance &db, FileOpener *opener, const string &extension) {
|
|
126
125
|
auto &loaded_extensions = db.LoadedExtensions();
|
|
127
126
|
if (loaded_extensions.find(extension) != loaded_extensions.end()) {
|
|
128
127
|
return;
|
|
129
128
|
}
|
|
130
129
|
|
|
131
|
-
auto res = InitialLoad(DBConfig::GetConfig(
|
|
130
|
+
auto res = InitialLoad(DBConfig::GetConfig(db), opener, extension);
|
|
132
131
|
auto init_fun_name = res.basename + "_init";
|
|
133
132
|
|
|
134
133
|
ext_init_fun_t init_fun;
|
|
@@ -141,38 +140,27 @@ void ExtensionHelper::LoadExternalExtension(ClientContext &context, const string
|
|
|
141
140
|
init_fun_name, res.filename, e.what());
|
|
142
141
|
}
|
|
143
142
|
|
|
144
|
-
|
|
143
|
+
db.SetExtensionLoaded(extension);
|
|
145
144
|
}
|
|
146
145
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
auto res = InitialLoad(config, nullptr, extension); // TODO opener
|
|
150
|
-
auto init_fun_name = res.basename + "_replacement_open_pre";
|
|
151
|
-
|
|
152
|
-
replacement_open_pre_t open_pre_fun;
|
|
153
|
-
open_pre_fun = LoadFunctionFromDLL<replacement_open_pre_t>(res.lib_hdl, init_fun_name, res.filename);
|
|
154
|
-
|
|
155
|
-
try {
|
|
156
|
-
return (*open_pre_fun)(config, nullptr);
|
|
157
|
-
} catch (std::exception &e) {
|
|
158
|
-
throw InvalidInputException("Initialization function \"%s\" from file \"%s\" threw an exception: \"%s\"",
|
|
159
|
-
init_fun_name, res.filename, e.what());
|
|
160
|
-
}
|
|
146
|
+
void ExtensionHelper::LoadExternalExtension(ClientContext &context, const string &extension) {
|
|
147
|
+
LoadExternalExtension(DatabaseInstance::GetDatabase(context), FileSystem::GetFileOpener(context), extension);
|
|
161
148
|
}
|
|
162
149
|
|
|
163
|
-
void ExtensionHelper::
|
|
164
|
-
|
|
165
|
-
auto res = InitialLoad(
|
|
166
|
-
auto
|
|
150
|
+
void ExtensionHelper::StorageInit(string &extension, DBConfig &config) {
|
|
151
|
+
extension = ExtensionHelper::ApplyExtensionAlias(extension);
|
|
152
|
+
auto res = InitialLoad(config, nullptr, extension); // TODO opener
|
|
153
|
+
auto storage_fun_name = res.basename + "_storage_init";
|
|
167
154
|
|
|
168
|
-
|
|
169
|
-
|
|
155
|
+
ext_storage_init_t storage_init_fun;
|
|
156
|
+
storage_init_fun = LoadFunctionFromDLL<ext_storage_init_t>(res.lib_hdl, storage_fun_name, res.filename);
|
|
170
157
|
|
|
171
158
|
try {
|
|
172
|
-
(*
|
|
159
|
+
(*storage_init_fun)(config);
|
|
173
160
|
} catch (std::exception &e) {
|
|
174
|
-
throw InvalidInputException(
|
|
175
|
-
|
|
161
|
+
throw InvalidInputException(
|
|
162
|
+
"Storage initialization function \"%s\" from file \"%s\" threw an exception: \"%s\"", storage_fun_name,
|
|
163
|
+
res.filename, e.what());
|
|
176
164
|
}
|
|
177
165
|
}
|
|
178
166
|
|
|
@@ -189,6 +177,10 @@ string ExtensionHelper::ExtractExtensionPrefixFromPath(const string &path) {
|
|
|
189
177
|
return "";
|
|
190
178
|
}
|
|
191
179
|
}
|
|
180
|
+
if (extension == "http" || extension == "https" || extension == "s3") {
|
|
181
|
+
// these are not extensions
|
|
182
|
+
return "";
|
|
183
|
+
}
|
|
192
184
|
return extension;
|
|
193
185
|
}
|
|
194
186
|
|