duckdb 0.7.1-dev37.0 → 0.7.1-dev415.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/README.md +1 -1
- package/binding.gyp +7 -7
- package/package.json +3 -3
- package/src/duckdb/extension/json/buffered_json_reader.cpp +50 -9
- package/src/duckdb/extension/json/include/buffered_json_reader.hpp +7 -2
- package/src/duckdb/extension/json/include/json_scan.hpp +45 -10
- package/src/duckdb/extension/json/json_functions/copy_json.cpp +35 -22
- package/src/duckdb/extension/json/json_functions/json_create.cpp +8 -8
- package/src/duckdb/extension/json/json_functions/json_structure.cpp +8 -3
- package/src/duckdb/extension/json/json_functions/json_transform.cpp +54 -10
- package/src/duckdb/extension/json/json_functions/read_json.cpp +104 -49
- package/src/duckdb/extension/json/json_functions/read_json_objects.cpp +5 -3
- package/src/duckdb/extension/json/json_functions.cpp +7 -0
- package/src/duckdb/extension/json/json_scan.cpp +144 -37
- package/src/duckdb/extension/parquet/column_reader.cpp +7 -0
- package/src/duckdb/extension/parquet/include/column_reader.hpp +1 -0
- package/src/duckdb/extension/parquet/parquet-extension.cpp +2 -9
- package/src/duckdb/src/catalog/catalog.cpp +62 -13
- package/src/duckdb/src/catalog/catalog_entry/index_catalog_entry.cpp +8 -7
- package/src/duckdb/src/catalog/catalog_entry/schema_catalog_entry.cpp +1 -1
- package/src/duckdb/src/catalog/catalog_set.cpp +1 -1
- package/src/duckdb/src/catalog/default/default_views.cpp +1 -1
- package/src/duckdb/src/common/bind_helpers.cpp +55 -0
- package/src/duckdb/src/common/enums/logical_operator_type.cpp +2 -0
- package/src/duckdb/src/common/enums/physical_operator_type.cpp +2 -0
- package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
- package/src/duckdb/src/common/file_system.cpp +28 -0
- package/src/duckdb/src/common/hive_partitioning.cpp +1 -0
- package/src/duckdb/src/common/local_file_system.cpp +4 -4
- package/src/duckdb/src/common/operator/cast_operators.cpp +10 -4
- package/src/duckdb/src/common/string_util.cpp +8 -4
- package/src/duckdb/src/common/types/partitioned_column_data.cpp +1 -0
- package/src/duckdb/src/common/types/time.cpp +1 -1
- package/src/duckdb/src/common/types/timestamp.cpp +35 -4
- package/src/duckdb/src/common/types.cpp +37 -11
- package/src/duckdb/src/execution/column_binding_resolver.cpp +5 -2
- package/src/duckdb/src/execution/index/art/art.cpp +117 -67
- package/src/duckdb/src/execution/index/art/art_key.cpp +24 -12
- package/src/duckdb/src/execution/index/art/leaf.cpp +7 -8
- package/src/duckdb/src/execution/index/art/node.cpp +13 -27
- package/src/duckdb/src/execution/index/art/node16.cpp +5 -8
- package/src/duckdb/src/execution/index/art/node256.cpp +3 -5
- package/src/duckdb/src/execution/index/art/node4.cpp +4 -7
- package/src/duckdb/src/execution/index/art/node48.cpp +5 -8
- package/src/duckdb/src/execution/index/art/prefix.cpp +2 -3
- package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +6 -27
- package/src/duckdb/src/execution/operator/helper/physical_reset.cpp +1 -9
- package/src/duckdb/src/execution/operator/helper/physical_set.cpp +1 -9
- package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +7 -9
- package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +6 -11
- package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +13 -13
- package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +37 -0
- package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +0 -5
- package/src/duckdb/src/execution/physical_operator.cpp +6 -6
- package/src/duckdb/src/execution/physical_plan/plan_simple.cpp +4 -0
- package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -0
- package/src/duckdb/src/function/pragma/pragma_queries.cpp +38 -11
- package/src/duckdb/src/function/scalar/generic/current_setting.cpp +2 -2
- package/src/duckdb/src/function/scalar/map/map.cpp +69 -21
- package/src/duckdb/src/function/table/read_csv.cpp +17 -5
- package/src/duckdb/src/function/table/system/duckdb_temporary_files.cpp +59 -0
- package/src/duckdb/src/function/table/system_functions.cpp +1 -0
- package/src/duckdb/src/function/table/table_scan.cpp +3 -0
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +7 -1
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +1 -1
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/bind_helpers.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +3 -2
- package/src/duckdb/src/include/duckdb/common/enums/wal_type.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/exception.hpp +10 -0
- package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +9 -1
- package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +4 -4
- package/src/duckdb/src/include/duckdb/common/string_util.hpp +9 -2
- package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +5 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +37 -41
- package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +8 -11
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +1 -3
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
- package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_detach.hpp +32 -0
- package/src/duckdb/src/include/duckdb/function/table/system_functions.hpp +4 -0
- package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -2
- package/src/duckdb/src/include/duckdb/main/config.hpp +2 -3
- package/src/duckdb/src/include/duckdb/main/{extension_functions.hpp → extension_entries.hpp} +26 -5
- package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +3 -0
- package/src/duckdb/src/include/duckdb/main/settings.hpp +9 -0
- package/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp +0 -7
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -4
- package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +32 -0
- package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -2
- package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/statement/detach_statement.hpp +29 -0
- package/src/duckdb/src/include/duckdb/parser/statement/list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +3 -3
- package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/expression_binder/index_binder.hpp +10 -3
- package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +1 -5
- package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +1 -2
- package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +8 -0
- package/src/duckdb/src/include/duckdb/storage/data_table.hpp +7 -1
- package/src/duckdb/src/include/duckdb/storage/index.hpp +47 -38
- package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
- package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +7 -0
- package/src/duckdb/src/main/client_context.cpp +2 -0
- package/src/duckdb/src/main/config.cpp +1 -0
- package/src/duckdb/src/main/database.cpp +14 -5
- package/src/duckdb/src/main/extension/extension_alias.cpp +2 -1
- package/src/duckdb/src/main/extension/extension_install.cpp +43 -9
- package/src/duckdb/src/main/extension/extension_load.cpp +29 -5
- package/src/duckdb/src/main/settings/settings.cpp +16 -0
- package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +2 -6
- package/src/duckdb/src/parallel/pipeline_executor.cpp +1 -55
- package/src/duckdb/src/parser/parsed_data/create_index_info.cpp +3 -0
- package/src/duckdb/src/parser/statement/copy_statement.cpp +2 -13
- package/src/duckdb/src/parser/statement/delete_statement.cpp +3 -0
- package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
- package/src/duckdb/src/parser/statement/insert_statement.cpp +9 -0
- package/src/duckdb/src/parser/statement/update_statement.cpp +3 -0
- package/src/duckdb/src/parser/transform/expression/transform_case.cpp +3 -3
- package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -1
- package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +19 -0
- package/src/duckdb/src/parser/transformer.cpp +2 -0
- package/src/duckdb/src/planner/bind_context.cpp +1 -1
- package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +3 -0
- package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +7 -14
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +16 -14
- package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +13 -0
- package/src/duckdb/src/planner/binder/statement/bind_detach.cpp +19 -0
- package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +29 -4
- package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +22 -1
- package/src/duckdb/src/planner/binder.cpp +2 -0
- package/src/duckdb/src/planner/expression_binder/index_binder.cpp +32 -1
- package/src/duckdb/src/planner/logical_operator.cpp +6 -1
- package/src/duckdb/src/planner/planner.cpp +1 -0
- package/src/duckdb/src/storage/buffer_manager.cpp +105 -26
- package/src/duckdb/src/storage/compression/bitpacking.cpp +16 -7
- package/src/duckdb/src/storage/data_table.cpp +66 -3
- package/src/duckdb/src/storage/index.cpp +1 -1
- package/src/duckdb/src/storage/local_storage.cpp +1 -1
- package/src/duckdb/src/storage/table/column_data.cpp +4 -2
- package/src/duckdb/src/storage/table/update_segment.cpp +15 -0
- package/src/duckdb/src/storage/table_index_list.cpp +1 -2
- package/src/duckdb/src/storage/wal_replay.cpp +68 -0
- package/src/duckdb/src/storage/write_ahead_log.cpp +21 -1
- package/src/duckdb/src/transaction/commit_state.cpp +5 -2
- package/src/duckdb/third_party/concurrentqueue/blockingconcurrentqueue.h +2 -2
- package/src/duckdb/third_party/fmt/include/fmt/core.h +1 -2
- package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +1 -0
- package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +14 -0
- package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +530 -1006
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +17659 -17626
- package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
- package/src/duckdb/ub_src_execution_operator_schema.cpp +2 -0
- package/src/duckdb/ub_src_function_table_system.cpp +2 -0
- package/src/duckdb/ub_src_parser_statement.cpp +2 -0
- package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
- package/src/duckdb/ub_src_planner_binder_statement.cpp +2 -0
- package/src/statement.cpp +46 -12
- package/test/arrow.test.ts +3 -3
- package/test/prepare.test.ts +39 -1
- package/test/typescript_decls.test.ts +1 -1
- package/src/duckdb/src/include/duckdb/function/create_database_extension.hpp +0 -37
|
@@ -32,11 +32,7 @@ protected:
|
|
|
32
32
|
// already resolved
|
|
33
33
|
}
|
|
34
34
|
vector<ColumnBinding> GetColumnBindings() override {
|
|
35
|
-
|
|
36
|
-
for (idx_t i = 0; i < types.size(); i++) {
|
|
37
|
-
bindings.push_back(ColumnBinding(0, i));
|
|
38
|
-
}
|
|
39
|
-
return bindings;
|
|
35
|
+
return GenerateColumnBindings(0, types.size());
|
|
40
36
|
}
|
|
41
37
|
};
|
|
42
38
|
} // namespace duckdb
|
|
@@ -33,8 +33,7 @@ protected:
|
|
|
33
33
|
LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR};
|
|
34
34
|
}
|
|
35
35
|
vector<ColumnBinding> GetColumnBindings() override {
|
|
36
|
-
return
|
|
37
|
-
ColumnBinding(0, 3), ColumnBinding(0, 4), ColumnBinding(0, 5)};
|
|
36
|
+
return GenerateColumnBindings(0, types.size());
|
|
38
37
|
}
|
|
39
38
|
};
|
|
40
39
|
} // namespace duckdb
|
|
@@ -23,6 +23,11 @@ class DatabaseInstance;
|
|
|
23
23
|
class TemporaryDirectoryHandle;
|
|
24
24
|
struct EvictionQueue;
|
|
25
25
|
|
|
26
|
+
struct TemporaryFileInformation {
|
|
27
|
+
string path;
|
|
28
|
+
idx_t size;
|
|
29
|
+
};
|
|
30
|
+
|
|
26
31
|
//! The buffer manager is in charge of handling memory management for the database. It hands out memory buffers that can
|
|
27
32
|
//! be used by the database internally.
|
|
28
33
|
//
|
|
@@ -98,6 +103,9 @@ public:
|
|
|
98
103
|
DUCKDB_API void ReserveMemory(idx_t size);
|
|
99
104
|
DUCKDB_API void FreeReservedMemory(idx_t size);
|
|
100
105
|
|
|
106
|
+
//! Returns a list of all temporary files
|
|
107
|
+
vector<TemporaryFileInformation> GetTemporaryFiles();
|
|
108
|
+
|
|
101
109
|
private:
|
|
102
110
|
//! Register an in-memory buffer of arbitrary size, as long as it is >= BLOCK_SIZE. can_destroy signifies whether or
|
|
103
111
|
//! not the buffer can be destroyed when unpinned, or whether or not it needs to be written to a temporary file so
|
|
@@ -122,6 +122,12 @@ public:
|
|
|
122
122
|
void UpdateColumn(TableCatalogEntry &table, ClientContext &context, Vector &row_ids,
|
|
123
123
|
const vector<column_t> &column_path, DataChunk &updates);
|
|
124
124
|
|
|
125
|
+
//! Add an index to the DataTable. NOTE: for CREATE (UNIQUE) INDEX statements, we use the PhysicalCreateIndex
|
|
126
|
+
//! operator. This function is only used during the WAL replay, and is a much less performant index creation
|
|
127
|
+
//! approach.
|
|
128
|
+
void WALAddIndex(ClientContext &context, unique_ptr<Index> index,
|
|
129
|
+
const vector<unique_ptr<Expression>> &expressions);
|
|
130
|
+
|
|
125
131
|
//! Fetches an append lock
|
|
126
132
|
void AppendLock(TableAppendState &state);
|
|
127
133
|
//! Begin appending structs to this table, obtaining necessary locks, etc
|
|
@@ -176,7 +182,7 @@ public:
|
|
|
176
182
|
static bool IsForeignKeyIndex(const vector<PhysicalIndex> &fk_keys, Index &index, ForeignKeyType fk_type);
|
|
177
183
|
|
|
178
184
|
//! Initializes a special scan that is used to create an index on the table, it keeps locks on the table
|
|
179
|
-
void
|
|
185
|
+
void InitializeWALCreateIndexScan(CreateIndexScanState &state, const vector<column_t> &column_ids);
|
|
180
186
|
//! Scans the next chunk for the CREATE INDEX operator
|
|
181
187
|
bool CreateIndexScan(TableScanState &state, DataChunk &result, TableScanType type);
|
|
182
188
|
|
|
@@ -40,11 +40,11 @@ public:
|
|
|
40
40
|
IndexType type;
|
|
41
41
|
//! Associated table io manager
|
|
42
42
|
TableIOManager &table_io_manager;
|
|
43
|
-
//! Column identifiers to extract from the base table
|
|
43
|
+
//! Column identifiers to extract key columns from the base table
|
|
44
44
|
vector<column_t> column_ids;
|
|
45
|
-
//!
|
|
45
|
+
//! Unordered set of column_ids used by the index
|
|
46
46
|
unordered_set<column_t> column_id_set;
|
|
47
|
-
//! Unbound expressions used by the index
|
|
47
|
+
//! Unbound expressions used by the index during optimizations
|
|
48
48
|
vector<unique_ptr<Expression>> unbound_expressions;
|
|
49
49
|
//! The physical types stored in the index
|
|
50
50
|
vector<PhysicalType> types;
|
|
@@ -64,94 +64,103 @@ public:
|
|
|
64
64
|
bool track_memory;
|
|
65
65
|
|
|
66
66
|
public:
|
|
67
|
-
//! Initialize a scan on the index with the given expression and column
|
|
68
|
-
//! to fetch from the base table when we only have one query predicate
|
|
67
|
+
//! Initialize a single predicate scan on the index with the given expression and column IDs
|
|
69
68
|
virtual unique_ptr<IndexScanState> InitializeScanSinglePredicate(const Transaction &transaction, const Value &value,
|
|
70
69
|
ExpressionType expressionType) = 0;
|
|
71
|
-
//! Initialize a scan on the index with the given expression and column
|
|
72
|
-
//! to fetch from the base table for two query predicates
|
|
70
|
+
//! Initialize a two predicate scan on the index with the given expression and column IDs
|
|
73
71
|
virtual unique_ptr<IndexScanState> InitializeScanTwoPredicates(Transaction &transaction, const Value &low_value,
|
|
74
72
|
ExpressionType low_expression_type,
|
|
75
73
|
const Value &high_value,
|
|
76
74
|
ExpressionType high_expression_type) = 0;
|
|
77
|
-
//!
|
|
78
|
-
//! and false otherwise
|
|
75
|
+
//! Performs a lookup on the index, fetching up to max_count result IDs. Returns true if all row IDs were fetched,
|
|
76
|
+
//! and false otherwise
|
|
79
77
|
virtual bool Scan(Transaction &transaction, DataTable &table, IndexScanState &state, idx_t max_count,
|
|
80
78
|
vector<row_t> &result_ids) = 0;
|
|
81
79
|
|
|
82
80
|
//! Obtain a lock on the index
|
|
83
81
|
virtual void InitializeLock(IndexLock &state);
|
|
84
|
-
//! Called when data is appended to the index. The lock obtained from
|
|
82
|
+
//! Called when data is appended to the index. The lock obtained from InitializeLock must be held
|
|
85
83
|
virtual bool Append(IndexLock &state, DataChunk &entries, Vector &row_identifiers) = 0;
|
|
84
|
+
//! Obtains a lock and calls Append while holding that lock
|
|
86
85
|
bool Append(DataChunk &entries, Vector &row_identifiers);
|
|
87
|
-
//! Verify that data can be appended to the index
|
|
86
|
+
//! Verify that data can be appended to the index without a constraint violation
|
|
88
87
|
virtual void VerifyAppend(DataChunk &chunk) = 0;
|
|
89
|
-
//! Verify that data can be appended to the index
|
|
88
|
+
//! Verify that data can be appended to the index without a constraint violation using the conflict manager
|
|
90
89
|
virtual void VerifyAppend(DataChunk &chunk, ConflictManager &conflict_manager) = 0;
|
|
91
|
-
//!
|
|
92
|
-
virtual void
|
|
93
|
-
//! Verify that data can be delete from the index for foreign key constraint
|
|
94
|
-
virtual void VerifyDeleteForeignKey(DataChunk &chunk) = 0;
|
|
90
|
+
//! Performs constraint checking for a chunk of input data
|
|
91
|
+
virtual void CheckConstraintsForChunk(DataChunk &input, ConflictManager &conflict_manager) = 0;
|
|
95
92
|
|
|
96
|
-
//!
|
|
93
|
+
//! Delete a chunk of entries from the index. The lock obtained from InitializeLock must be held
|
|
97
94
|
virtual void Delete(IndexLock &state, DataChunk &entries, Vector &row_identifiers) = 0;
|
|
95
|
+
//! Obtains a lock and calls Delete while holding that lock
|
|
98
96
|
void Delete(DataChunk &entries, Vector &row_identifiers);
|
|
99
97
|
|
|
100
|
-
//! Insert
|
|
98
|
+
//! Insert a chunk of entries into the index
|
|
101
99
|
virtual bool Insert(IndexLock &lock, DataChunk &input, Vector &row_identifiers) = 0;
|
|
102
100
|
|
|
103
|
-
//! Merge
|
|
101
|
+
//! Merge another index into this index. The lock obtained from InitializeLock must be held, and the other
|
|
102
|
+
//! index must also be locked during the merge
|
|
104
103
|
virtual bool MergeIndexes(IndexLock &state, Index *other_index) = 0;
|
|
104
|
+
//! Obtains a lock and calls MergeIndexes while holding that lock
|
|
105
105
|
bool MergeIndexes(Index *other_index);
|
|
106
106
|
|
|
107
107
|
//! Returns the string representation of an index
|
|
108
108
|
virtual string ToString() = 0;
|
|
109
|
-
//! Verifies that the
|
|
109
|
+
//! Verifies that the in-memory size value of the index matches its actual size
|
|
110
110
|
virtual void Verify() = 0;
|
|
111
|
-
|
|
112
|
-
//!
|
|
111
|
+
//! Increases the memory size by the difference between the old size and the current size
|
|
112
|
+
//! and performs verifications
|
|
113
|
+
virtual void IncreaseAndVerifyMemorySize(idx_t old_memory_size) = 0;
|
|
114
|
+
|
|
115
|
+
//! Increases the in-memory size value
|
|
116
|
+
inline void IncreaseMemorySize(idx_t size) {
|
|
117
|
+
memory_size += size;
|
|
118
|
+
};
|
|
119
|
+
//! Decreases the in-memory size value
|
|
120
|
+
inline void DecreaseMemorySize(idx_t size) {
|
|
121
|
+
D_ASSERT(memory_size >= size);
|
|
122
|
+
memory_size -= size;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
//! Returns true if the index is affected by updates on the specified column IDs, and false otherwise
|
|
113
126
|
bool IndexIsUpdated(const vector<PhysicalIndex> &column_ids) const;
|
|
114
127
|
|
|
115
|
-
//! Returns how many of the input values were found in the 'input' chunk, with the option to also record what those
|
|
116
|
-
//! matches were. For this purpose, nulls count as a match, and are returned in 'null_count'
|
|
117
|
-
virtual void LookupValues(DataChunk &input, ConflictManager &conflict_manager) = 0;
|
|
118
|
-
|
|
119
128
|
//! Returns unique flag
|
|
120
129
|
bool IsUnique() {
|
|
121
130
|
return (constraint_type == IndexConstraintType::UNIQUE || constraint_type == IndexConstraintType::PRIMARY);
|
|
122
131
|
}
|
|
123
|
-
//! Returns primary flag
|
|
132
|
+
//! Returns primary key flag
|
|
124
133
|
bool IsPrimary() {
|
|
125
134
|
return (constraint_type == IndexConstraintType::PRIMARY);
|
|
126
135
|
}
|
|
127
|
-
//! Returns foreign flag
|
|
136
|
+
//! Returns foreign key flag
|
|
128
137
|
bool IsForeign() {
|
|
129
138
|
return (constraint_type == IndexConstraintType::FOREIGN);
|
|
130
139
|
}
|
|
131
|
-
//! Serializes the index and returns the pair of block_id offset positions
|
|
132
|
-
virtual BlockPointer Serialize(duckdb::MetaBlockWriter &writer);
|
|
133
|
-
BlockPointer GetBlockPointer();
|
|
134
140
|
|
|
135
|
-
//!
|
|
141
|
+
//! Serializes the index and returns the pair of block_id offset positions
|
|
142
|
+
virtual BlockPointer Serialize(MetaBlockWriter &writer);
|
|
143
|
+
//! Returns the serialized data pointer to the block and offset of the serialized index
|
|
136
144
|
BlockPointer GetSerializedDataPointer() const {
|
|
137
145
|
return serialized_data_pointer;
|
|
138
146
|
}
|
|
139
147
|
|
|
140
|
-
|
|
148
|
+
//! Execute the index expressions on an input chunk
|
|
141
149
|
void ExecuteExpressions(DataChunk &input, DataChunk &result);
|
|
142
150
|
|
|
143
|
-
|
|
151
|
+
protected:
|
|
152
|
+
//! Lock used for any changes to the index
|
|
144
153
|
mutex lock;
|
|
145
|
-
|
|
146
|
-
//! Pointer to most recently checkpointed index data.
|
|
154
|
+
//! Pointer to serialized index data
|
|
147
155
|
BlockPointer serialized_data_pointer;
|
|
148
156
|
|
|
149
157
|
private:
|
|
150
|
-
//! Bound expressions used
|
|
158
|
+
//! Bound expressions used during expression execution
|
|
151
159
|
vector<unique_ptr<Expression>> bound_expressions;
|
|
152
|
-
//! Expression executor
|
|
160
|
+
//! Expression executor to execute the index expressions
|
|
153
161
|
ExpressionExecutor executor;
|
|
154
162
|
|
|
163
|
+
//! Bind the unbound expressions of the index
|
|
155
164
|
unique_ptr<Expression> BindExpression(unique_ptr<Expression> expr);
|
|
156
165
|
};
|
|
157
166
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
#include "duckdb/common/common.hpp"
|
|
12
12
|
#include "duckdb/common/enums/access_mode.hpp"
|
|
13
|
+
#include "duckdb/parser/tableref/table_function_ref.hpp"
|
|
13
14
|
|
|
14
15
|
namespace duckdb {
|
|
15
16
|
class AttachedDatabase;
|
|
@@ -27,11 +28,17 @@ typedef unique_ptr<Catalog> (*attach_function_t)(StorageExtensionInfo *storage_i
|
|
|
27
28
|
const string &name, AttachInfo &info, AccessMode access_mode);
|
|
28
29
|
typedef unique_ptr<TransactionManager> (*create_transaction_manager_t)(StorageExtensionInfo *storage_info,
|
|
29
30
|
AttachedDatabase &db, Catalog &catalog);
|
|
31
|
+
typedef unique_ptr<TableFunctionRef> (*create_database_t)(StorageExtensionInfo *info, ClientContext &context,
|
|
32
|
+
const string &database_name, const string &source_path);
|
|
33
|
+
typedef unique_ptr<TableFunctionRef> (*drop_database_t)(StorageExtensionInfo *storage_info, ClientContext &context,
|
|
34
|
+
const string &database_name);
|
|
30
35
|
|
|
31
36
|
class StorageExtension {
|
|
32
37
|
public:
|
|
33
38
|
attach_function_t attach;
|
|
34
39
|
create_transaction_manager_t create_transaction_manager;
|
|
40
|
+
create_database_t create_database;
|
|
41
|
+
drop_database_t drop_database;
|
|
35
42
|
|
|
36
43
|
//! Additional info passed to the various storage functions
|
|
37
44
|
shared_ptr<StorageExtensionInfo> storage_info;
|
|
@@ -23,6 +23,8 @@ struct UpdateNode;
|
|
|
23
23
|
class UpdateSegment {
|
|
24
24
|
public:
|
|
25
25
|
UpdateSegment(ColumnData &column_data);
|
|
26
|
+
// Construct a duplicate of 'other' with 'new_owner' as it's column data
|
|
27
|
+
UpdateSegment(UpdateSegment &other, ColumnData &new_owner);
|
|
26
28
|
~UpdateSegment();
|
|
27
29
|
|
|
28
30
|
ColumnData &column_data;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
#include "duckdb/catalog/catalog_entry/scalar_macro_catalog_entry.hpp"
|
|
16
16
|
#include "duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp"
|
|
17
17
|
#include "duckdb/catalog/catalog_entry/table_macro_catalog_entry.hpp"
|
|
18
|
+
#include "duckdb/catalog/catalog_entry/index_catalog_entry.hpp"
|
|
18
19
|
#include "duckdb/main/attached_database.hpp"
|
|
19
20
|
#include "duckdb/storage/storage_info.hpp"
|
|
20
21
|
|
|
@@ -77,6 +78,9 @@ protected:
|
|
|
77
78
|
void ReplayCreateTableMacro();
|
|
78
79
|
void ReplayDropTableMacro();
|
|
79
80
|
|
|
81
|
+
void ReplayCreateIndex();
|
|
82
|
+
void ReplayDropIndex();
|
|
83
|
+
|
|
80
84
|
void ReplayUseTable();
|
|
81
85
|
void ReplayInsert();
|
|
82
86
|
void ReplayDelete();
|
|
@@ -125,6 +129,9 @@ public:
|
|
|
125
129
|
void WriteCreateTableMacro(TableMacroCatalogEntry *entry);
|
|
126
130
|
void WriteDropTableMacro(TableMacroCatalogEntry *entry);
|
|
127
131
|
|
|
132
|
+
void WriteCreateIndex(IndexCatalogEntry *entry);
|
|
133
|
+
void WriteDropIndex(IndexCatalogEntry *entry);
|
|
134
|
+
|
|
128
135
|
void WriteCreateType(TypeCatalogEntry *entry);
|
|
129
136
|
void WriteDropType(TypeCatalogEntry *entry);
|
|
130
137
|
//! Sets the table used for subsequent insert/delete/update commands
|
|
@@ -665,6 +665,7 @@ unique_ptr<PendingQueryResult> ClientContext::PendingStatementOrPreparedStatemen
|
|
|
665
665
|
statement = std::move(copied_statement);
|
|
666
666
|
break;
|
|
667
667
|
}
|
|
668
|
+
#ifndef DUCKDB_ALTERNATIVE_VERIFY
|
|
668
669
|
case StatementType::COPY_STATEMENT:
|
|
669
670
|
case StatementType::INSERT_STATEMENT:
|
|
670
671
|
case StatementType::DELETE_STATEMENT:
|
|
@@ -685,6 +686,7 @@ unique_ptr<PendingQueryResult> ClientContext::PendingStatementOrPreparedStatemen
|
|
|
685
686
|
statement = std::move(parser.statements[0]);
|
|
686
687
|
break;
|
|
687
688
|
}
|
|
689
|
+
#endif
|
|
688
690
|
default:
|
|
689
691
|
statement = std::move(copied_statement);
|
|
690
692
|
break;
|
|
@@ -67,6 +67,7 @@ static ConfigurationOption internal_options[] = {DUCKDB_GLOBAL(AccessModeSetting
|
|
|
67
67
|
DUCKDB_LOCAL(EnableProgressBarPrintSetting),
|
|
68
68
|
DUCKDB_GLOBAL(ExperimentalParallelCSVSetting),
|
|
69
69
|
DUCKDB_LOCAL(ExplainOutputSetting),
|
|
70
|
+
DUCKDB_GLOBAL(ExtensionDirectorySetting),
|
|
70
71
|
DUCKDB_GLOBAL(ExternalThreadsSetting),
|
|
71
72
|
DUCKDB_LOCAL(FileSearchPathSetting),
|
|
72
73
|
DUCKDB_GLOBAL(ForceCompressionSetting),
|
|
@@ -144,9 +144,15 @@ unique_ptr<AttachedDatabase> DatabaseInstance::CreateAttachedDatabase(AttachInfo
|
|
|
144
144
|
if (entry == config.storage_extensions.end()) {
|
|
145
145
|
throw BinderException("Unrecognized storage type \"%s\"", type);
|
|
146
146
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
|
|
148
|
+
if (entry->second->attach != nullptr && entry->second->create_transaction_manager != nullptr) {
|
|
149
|
+
// use storage extension to create the initial database
|
|
150
|
+
attached_database = make_unique<AttachedDatabase>(*this, Catalog::GetSystemCatalog(*this), *entry->second,
|
|
151
|
+
info.name, info, access_mode);
|
|
152
|
+
} else {
|
|
153
|
+
attached_database = make_unique<AttachedDatabase>(*this, Catalog::GetSystemCatalog(*this), info.name,
|
|
154
|
+
info.path, access_mode);
|
|
155
|
+
}
|
|
150
156
|
} else {
|
|
151
157
|
// check if this is an in-memory database or not
|
|
152
158
|
attached_database =
|
|
@@ -200,6 +206,7 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf
|
|
|
200
206
|
AttachInfo info;
|
|
201
207
|
info.name = AttachedDatabase::ExtractDatabaseName(config.options.database_path);
|
|
202
208
|
info.path = config.options.database_path;
|
|
209
|
+
|
|
203
210
|
auto attached_database = CreateAttachedDatabase(info, database_type, config.options.access_mode);
|
|
204
211
|
auto initial_database = attached_database.get();
|
|
205
212
|
{
|
|
@@ -356,7 +363,8 @@ idx_t DuckDB::NumberOfThreads() {
|
|
|
356
363
|
}
|
|
357
364
|
|
|
358
365
|
bool DatabaseInstance::ExtensionIsLoaded(const std::string &name) {
|
|
359
|
-
|
|
366
|
+
auto extension_name = ExtensionHelper::GetExtensionName(name);
|
|
367
|
+
return loaded_extensions.find(extension_name) != loaded_extensions.end();
|
|
360
368
|
}
|
|
361
369
|
|
|
362
370
|
bool DuckDB::ExtensionIsLoaded(const std::string &name) {
|
|
@@ -364,7 +372,8 @@ bool DuckDB::ExtensionIsLoaded(const std::string &name) {
|
|
|
364
372
|
}
|
|
365
373
|
|
|
366
374
|
void DatabaseInstance::SetExtensionLoaded(const std::string &name) {
|
|
367
|
-
|
|
375
|
+
auto extension_name = ExtensionHelper::GetExtensionName(name);
|
|
376
|
+
loaded_extensions.insert(extension_name);
|
|
368
377
|
}
|
|
369
378
|
|
|
370
379
|
bool DatabaseInstance::TryGetCurrentSetting(const std::string &key, Value &result) {
|
|
@@ -24,8 +24,9 @@ ExtensionAlias ExtensionHelper::GetExtensionAlias(idx_t index) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
string ExtensionHelper::ApplyExtensionAlias(string extension_name) {
|
|
27
|
+
auto lname = StringUtil::Lower(extension_name);
|
|
27
28
|
for (idx_t index = 0; internal_aliases[index].alias; index++) {
|
|
28
|
-
if (
|
|
29
|
+
if (lname == internal_aliases[index].alias) {
|
|
29
30
|
return internal_aliases[index].extension;
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -40,20 +40,54 @@ const vector<string> ExtensionHelper::PathComponents() {
|
|
|
40
40
|
|
|
41
41
|
string ExtensionHelper::ExtensionDirectory(ClientContext &context) {
|
|
42
42
|
auto &fs = FileSystem::GetFileSystem(context);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
auto opener = FileSystem::GetFileOpener(context);
|
|
44
|
+
Value extension_directory_value;
|
|
45
|
+
string extension_directory;
|
|
46
|
+
|
|
47
|
+
if (context.TryGetCurrentSetting("extension_directory", extension_directory_value) &&
|
|
48
|
+
!extension_directory_value.IsNull() &&
|
|
49
|
+
!extension_directory_value.ToString().empty()) { // create the extension directory if not present
|
|
50
|
+
extension_directory = extension_directory_value.ToString();
|
|
51
|
+
// TODO this should probably live in the FileSystem
|
|
52
|
+
// convert random separators to platform-canonic
|
|
53
|
+
extension_directory = fs.ConvertSeparators(extension_directory);
|
|
54
|
+
// expand ~ in extension directory
|
|
55
|
+
extension_directory = fs.ExpandPath(extension_directory, opener);
|
|
56
|
+
if (!fs.DirectoryExists(extension_directory)) {
|
|
57
|
+
auto sep = fs.PathSeparator();
|
|
58
|
+
auto splits = StringUtil::Split(extension_directory, sep);
|
|
59
|
+
D_ASSERT(!splits.empty());
|
|
60
|
+
string extension_directory_prefix;
|
|
61
|
+
if (StringUtil::StartsWith(extension_directory, sep)) {
|
|
62
|
+
extension_directory_prefix = sep; // this is swallowed by Split otherwise
|
|
63
|
+
}
|
|
64
|
+
for (auto &split : splits) {
|
|
65
|
+
extension_directory_prefix = extension_directory_prefix + split + sep;
|
|
66
|
+
if (!fs.DirectoryExists(extension_directory_prefix)) {
|
|
67
|
+
fs.CreateDirectory(extension_directory_prefix);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
} else { // otherwise default to home
|
|
72
|
+
string home_directory = fs.GetHomeDirectory(opener);
|
|
73
|
+
// exception if the home directory does not exist, don't create whatever we think is home
|
|
74
|
+
if (!fs.DirectoryExists(home_directory)) {
|
|
75
|
+
throw IOException("Can't find the home directory at '%s'\nSpecify a home directory using the SET "
|
|
76
|
+
"home_directory='/path/to/dir' option.",
|
|
77
|
+
home_directory);
|
|
78
|
+
}
|
|
79
|
+
extension_directory = home_directory;
|
|
48
80
|
}
|
|
81
|
+
D_ASSERT(fs.DirectoryExists(extension_directory));
|
|
82
|
+
|
|
49
83
|
auto path_components = PathComponents();
|
|
50
84
|
for (auto &path_ele : path_components) {
|
|
51
|
-
|
|
52
|
-
if (!fs.DirectoryExists(
|
|
53
|
-
fs.CreateDirectory(
|
|
85
|
+
extension_directory = fs.JoinPath(extension_directory, path_ele);
|
|
86
|
+
if (!fs.DirectoryExists(extension_directory)) {
|
|
87
|
+
fs.CreateDirectory(extension_directory);
|
|
54
88
|
}
|
|
55
89
|
}
|
|
56
|
-
return
|
|
90
|
+
return extension_directory;
|
|
57
91
|
}
|
|
58
92
|
|
|
59
93
|
bool ExtensionHelper::CreateSuggestions(const string &extension_name, string &message) {
|
|
@@ -31,8 +31,14 @@ ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileOpener *o
|
|
|
31
31
|
auto filename = fs.ConvertSeparators(extension);
|
|
32
32
|
|
|
33
33
|
// shorthand case
|
|
34
|
-
if (!
|
|
35
|
-
string local_path =
|
|
34
|
+
if (!ExtensionHelper::IsFullPath(extension)) {
|
|
35
|
+
string local_path = !config.options.extension_directory.empty() ? config.options.extension_directory
|
|
36
|
+
: fs.GetHomeDirectory(opener);
|
|
37
|
+
|
|
38
|
+
// convert random separators to platform-canonic
|
|
39
|
+
local_path = fs.ConvertSeparators(local_path);
|
|
40
|
+
// expand ~ in extension directory
|
|
41
|
+
local_path = fs.ExpandPath(local_path, opener);
|
|
36
42
|
auto path_components = PathComponents();
|
|
37
43
|
for (auto &path_ele : path_components) {
|
|
38
44
|
local_path = fs.JoinPath(local_path, path_ele);
|
|
@@ -40,7 +46,6 @@ ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileOpener *o
|
|
|
40
46
|
string extension_name = ApplyExtensionAlias(extension);
|
|
41
47
|
filename = fs.JoinPath(local_path, extension_name + ".duckdb_extension");
|
|
42
48
|
}
|
|
43
|
-
|
|
44
49
|
if (!fs.FileExists(filename)) {
|
|
45
50
|
string message;
|
|
46
51
|
bool exact_match = ExtensionHelper::CreateSuggestions(extension, message);
|
|
@@ -121,9 +126,28 @@ ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileOpener *o
|
|
|
121
126
|
return res;
|
|
122
127
|
}
|
|
123
128
|
|
|
129
|
+
bool ExtensionHelper::IsFullPath(const string &extension) {
|
|
130
|
+
return StringUtil::Contains(extension, ".") || StringUtil::Contains(extension, "/") ||
|
|
131
|
+
StringUtil::Contains(extension, "\\");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
string ExtensionHelper::GetExtensionName(const string &extension) {
|
|
135
|
+
if (!IsFullPath(extension)) {
|
|
136
|
+
return extension;
|
|
137
|
+
}
|
|
138
|
+
auto splits = StringUtil::Split(StringUtil::Replace(extension, "\\", "/"), '/');
|
|
139
|
+
if (splits.empty()) {
|
|
140
|
+
return extension;
|
|
141
|
+
}
|
|
142
|
+
splits = StringUtil::Split(splits.back(), '.');
|
|
143
|
+
if (splits.empty()) {
|
|
144
|
+
return extension;
|
|
145
|
+
}
|
|
146
|
+
return StringUtil::Lower(splits.front());
|
|
147
|
+
}
|
|
148
|
+
|
|
124
149
|
void ExtensionHelper::LoadExternalExtension(DatabaseInstance &db, FileOpener *opener, const string &extension) {
|
|
125
|
-
|
|
126
|
-
if (loaded_extensions.find(extension) != loaded_extensions.end()) {
|
|
150
|
+
if (db.ExtensionIsLoaded(extension)) {
|
|
127
151
|
return;
|
|
128
152
|
}
|
|
129
153
|
|
|
@@ -531,6 +531,22 @@ Value ExplainOutputSetting::GetSetting(ClientContext &context) {
|
|
|
531
531
|
}
|
|
532
532
|
}
|
|
533
533
|
|
|
534
|
+
//===--------------------------------------------------------------------===//
|
|
535
|
+
// Extension Directory Setting
|
|
536
|
+
//===--------------------------------------------------------------------===//
|
|
537
|
+
void ExtensionDirectorySetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) {
|
|
538
|
+
auto new_directory = input.ToString();
|
|
539
|
+
config.options.extension_directory = input.ToString();
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
void ExtensionDirectorySetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) {
|
|
543
|
+
config.options.extension_directory = DBConfig().options.extension_directory;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
Value ExtensionDirectorySetting::GetSetting(ClientContext &context) {
|
|
547
|
+
return Value(DBConfig::GetConfig(context).options.extension_directory);
|
|
548
|
+
}
|
|
549
|
+
|
|
534
550
|
//===--------------------------------------------------------------------===//
|
|
535
551
|
// External Threads Setting
|
|
536
552
|
//===--------------------------------------------------------------------===//
|
|
@@ -83,12 +83,8 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq
|
|
|
83
83
|
*node_ptr = std::move(cross_product);
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
|
-
case JoinType::INNER:
|
|
87
|
-
|
|
88
|
-
case JoinType::RIGHT:
|
|
89
|
-
case JoinType::OUTER: {
|
|
90
|
-
// inner/left/right/full outer join, replace with cross product
|
|
91
|
-
// since the condition is always true, left/right/outer join are equivalent to inner join here
|
|
86
|
+
case JoinType::INNER: {
|
|
87
|
+
// inner, replace with cross product
|
|
92
88
|
auto cross_product =
|
|
93
89
|
LogicalCrossProduct::Create(std::move(join.children[0]), std::move(join.children[1]));
|
|
94
90
|
*node_ptr = std::move(cross_product);
|
|
@@ -114,52 +114,6 @@ OperatorResultType PipelineExecutor::ExecutePushInternal(DataChunk &input, idx_t
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
// Pull a single DataChunk from the pipeline by flushing any operators holding cached output
|
|
118
|
-
void PipelineExecutor::FlushCachingOperatorsPull(DataChunk &result) {
|
|
119
|
-
idx_t start_idx = IsFinished() ? idx_t(finished_processing_idx) : 0;
|
|
120
|
-
idx_t op_idx = start_idx;
|
|
121
|
-
while (op_idx < pipeline.operators.size()) {
|
|
122
|
-
if (!pipeline.operators[op_idx]->RequiresFinalExecute()) {
|
|
123
|
-
op_idx++;
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
OperatorFinalizeResultType finalize_result;
|
|
128
|
-
DataChunk &curr_chunk =
|
|
129
|
-
op_idx + 1 >= intermediate_chunks.size() ? final_chunk : *intermediate_chunks[op_idx + 1];
|
|
130
|
-
|
|
131
|
-
if (pending_final_execute) {
|
|
132
|
-
// Still have a cached chunk from a last pull, reuse chunk
|
|
133
|
-
finalize_result = cached_final_execute_result;
|
|
134
|
-
} else {
|
|
135
|
-
// Flush the current operator
|
|
136
|
-
auto current_operator = pipeline.operators[op_idx];
|
|
137
|
-
StartOperator(current_operator);
|
|
138
|
-
finalize_result = current_operator->FinalExecute(context, curr_chunk, *current_operator->op_state,
|
|
139
|
-
*intermediate_states[op_idx]);
|
|
140
|
-
EndOperator(current_operator, &curr_chunk);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
auto execute_result = Execute(curr_chunk, result, op_idx + 1);
|
|
144
|
-
|
|
145
|
-
if (execute_result == OperatorResultType::HAVE_MORE_OUTPUT) {
|
|
146
|
-
pending_final_execute = true;
|
|
147
|
-
cached_final_execute_result = finalize_result;
|
|
148
|
-
} else {
|
|
149
|
-
pending_final_execute = false;
|
|
150
|
-
if (finalize_result == OperatorFinalizeResultType::FINISHED) {
|
|
151
|
-
FinishProcessing(op_idx);
|
|
152
|
-
op_idx++;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Some non-empty result was pulled from some caching operator, we're done for this pull
|
|
157
|
-
if (result.size() > 0) {
|
|
158
|
-
break;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
117
|
// Push all remaining cached operator output through the pipeline
|
|
164
118
|
void PipelineExecutor::FlushCachingOperatorsPush() {
|
|
165
119
|
idx_t start_idx = IsFinished() ? idx_t(finished_processing_idx) : 0;
|
|
@@ -223,21 +177,13 @@ void PipelineExecutor::ExecutePull(DataChunk &result) {
|
|
|
223
177
|
D_ASSERT(!pipeline.sink);
|
|
224
178
|
auto &source_chunk = pipeline.operators.empty() ? result : *intermediate_chunks[0];
|
|
225
179
|
while (result.size() == 0) {
|
|
226
|
-
if (source_empty) {
|
|
227
|
-
FlushCachingOperatorsPull(result);
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
180
|
if (in_process_operators.empty()) {
|
|
232
181
|
source_chunk.Reset();
|
|
233
182
|
FetchFromSource(source_chunk);
|
|
234
|
-
|
|
235
183
|
if (source_chunk.size() == 0) {
|
|
236
|
-
|
|
237
|
-
continue;
|
|
184
|
+
break;
|
|
238
185
|
}
|
|
239
186
|
}
|
|
240
|
-
|
|
241
187
|
if (!pipeline.operators.empty()) {
|
|
242
188
|
auto state = Execute(source_chunk, result);
|
|
243
189
|
if (state == OperatorResultType::FINISHED) {
|
|
@@ -16,6 +16,9 @@ unique_ptr<CreateInfo> CreateIndexInfo::Copy() const {
|
|
|
16
16
|
for (auto &expr : expressions) {
|
|
17
17
|
result->expressions.push_back(expr->Copy());
|
|
18
18
|
}
|
|
19
|
+
for (auto &expr : parsed_expressions) {
|
|
20
|
+
result->parsed_expressions.push_back(expr->Copy());
|
|
21
|
+
}
|
|
19
22
|
|
|
20
23
|
result->scan_types = scan_types;
|
|
21
24
|
result->names = names;
|
|
@@ -11,16 +11,6 @@ CopyStatement::CopyStatement(const CopyStatement &other) : SQLStatement(other),
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
string ConvertOptionValueToString(const Value &val) {
|
|
15
|
-
auto type = val.type().id();
|
|
16
|
-
switch (type) {
|
|
17
|
-
case LogicalTypeId::VARCHAR:
|
|
18
|
-
return KeywordHelper::WriteOptionallyQuoted(val.ToString());
|
|
19
|
-
default:
|
|
20
|
-
return val.ToString();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
14
|
string CopyStatement::CopyOptionsToString(const string &format,
|
|
25
15
|
const case_insensitive_map_t<vector<Value>> &options) const {
|
|
26
16
|
if (format.empty() && options.empty()) {
|
|
@@ -45,15 +35,14 @@ string CopyStatement::CopyOptionsToString(const string &format,
|
|
|
45
35
|
// Options like HEADER don't need an explicit value
|
|
46
36
|
// just providing the name already sets it to true
|
|
47
37
|
} else if (values.size() == 1) {
|
|
48
|
-
result +=
|
|
38
|
+
result += values[0].ToSQLString();
|
|
49
39
|
} else {
|
|
50
40
|
result += "( ";
|
|
51
41
|
for (idx_t i = 0; i < values.size(); i++) {
|
|
52
|
-
auto &value = values[i];
|
|
53
42
|
if (i) {
|
|
54
43
|
result += ", ";
|
|
55
44
|
}
|
|
56
|
-
result +=
|
|
45
|
+
result += values[i].ToSQLString();
|
|
57
46
|
}
|
|
58
47
|
result += " )";
|
|
59
48
|
}
|