duckdb 0.5.2-dev250.0 → 0.5.2-dev266.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.cpp +185 -24
- package/src/duckdb.hpp +54 -2
- package/src/parquet-amalgamation.cpp +25733 -25733
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -66611,6 +66611,13 @@ struct DefaultExtension {
|
|
|
66611
66611
|
bool statically_loaded;
|
|
66612
66612
|
};
|
|
66613
66613
|
|
|
66614
|
+
struct ExtensionInitResult {
|
|
66615
|
+
string filename;
|
|
66616
|
+
string basename;
|
|
66617
|
+
|
|
66618
|
+
void *lib_hdl;
|
|
66619
|
+
};
|
|
66620
|
+
|
|
66614
66621
|
class ExtensionHelper {
|
|
66615
66622
|
public:
|
|
66616
66623
|
static void LoadAllExtensions(DuckDB &db);
|
|
@@ -66627,8 +66634,13 @@ public:
|
|
|
66627
66634
|
|
|
66628
66635
|
static const vector<string> GetPublicKeys();
|
|
66629
66636
|
|
|
66637
|
+
static unique_ptr<ReplacementOpenData> ReplacementOpenPre(const string &extension, DBConfig &config);
|
|
66638
|
+
static void ReplacementOpenPost(ClientContext &context, const string &extension, DatabaseInstance &instance,
|
|
66639
|
+
ReplacementOpenData *open_data);
|
|
66640
|
+
|
|
66630
66641
|
private:
|
|
66631
66642
|
static const vector<string> PathComponents();
|
|
66643
|
+
static ExtensionInitResult InitialLoad(DBConfig &context, FileOpener *opener, const string &extension);
|
|
66632
66644
|
//! For tagged releases we use the tag, else we use the git commit hash
|
|
66633
66645
|
static const string GetVersionDirectoryName();
|
|
66634
66646
|
//! Version tags occur with and without 'v', tag in extension path is always with 'v'
|
|
@@ -129389,6 +129401,27 @@ bool Connection::HasActiveTransaction() {
|
|
|
129389
129401
|
|
|
129390
129402
|
|
|
129391
129403
|
|
|
129404
|
+
//===----------------------------------------------------------------------===//
|
|
129405
|
+
// DuckDB
|
|
129406
|
+
//
|
|
129407
|
+
// duckdb/main/extension_helper.hpp
|
|
129408
|
+
//
|
|
129409
|
+
//
|
|
129410
|
+
//===----------------------------------------------------------------------===//
|
|
129411
|
+
|
|
129412
|
+
|
|
129413
|
+
|
|
129414
|
+
|
|
129415
|
+
|
|
129416
|
+
namespace duckdb {
|
|
129417
|
+
|
|
129418
|
+
class ExtensionPrefixReplacementOpen : public ReplacementOpen {
|
|
129419
|
+
public:
|
|
129420
|
+
ExtensionPrefixReplacementOpen();
|
|
129421
|
+
};
|
|
129422
|
+
|
|
129423
|
+
} // namespace duckdb
|
|
129424
|
+
|
|
129392
129425
|
|
|
129393
129426
|
|
|
129394
129427
|
#ifndef DUCKDB_NO_THREADS
|
|
@@ -129399,6 +129432,7 @@ namespace duckdb {
|
|
|
129399
129432
|
|
|
129400
129433
|
DBConfig::DBConfig() {
|
|
129401
129434
|
compression_functions = make_unique<CompressionFunctionSet>();
|
|
129435
|
+
replacement_opens.push_back(ExtensionPrefixReplacementOpen());
|
|
129402
129436
|
cast_functions = make_unique<CastFunctionSet>();
|
|
129403
129437
|
}
|
|
129404
129438
|
|
|
@@ -129488,30 +129522,47 @@ ConnectionManager &ConnectionManager::Get(ClientContext &context) {
|
|
|
129488
129522
|
return ConnectionManager::Get(DatabaseInstance::GetDatabase(context));
|
|
129489
129523
|
}
|
|
129490
129524
|
|
|
129491
|
-
void DatabaseInstance::Initialize(const char *
|
|
129492
|
-
|
|
129493
|
-
|
|
129494
|
-
|
|
129495
|
-
|
|
129496
|
-
// default configuration
|
|
129497
|
-
DBConfig config;
|
|
129498
|
-
Configure(config);
|
|
129525
|
+
void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_config) {
|
|
129526
|
+
DBConfig default_config;
|
|
129527
|
+
DBConfig *config_ptr = &default_config;
|
|
129528
|
+
if (user_config) {
|
|
129529
|
+
config_ptr = user_config;
|
|
129499
129530
|
}
|
|
129500
|
-
|
|
129531
|
+
|
|
129532
|
+
if (config_ptr->options.temporary_directory.empty() && database_path) {
|
|
129501
129533
|
// no directory specified: use default temp path
|
|
129502
|
-
|
|
129534
|
+
config_ptr->options.temporary_directory = string(database_path) + ".tmp";
|
|
129503
129535
|
|
|
129504
129536
|
// special treatment for in-memory mode
|
|
129505
|
-
if (strcmp(
|
|
129506
|
-
|
|
129537
|
+
if (strcmp(database_path, ":memory:") == 0) {
|
|
129538
|
+
config_ptr->options.temporary_directory = ".tmp";
|
|
129507
129539
|
}
|
|
129508
129540
|
}
|
|
129509
|
-
|
|
129541
|
+
|
|
129542
|
+
if (database_path) {
|
|
129543
|
+
config_ptr->options.database_path = database_path;
|
|
129544
|
+
} else {
|
|
129545
|
+
config_ptr->options.database_path.clear();
|
|
129546
|
+
}
|
|
129547
|
+
|
|
129548
|
+
for (auto &open : config_ptr->replacement_opens) {
|
|
129549
|
+
if (open.pre_func) {
|
|
129550
|
+
open.data = open.pre_func(*config_ptr, open.static_data.get());
|
|
129551
|
+
if (open.data) {
|
|
129552
|
+
break;
|
|
129553
|
+
}
|
|
129554
|
+
}
|
|
129555
|
+
}
|
|
129556
|
+
Configure(*config_ptr);
|
|
129557
|
+
|
|
129558
|
+
if (user_config && !user_config->options.use_temporary_directory) {
|
|
129510
129559
|
// temporary directories explicitly disabled
|
|
129511
129560
|
config.options.temporary_directory = string();
|
|
129512
129561
|
}
|
|
129513
129562
|
|
|
129514
|
-
|
|
129563
|
+
// config.create_storage_manager(config.options.database_path,
|
|
129564
|
+
// config.options.access_mode == AccessMode::READ_ONLY);
|
|
129565
|
+
storage = make_unique<StorageManager>(*this, config.options.database_path,
|
|
129515
129566
|
config.options.access_mode == AccessMode::READ_ONLY);
|
|
129516
129567
|
catalog = make_unique<Catalog>(*this);
|
|
129517
129568
|
transaction_manager = make_unique<TransactionManager>(*this);
|
|
@@ -129524,6 +129575,13 @@ void DatabaseInstance::Initialize(const char *path, DBConfig *new_config) {
|
|
|
129524
129575
|
|
|
129525
129576
|
// only increase thread count after storage init because we get races on catalog otherwise
|
|
129526
129577
|
scheduler->SetThreads(config.options.maximum_threads);
|
|
129578
|
+
|
|
129579
|
+
for (auto &open : config.replacement_opens) {
|
|
129580
|
+
if (open.post_func && open.data) {
|
|
129581
|
+
open.post_func(*this, open.data.get());
|
|
129582
|
+
break;
|
|
129583
|
+
}
|
|
129584
|
+
}
|
|
129527
129585
|
}
|
|
129528
129586
|
|
|
129529
129587
|
DuckDB::DuckDB(const char *path, DBConfig *new_config) : instance(make_shared<DatabaseInstance>()) {
|
|
@@ -129583,6 +129641,7 @@ Allocator &Allocator::Get(DatabaseInstance &db) {
|
|
|
129583
129641
|
}
|
|
129584
129642
|
|
|
129585
129643
|
void DatabaseInstance::Configure(DBConfig &new_config) {
|
|
129644
|
+
config.options.database_path = new_config.options.database_path;
|
|
129586
129645
|
config.options.access_mode = AccessMode::READ_WRITE;
|
|
129587
129646
|
if (new_config.options.access_mode != AccessMode::UNDEFINED) {
|
|
129588
129647
|
config.options.access_mode = new_config.options.access_mode;
|
|
@@ -129624,6 +129683,7 @@ void DatabaseInstance::Configure(DBConfig &new_config) {
|
|
|
129624
129683
|
config.options.enable_external_access = new_config.options.enable_external_access;
|
|
129625
129684
|
config.options.allow_unsigned_extensions = new_config.options.allow_unsigned_extensions;
|
|
129626
129685
|
config.replacement_scans = move(new_config.replacement_scans);
|
|
129686
|
+
config.replacement_opens = move(new_config.replacement_opens); // TODO is this okay?
|
|
129627
129687
|
config.options.initialize_default_database = new_config.options.initialize_default_database;
|
|
129628
129688
|
config.options.disabled_optimizers = move(new_config.options.disabled_optimizers);
|
|
129629
129689
|
config.parser_extensions = move(new_config.parser_extensions);
|
|
@@ -138575,6 +138635,8 @@ public:
|
|
|
138575
138635
|
// LICENSE_CHANGE_END
|
|
138576
138636
|
|
|
138577
138637
|
|
|
138638
|
+
|
|
138639
|
+
|
|
138578
138640
|
namespace duckdb {
|
|
138579
138641
|
|
|
138580
138642
|
//===--------------------------------------------------------------------===//
|
|
@@ -138592,18 +138654,17 @@ static T LoadFunctionFromDLL(void *dll, const string &function_name, const strin
|
|
|
138592
138654
|
return (T)function;
|
|
138593
138655
|
}
|
|
138594
138656
|
|
|
138595
|
-
|
|
138596
|
-
auto &db = DatabaseInstance::GetDatabase(context);
|
|
138597
|
-
auto &config = DBConfig::GetConfig(context);
|
|
138657
|
+
ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileOpener *opener, const string &extension) {
|
|
138598
138658
|
if (!config.options.enable_external_access) {
|
|
138599
138659
|
throw PermissionException("Loading external extensions is disabled through configuration");
|
|
138600
138660
|
}
|
|
138601
|
-
|
|
138661
|
+
VirtualFileSystem fallback_file_system; // config may not contain one yet
|
|
138662
|
+
auto &fs = config.file_system ? *config.file_system : fallback_file_system;
|
|
138602
138663
|
auto filename = fs.ConvertSeparators(extension);
|
|
138603
138664
|
|
|
138604
138665
|
// shorthand case
|
|
138605
138666
|
if (!StringUtil::Contains(extension, ".") && !StringUtil::Contains(extension, fs.PathSeparator())) {
|
|
138606
|
-
string local_path = fs.GetHomeDirectory(
|
|
138667
|
+
string local_path = fs.GetHomeDirectory(opener);
|
|
138607
138668
|
auto path_components = PathComponents();
|
|
138608
138669
|
for (auto &path_ele : path_components) {
|
|
138609
138670
|
local_path = fs.JoinPath(local_path, path_ele);
|
|
@@ -138653,13 +138714,10 @@ void ExtensionHelper::LoadExternalExtension(ClientContext &context, const string
|
|
|
138653
138714
|
}
|
|
138654
138715
|
|
|
138655
138716
|
auto basename = fs.ExtractBaseName(filename);
|
|
138656
|
-
auto init_fun_name = basename + "_init";
|
|
138657
|
-
auto version_fun_name = basename + "_version";
|
|
138658
138717
|
|
|
138659
|
-
ext_init_fun_t init_fun;
|
|
138660
138718
|
ext_version_fun_t version_fun;
|
|
138719
|
+
auto version_fun_name = basename + "_version";
|
|
138661
138720
|
|
|
138662
|
-
init_fun = LoadFunctionFromDLL<ext_init_fun_t>(lib_hdl, init_fun_name, filename);
|
|
138663
138721
|
version_fun = LoadFunctionFromDLL<ext_version_fun_t>(lib_hdl, version_fun_name, filename);
|
|
138664
138722
|
|
|
138665
138723
|
std::string engine_version = std::string(DuckDB::LibraryVersion());
|
|
@@ -138685,11 +138743,59 @@ void ExtensionHelper::LoadExternalExtension(ClientContext &context, const string
|
|
|
138685
138743
|
extension_version, engine_version);
|
|
138686
138744
|
}
|
|
138687
138745
|
|
|
138746
|
+
ExtensionInitResult res;
|
|
138747
|
+
res.basename = basename;
|
|
138748
|
+
res.filename = filename;
|
|
138749
|
+
res.lib_hdl = lib_hdl;
|
|
138750
|
+
return res;
|
|
138751
|
+
}
|
|
138752
|
+
|
|
138753
|
+
void ExtensionHelper::LoadExternalExtension(ClientContext &context, const string &extension) {
|
|
138754
|
+
auto &db = DatabaseInstance::GetDatabase(context);
|
|
138755
|
+
|
|
138756
|
+
auto res = InitialLoad(DBConfig::GetConfig(context), FileSystem::GetFileOpener(context), extension);
|
|
138757
|
+
auto init_fun_name = res.basename + "_init";
|
|
138758
|
+
|
|
138759
|
+
ext_init_fun_t init_fun;
|
|
138760
|
+
init_fun = LoadFunctionFromDLL<ext_init_fun_t>(res.lib_hdl, init_fun_name, res.filename);
|
|
138761
|
+
|
|
138688
138762
|
try {
|
|
138689
138763
|
(*init_fun)(db);
|
|
138690
138764
|
} catch (std::exception &e) {
|
|
138691
138765
|
throw InvalidInputException("Initialization function \"%s\" from file \"%s\" threw an exception: \"%s\"",
|
|
138692
|
-
init_fun_name, filename, e.what());
|
|
138766
|
+
init_fun_name, res.filename, e.what());
|
|
138767
|
+
}
|
|
138768
|
+
}
|
|
138769
|
+
|
|
138770
|
+
unique_ptr<ReplacementOpenData> ExtensionHelper::ReplacementOpenPre(const string &extension, DBConfig &config) {
|
|
138771
|
+
|
|
138772
|
+
auto res = InitialLoad(config, nullptr, extension); // TODO opener
|
|
138773
|
+
auto init_fun_name = res.basename + "_replacement_open_pre";
|
|
138774
|
+
|
|
138775
|
+
replacement_open_pre_t open_pre_fun;
|
|
138776
|
+
open_pre_fun = LoadFunctionFromDLL<replacement_open_pre_t>(res.lib_hdl, init_fun_name, res.filename);
|
|
138777
|
+
|
|
138778
|
+
try {
|
|
138779
|
+
return (*open_pre_fun)(config, nullptr);
|
|
138780
|
+
} catch (std::exception &e) {
|
|
138781
|
+
throw InvalidInputException("Initialization function \"%s\" from file \"%s\" threw an exception: \"%s\"",
|
|
138782
|
+
init_fun_name, res.filename, e.what());
|
|
138783
|
+
}
|
|
138784
|
+
}
|
|
138785
|
+
|
|
138786
|
+
void ExtensionHelper::ReplacementOpenPost(ClientContext &context, const string &extension, DatabaseInstance &instance,
|
|
138787
|
+
ReplacementOpenData *open_data) {
|
|
138788
|
+
auto res = InitialLoad(DBConfig::GetConfig(context), FileSystem::GetFileOpener(context), extension);
|
|
138789
|
+
auto init_fun_name = res.basename + "_replacement_open_post";
|
|
138790
|
+
|
|
138791
|
+
replacement_open_post_t open_post_fun;
|
|
138792
|
+
open_post_fun = LoadFunctionFromDLL<replacement_open_post_t>(res.lib_hdl, init_fun_name, res.filename);
|
|
138793
|
+
|
|
138794
|
+
try {
|
|
138795
|
+
(*open_post_fun)(instance, open_data);
|
|
138796
|
+
} catch (std::exception &e) {
|
|
138797
|
+
throw InvalidInputException("Initialization function \"%s\" from file \"%s\" threw an exception: \"%s\"",
|
|
138798
|
+
init_fun_name, res.filename, e.what());
|
|
138693
138799
|
}
|
|
138694
138800
|
}
|
|
138695
138801
|
|
|
@@ -138706,6 +138812,61 @@ Extension::~Extension() {
|
|
|
138706
138812
|
|
|
138707
138813
|
|
|
138708
138814
|
|
|
138815
|
+
|
|
138816
|
+
namespace duckdb {
|
|
138817
|
+
|
|
138818
|
+
struct ExtensionPrefixOpenData : public ReplacementOpenData {
|
|
138819
|
+
ExtensionPrefixOpenData(string extension, string path, unique_ptr<ReplacementOpenData> data)
|
|
138820
|
+
: extension(move(extension)), path(move(path)), data(move(data)) {
|
|
138821
|
+
}
|
|
138822
|
+
string extension;
|
|
138823
|
+
string path;
|
|
138824
|
+
unique_ptr<ReplacementOpenData> data;
|
|
138825
|
+
};
|
|
138826
|
+
|
|
138827
|
+
static unique_ptr<ReplacementOpenData> ExtensionPrefixPreOpen(DBConfig &config, ReplacementOpenStaticData *) {
|
|
138828
|
+
auto path = config.options.database_path;
|
|
138829
|
+
auto first_colon = path.find(':');
|
|
138830
|
+
if (first_colon == string::npos || first_colon < 2) { // needs to be at least two characters because windows c: ...
|
|
138831
|
+
return nullptr;
|
|
138832
|
+
}
|
|
138833
|
+
auto extension = path.substr(0, first_colon);
|
|
138834
|
+
D_ASSERT(extension.size() > 1);
|
|
138835
|
+
// needs to be alphanumeric
|
|
138836
|
+
for (auto &ch : extension) {
|
|
138837
|
+
if (!isalnum(ch) && ch != '_') {
|
|
138838
|
+
return nullptr;
|
|
138839
|
+
}
|
|
138840
|
+
}
|
|
138841
|
+
auto extension_data = ExtensionHelper::ReplacementOpenPre(extension, config);
|
|
138842
|
+
if (extension_data) {
|
|
138843
|
+
return make_unique<ExtensionPrefixOpenData>(extension, path, move(extension_data));
|
|
138844
|
+
}
|
|
138845
|
+
return nullptr;
|
|
138846
|
+
}
|
|
138847
|
+
|
|
138848
|
+
static void ExtensionPrefixPostOpen(DatabaseInstance &instance, ReplacementOpenData *open_data) {
|
|
138849
|
+
if (!open_data) {
|
|
138850
|
+
return;
|
|
138851
|
+
}
|
|
138852
|
+
D_ASSERT(open_data);
|
|
138853
|
+
auto prefix_open_data = (ExtensionPrefixOpenData *)open_data;
|
|
138854
|
+
|
|
138855
|
+
Connection con(instance);
|
|
138856
|
+
ExtensionHelper::LoadExternalExtension(*con.context, prefix_open_data->extension);
|
|
138857
|
+
ExtensionHelper::ReplacementOpenPost(*con.context, prefix_open_data->extension, instance,
|
|
138858
|
+
prefix_open_data->data.get());
|
|
138859
|
+
}
|
|
138860
|
+
|
|
138861
|
+
ExtensionPrefixReplacementOpen::ExtensionPrefixReplacementOpen()
|
|
138862
|
+
: ReplacementOpen(ExtensionPrefixPreOpen, ExtensionPrefixPostOpen) {
|
|
138863
|
+
}
|
|
138864
|
+
|
|
138865
|
+
} // namespace duckdb
|
|
138866
|
+
|
|
138867
|
+
|
|
138868
|
+
|
|
138869
|
+
|
|
138709
138870
|
namespace duckdb {
|
|
138710
138871
|
|
|
138711
138872
|
MaterializedQueryResult::MaterializedQueryResult(StatementType statement_type, StatementProperties properties,
|
package/src/duckdb.hpp
CHANGED
|
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
13
|
#define DUCKDB_AMALGAMATION_EXTENDED 1
|
|
14
|
-
#define DUCKDB_SOURCE_ID "
|
|
15
|
-
#define DUCKDB_VERSION "v0.5.2-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "5748a740d"
|
|
15
|
+
#define DUCKDB_VERSION "v0.5.2-dev266"
|
|
16
16
|
//===----------------------------------------------------------------------===//
|
|
17
17
|
// DuckDB
|
|
18
18
|
//
|
|
@@ -23916,6 +23916,52 @@ struct ReplacementScan {
|
|
|
23916
23916
|
|
|
23917
23917
|
} // namespace duckdb
|
|
23918
23918
|
|
|
23919
|
+
//===----------------------------------------------------------------------===//
|
|
23920
|
+
// DuckDB
|
|
23921
|
+
//
|
|
23922
|
+
// duckdb/function/replacement_scan.hpp
|
|
23923
|
+
//
|
|
23924
|
+
//
|
|
23925
|
+
//===----------------------------------------------------------------------===//
|
|
23926
|
+
|
|
23927
|
+
|
|
23928
|
+
|
|
23929
|
+
|
|
23930
|
+
|
|
23931
|
+
namespace duckdb {
|
|
23932
|
+
|
|
23933
|
+
class DatabaseInstance;
|
|
23934
|
+
struct DBConfig;
|
|
23935
|
+
|
|
23936
|
+
struct ReplacementOpenData {
|
|
23937
|
+
virtual ~ReplacementOpenData() {
|
|
23938
|
+
}
|
|
23939
|
+
};
|
|
23940
|
+
|
|
23941
|
+
struct ReplacementOpenStaticData {
|
|
23942
|
+
virtual ~ReplacementOpenStaticData() {
|
|
23943
|
+
}
|
|
23944
|
+
};
|
|
23945
|
+
|
|
23946
|
+
typedef unique_ptr<ReplacementOpenData> (*replacement_open_pre_t)(DBConfig &config,
|
|
23947
|
+
ReplacementOpenStaticData *static_data);
|
|
23948
|
+
typedef void (*replacement_open_post_t)(DatabaseInstance &instance, ReplacementOpenData *open_data);
|
|
23949
|
+
|
|
23950
|
+
struct ReplacementOpen {
|
|
23951
|
+
explicit ReplacementOpen(replacement_open_pre_t pre_func, replacement_open_post_t post_func)
|
|
23952
|
+
: pre_func(pre_func), post_func(post_func), data(nullptr) {
|
|
23953
|
+
}
|
|
23954
|
+
|
|
23955
|
+
replacement_open_pre_t pre_func;
|
|
23956
|
+
replacement_open_post_t post_func;
|
|
23957
|
+
|
|
23958
|
+
unique_ptr<ReplacementOpenData> data;
|
|
23959
|
+
|
|
23960
|
+
shared_ptr<ReplacementOpenStaticData> static_data;
|
|
23961
|
+
};
|
|
23962
|
+
|
|
23963
|
+
} // namespace duckdb
|
|
23964
|
+
|
|
23919
23965
|
|
|
23920
23966
|
|
|
23921
23967
|
//===----------------------------------------------------------------------===//
|
|
@@ -24180,6 +24226,8 @@ struct ExtensionOption {
|
|
|
24180
24226
|
};
|
|
24181
24227
|
|
|
24182
24228
|
struct DBConfigOptions {
|
|
24229
|
+
//! Database file path. May be empty for in-memory mode
|
|
24230
|
+
string database_path;
|
|
24183
24231
|
//! Access mode of the database (AUTOMATIC, READ_ONLY or READ_WRITE)
|
|
24184
24232
|
AccessMode access_mode = AccessMode::AUTOMATIC;
|
|
24185
24233
|
//! Checkpoint when WAL reaches this size (default: 16MB)
|
|
@@ -24243,6 +24291,10 @@ public:
|
|
|
24243
24291
|
|
|
24244
24292
|
//! Replacement table scans are automatically attempted when a table name cannot be found in the schema
|
|
24245
24293
|
vector<ReplacementScan> replacement_scans;
|
|
24294
|
+
|
|
24295
|
+
//! Replacement open handlers are callbacks that run pre and post database initialization
|
|
24296
|
+
vector<ReplacementOpen> replacement_opens;
|
|
24297
|
+
|
|
24246
24298
|
//! Extra parameters that can be SET for loaded extensions
|
|
24247
24299
|
case_insensitive_map_t<ExtensionOption> extension_parameters;
|
|
24248
24300
|
//! The FileSystem to use, can be overwritten to allow for injecting custom file systems for testing purposes (e.g.
|