duckdb 0.2.10-dev451.0 → 0.2.10-dev468.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 +327 -90
- package/src/duckdb.hpp +227 -186
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -1760,7 +1760,7 @@ public:
|
|
|
1760
1760
|
namespace duckdb {
|
|
1761
1761
|
|
|
1762
1762
|
struct CreateMacroInfo : public CreateFunctionInfo {
|
|
1763
|
-
CreateMacroInfo() : CreateFunctionInfo(CatalogType::MACRO_ENTRY) {
|
|
1763
|
+
CreateMacroInfo() : CreateFunctionInfo(CatalogType::MACRO_ENTRY, INVALID_SCHEMA) {
|
|
1764
1764
|
}
|
|
1765
1765
|
|
|
1766
1766
|
unique_ptr<MacroFunction> function;
|
|
@@ -2025,8 +2025,8 @@ namespace duckdb {
|
|
|
2025
2025
|
|
|
2026
2026
|
struct CreateSequenceInfo : public CreateInfo {
|
|
2027
2027
|
CreateSequenceInfo()
|
|
2028
|
-
: CreateInfo(CatalogType::SEQUENCE_ENTRY), name(string()), usage_count(0), increment(1),
|
|
2029
|
-
max_value(NumericLimits<int64_t>::Maximum()), start_value(1), cycle(false) {
|
|
2028
|
+
: CreateInfo(CatalogType::SEQUENCE_ENTRY, INVALID_SCHEMA), name(string()), usage_count(0), increment(1),
|
|
2029
|
+
min_value(1), max_value(NumericLimits<int64_t>::Maximum()), start_value(1), cycle(false) {
|
|
2030
2030
|
}
|
|
2031
2031
|
|
|
2032
2032
|
//! Sequence name to create
|
|
@@ -2049,6 +2049,7 @@ public:
|
|
|
2049
2049
|
auto result = make_unique<CreateSequenceInfo>();
|
|
2050
2050
|
CopyProperties(*result);
|
|
2051
2051
|
result->name = name;
|
|
2052
|
+
result->schema = schema;
|
|
2052
2053
|
result->usage_count = usage_count;
|
|
2053
2054
|
result->increment = increment;
|
|
2054
2055
|
result->min_value = min_value;
|
|
@@ -2290,6 +2291,44 @@ private:
|
|
|
2290
2291
|
} // namespace duckdb
|
|
2291
2292
|
|
|
2292
2293
|
|
|
2294
|
+
//===----------------------------------------------------------------------===//
|
|
2295
|
+
// DuckDB
|
|
2296
|
+
//
|
|
2297
|
+
// duckdb/catalog/catalog_search_path.hpp
|
|
2298
|
+
//
|
|
2299
|
+
//
|
|
2300
|
+
//===----------------------------------------------------------------------===//
|
|
2301
|
+
|
|
2302
|
+
|
|
2303
|
+
|
|
2304
|
+
#include <functional>
|
|
2305
|
+
|
|
2306
|
+
|
|
2307
|
+
|
|
2308
|
+
|
|
2309
|
+
|
|
2310
|
+
namespace duckdb {
|
|
2311
|
+
|
|
2312
|
+
class ClientContext;
|
|
2313
|
+
|
|
2314
|
+
//! The schema search path, in order by which entries are searched if no schema entry is provided
|
|
2315
|
+
class CatalogSearchPath {
|
|
2316
|
+
public:
|
|
2317
|
+
explicit CatalogSearchPath(ClientContext &client_p);
|
|
2318
|
+
CatalogSearchPath(const CatalogSearchPath &other) = delete;
|
|
2319
|
+
|
|
2320
|
+
const vector<string> &Get();
|
|
2321
|
+
const string &GetDefault();
|
|
2322
|
+
|
|
2323
|
+
private:
|
|
2324
|
+
static vector<string> ParsePaths(const string &value);
|
|
2325
|
+
ClientContext &context;
|
|
2326
|
+
string last_value;
|
|
2327
|
+
vector<string> paths;
|
|
2328
|
+
};
|
|
2329
|
+
|
|
2330
|
+
} // namespace duckdb
|
|
2331
|
+
|
|
2293
2332
|
|
|
2294
2333
|
|
|
2295
2334
|
//===----------------------------------------------------------------------===//
|
|
@@ -2678,7 +2717,7 @@ public:
|
|
|
2678
2717
|
namespace duckdb {
|
|
2679
2718
|
|
|
2680
2719
|
struct CreateViewInfo : public CreateInfo {
|
|
2681
|
-
CreateViewInfo() : CreateInfo(CatalogType::VIEW_ENTRY) {
|
|
2720
|
+
CreateViewInfo() : CreateInfo(CatalogType::VIEW_ENTRY, INVALID_SCHEMA) {
|
|
2682
2721
|
}
|
|
2683
2722
|
CreateViewInfo(string schema, string view_name)
|
|
2684
2723
|
: CreateInfo(CatalogType::VIEW_ENTRY, schema), view_name(view_name) {
|
|
@@ -4606,6 +4645,12 @@ public:
|
|
|
4606
4645
|
|
|
4607
4646
|
namespace duckdb {
|
|
4608
4647
|
|
|
4648
|
+
string SimilarCatalogEntry::GetQualifiedName() const {
|
|
4649
|
+
D_ASSERT(Found());
|
|
4650
|
+
|
|
4651
|
+
return name + "." + schema->name;
|
|
4652
|
+
}
|
|
4653
|
+
|
|
4609
4654
|
Catalog::Catalog(DatabaseInstance &db)
|
|
4610
4655
|
: db(db), schemas(make_unique<CatalogSet>(*this, make_unique<DefaultSchemaGenerator>(*this))),
|
|
4611
4656
|
dependency_manager(make_unique<DependencyManager>(*this)) {
|
|
@@ -4728,23 +4773,25 @@ void Catalog::DropEntry(ClientContext &context, DropInfo *info) {
|
|
|
4728
4773
|
if (info->type == CatalogType::SCHEMA_ENTRY) {
|
|
4729
4774
|
// DROP SCHEMA
|
|
4730
4775
|
DropSchema(context, info);
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4776
|
+
return;
|
|
4777
|
+
}
|
|
4778
|
+
|
|
4779
|
+
auto lookup = LookupEntry(context, info->type, info->schema, info->name, info->if_exists);
|
|
4780
|
+
if (!lookup.Found()) {
|
|
4781
|
+
return;
|
|
4737
4782
|
}
|
|
4783
|
+
|
|
4784
|
+
lookup.schema->DropEntry(context, info);
|
|
4738
4785
|
}
|
|
4739
4786
|
|
|
4740
|
-
SchemaCatalogEntry *Catalog::GetSchema(ClientContext &context, const string &schema_name,
|
|
4787
|
+
SchemaCatalogEntry *Catalog::GetSchema(ClientContext &context, const string &schema_name, bool if_exists,
|
|
4741
4788
|
QueryErrorContext error_context) {
|
|
4742
4789
|
D_ASSERT(!schema_name.empty());
|
|
4743
4790
|
if (schema_name == TEMP_SCHEMA) {
|
|
4744
4791
|
return context.temporary_objects.get();
|
|
4745
4792
|
}
|
|
4746
4793
|
auto entry = schemas->GetEntry(context, schema_name);
|
|
4747
|
-
if (!entry) {
|
|
4794
|
+
if (!entry && !if_exists) {
|
|
4748
4795
|
throw CatalogException(error_context.FormatError("Schema with name %s does not exist!", schema_name));
|
|
4749
4796
|
}
|
|
4750
4797
|
return (SchemaCatalogEntry *)entry;
|
|
@@ -4755,29 +4802,99 @@ void Catalog::ScanSchemas(ClientContext &context, std::function<void(CatalogEntr
|
|
|
4755
4802
|
schemas->Scan(context, [&](CatalogEntry *entry) { callback(entry); });
|
|
4756
4803
|
}
|
|
4757
4804
|
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4805
|
+
SimilarCatalogEntry Catalog::SimilarEntryInSchemas(ClientContext &context, const string &entry_name, CatalogType type,
|
|
4806
|
+
const vector<SchemaCatalogEntry *> &schemas) {
|
|
4807
|
+
|
|
4808
|
+
vector<CatalogSet *> sets;
|
|
4809
|
+
std::transform(schemas.begin(), schemas.end(), std::back_inserter(sets),
|
|
4810
|
+
[type](SchemaCatalogEntry *s) -> CatalogSet * { return &s->GetCatalogSet(type); });
|
|
4811
|
+
pair<string, idx_t> most_similar {"", (idx_t)-1};
|
|
4812
|
+
SchemaCatalogEntry *schema_of_most_similar = nullptr;
|
|
4813
|
+
for (auto schema : schemas) {
|
|
4814
|
+
auto entry = schema->GetCatalogSet(type).SimilarEntry(context, entry_name);
|
|
4815
|
+
if (!entry.first.empty() && (most_similar.first.empty() || most_similar.second > entry.second)) {
|
|
4816
|
+
most_similar = entry;
|
|
4817
|
+
schema_of_most_similar = schema;
|
|
4764
4818
|
}
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4819
|
+
}
|
|
4820
|
+
|
|
4821
|
+
return {most_similar.first, most_similar.second, schema_of_most_similar};
|
|
4822
|
+
}
|
|
4823
|
+
|
|
4824
|
+
CatalogException Catalog::CreateMissingEntryException(ClientContext &context, const string &entry_name,
|
|
4825
|
+
CatalogType type, const vector<SchemaCatalogEntry *> &schemas,
|
|
4826
|
+
QueryErrorContext error_context) {
|
|
4827
|
+
auto entry = SimilarEntryInSchemas(context, entry_name, type, schemas);
|
|
4828
|
+
|
|
4829
|
+
vector<SchemaCatalogEntry *> unseen_schemas;
|
|
4830
|
+
this->schemas->Scan([&schemas, &unseen_schemas](CatalogEntry *entry) {
|
|
4831
|
+
auto schema_entry = (SchemaCatalogEntry *)entry;
|
|
4832
|
+
if (std::find(schemas.begin(), schemas.end(), schema_entry) == schemas.end()) {
|
|
4833
|
+
unseen_schemas.emplace_back(schema_entry);
|
|
4834
|
+
}
|
|
4835
|
+
});
|
|
4836
|
+
auto unseen_entry = SimilarEntryInSchemas(context, entry_name, type, unseen_schemas);
|
|
4837
|
+
|
|
4838
|
+
string did_you_mean;
|
|
4839
|
+
if (unseen_entry.Found() && unseen_entry.distance < entry.distance) {
|
|
4840
|
+
did_you_mean = "\nDid you mean \"" + unseen_entry.GetQualifiedName() + "\"?";
|
|
4841
|
+
} else if (entry.Found()) {
|
|
4842
|
+
did_you_mean = "\nDid you mean \"" + entry.name + "\"?";
|
|
4843
|
+
}
|
|
4844
|
+
|
|
4845
|
+
return CatalogException(error_context.FormatError("%s with name %s does not exist!%s", CatalogTypeToString(type),
|
|
4846
|
+
entry_name, did_you_mean));
|
|
4847
|
+
}
|
|
4848
|
+
|
|
4849
|
+
CatalogEntryLookup Catalog::LookupEntry(ClientContext &context, CatalogType type, const string &schema_name,
|
|
4850
|
+
const string &name, bool if_exists, QueryErrorContext error_context) {
|
|
4851
|
+
if (!schema_name.empty()) {
|
|
4852
|
+
auto schema = GetSchema(context, schema_name, if_exists, error_context);
|
|
4853
|
+
if (!schema) {
|
|
4854
|
+
D_ASSERT(if_exists);
|
|
4855
|
+
return {nullptr, nullptr};
|
|
4856
|
+
}
|
|
4857
|
+
|
|
4858
|
+
auto entry = schema->GetCatalogSet(type).GetEntry(context, name);
|
|
4859
|
+
if (!entry && !if_exists) {
|
|
4860
|
+
throw CreateMissingEntryException(context, name, type, {schema}, error_context);
|
|
4861
|
+
}
|
|
4862
|
+
|
|
4863
|
+
return {schema, entry};
|
|
4864
|
+
}
|
|
4865
|
+
|
|
4866
|
+
const auto &paths = context.catalog_search_path->Get();
|
|
4867
|
+
for (const auto &path : paths) {
|
|
4868
|
+
auto lookup = LookupEntry(context, type, path, name, true, error_context);
|
|
4869
|
+
if (lookup.Found()) {
|
|
4870
|
+
return lookup;
|
|
4871
|
+
}
|
|
4872
|
+
}
|
|
4873
|
+
|
|
4874
|
+
if (!if_exists) {
|
|
4875
|
+
vector<SchemaCatalogEntry *> schemas;
|
|
4876
|
+
for (const auto &path : paths) {
|
|
4877
|
+
auto schema = GetSchema(context, path, true);
|
|
4878
|
+
if (schema) {
|
|
4879
|
+
schemas.emplace_back(schema);
|
|
4770
4880
|
}
|
|
4771
4881
|
}
|
|
4882
|
+
|
|
4883
|
+
throw CreateMissingEntryException(context, name, type, schemas, error_context);
|
|
4772
4884
|
}
|
|
4773
|
-
|
|
4774
|
-
return
|
|
4885
|
+
|
|
4886
|
+
return {nullptr, nullptr};
|
|
4887
|
+
}
|
|
4888
|
+
|
|
4889
|
+
CatalogEntry *Catalog::GetEntry(ClientContext &context, CatalogType type, const string &schema_name, const string &name,
|
|
4890
|
+
bool if_exists, QueryErrorContext error_context) {
|
|
4891
|
+
return LookupEntry(context, type, schema_name, name, if_exists, error_context).entry;
|
|
4775
4892
|
}
|
|
4776
4893
|
|
|
4777
4894
|
template <>
|
|
4778
|
-
TableCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
4779
|
-
QueryErrorContext error_context) {
|
|
4780
|
-
auto entry = GetEntry(context, CatalogType::TABLE_ENTRY,
|
|
4895
|
+
TableCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
4896
|
+
bool if_exists, QueryErrorContext error_context) {
|
|
4897
|
+
auto entry = GetEntry(context, CatalogType::TABLE_ENTRY, schema_name, name, if_exists);
|
|
4781
4898
|
if (!entry) {
|
|
4782
4899
|
return nullptr;
|
|
4783
4900
|
}
|
|
@@ -4788,38 +4905,37 @@ TableCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name,
|
|
|
4788
4905
|
}
|
|
4789
4906
|
|
|
4790
4907
|
template <>
|
|
4791
|
-
SequenceCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
4792
|
-
QueryErrorContext error_context) {
|
|
4793
|
-
return (SequenceCatalogEntry *)GetEntry(context, CatalogType::SEQUENCE_ENTRY,
|
|
4908
|
+
SequenceCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
4909
|
+
bool if_exists, QueryErrorContext error_context) {
|
|
4910
|
+
return (SequenceCatalogEntry *)GetEntry(context, CatalogType::SEQUENCE_ENTRY, schema_name, name, if_exists,
|
|
4794
4911
|
error_context);
|
|
4795
4912
|
}
|
|
4796
4913
|
|
|
4797
4914
|
template <>
|
|
4798
|
-
TableFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
4915
|
+
TableFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
4799
4916
|
bool if_exists, QueryErrorContext error_context) {
|
|
4800
|
-
return (TableFunctionCatalogEntry *)GetEntry(context, CatalogType::TABLE_FUNCTION_ENTRY,
|
|
4917
|
+
return (TableFunctionCatalogEntry *)GetEntry(context, CatalogType::TABLE_FUNCTION_ENTRY, schema_name, name,
|
|
4801
4918
|
if_exists, error_context);
|
|
4802
4919
|
}
|
|
4803
4920
|
|
|
4804
4921
|
template <>
|
|
4805
|
-
CopyFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
4922
|
+
CopyFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
4806
4923
|
bool if_exists, QueryErrorContext error_context) {
|
|
4807
|
-
return (CopyFunctionCatalogEntry *)GetEntry(context, CatalogType::COPY_FUNCTION_ENTRY,
|
|
4808
|
-
|
|
4924
|
+
return (CopyFunctionCatalogEntry *)GetEntry(context, CatalogType::COPY_FUNCTION_ENTRY, schema_name, name, if_exists,
|
|
4925
|
+
error_context);
|
|
4809
4926
|
}
|
|
4810
4927
|
|
|
4811
4928
|
template <>
|
|
4812
|
-
PragmaFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
4929
|
+
PragmaFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
4813
4930
|
bool if_exists, QueryErrorContext error_context) {
|
|
4814
|
-
return (PragmaFunctionCatalogEntry *)GetEntry(context, CatalogType::PRAGMA_FUNCTION_ENTRY,
|
|
4931
|
+
return (PragmaFunctionCatalogEntry *)GetEntry(context, CatalogType::PRAGMA_FUNCTION_ENTRY, schema_name, name,
|
|
4815
4932
|
if_exists, error_context);
|
|
4816
4933
|
}
|
|
4817
4934
|
|
|
4818
4935
|
template <>
|
|
4819
|
-
AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
4936
|
+
AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
4820
4937
|
bool if_exists, QueryErrorContext error_context) {
|
|
4821
|
-
auto entry =
|
|
4822
|
-
GetEntry(context, CatalogType::AGGREGATE_FUNCTION_ENTRY, move(schema_name), name, if_exists, error_context);
|
|
4938
|
+
auto entry = GetEntry(context, CatalogType::AGGREGATE_FUNCTION_ENTRY, schema_name, name, if_exists, error_context);
|
|
4823
4939
|
if (entry->type != CatalogType::AGGREGATE_FUNCTION_ENTRY) {
|
|
4824
4940
|
throw CatalogException(error_context.FormatError("%s is not an aggregate function", name));
|
|
4825
4941
|
}
|
|
@@ -4827,29 +4943,17 @@ AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string
|
|
|
4827
4943
|
}
|
|
4828
4944
|
|
|
4829
4945
|
template <>
|
|
4830
|
-
CollateCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
4831
|
-
QueryErrorContext error_context) {
|
|
4832
|
-
return (CollateCatalogEntry *)GetEntry(context, CatalogType::COLLATION_ENTRY,
|
|
4946
|
+
CollateCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
4947
|
+
bool if_exists, QueryErrorContext error_context) {
|
|
4948
|
+
return (CollateCatalogEntry *)GetEntry(context, CatalogType::COLLATION_ENTRY, schema_name, name, if_exists,
|
|
4833
4949
|
error_context);
|
|
4834
4950
|
}
|
|
4835
4951
|
|
|
4836
4952
|
void Catalog::Alter(ClientContext &context, AlterInfo *info) {
|
|
4837
4953
|
ModifyCatalog();
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
info->schema = DEFAULT_SCHEMA;
|
|
4842
|
-
for (idx_t i = 0; i < context.catalog_search_path.size(); i++) {
|
|
4843
|
-
auto entry = GetEntry(context, catalog_type, context.catalog_search_path[i], info->name, true);
|
|
4844
|
-
if (entry) {
|
|
4845
|
-
// entry exists in this schema: alter there
|
|
4846
|
-
info->schema = context.catalog_search_path[i];
|
|
4847
|
-
break;
|
|
4848
|
-
}
|
|
4849
|
-
}
|
|
4850
|
-
}
|
|
4851
|
-
auto schema = GetSchema(context, info->schema);
|
|
4852
|
-
return schema->Alter(context, info);
|
|
4954
|
+
auto lookup = LookupEntry(context, info->GetCatalogType(), info->schema, info->name);
|
|
4955
|
+
D_ASSERT(lookup.Found()); // It must have thrown otherwise.
|
|
4956
|
+
return lookup.schema->Alter(context, info);
|
|
4853
4957
|
}
|
|
4854
4958
|
|
|
4855
4959
|
idx_t Catalog::GetCatalogVersion() {
|
|
@@ -6622,26 +6726,6 @@ void SchemaCatalogEntry::Alter(ClientContext &context, AlterInfo *info) {
|
|
|
6622
6726
|
}
|
|
6623
6727
|
}
|
|
6624
6728
|
|
|
6625
|
-
CatalogEntry *SchemaCatalogEntry::GetEntry(ClientContext &context, CatalogType type, const string &entry_name,
|
|
6626
|
-
bool if_exists, QueryErrorContext error_context) {
|
|
6627
|
-
auto &set = GetCatalogSet(type);
|
|
6628
|
-
|
|
6629
|
-
auto entry = set.GetEntry(context, entry_name);
|
|
6630
|
-
if (!entry) {
|
|
6631
|
-
if (!if_exists) {
|
|
6632
|
-
auto entry = set.SimilarEntry(context, entry_name);
|
|
6633
|
-
string did_you_mean;
|
|
6634
|
-
if (!entry.empty()) {
|
|
6635
|
-
did_you_mean = "\nDid you mean \"" + entry + "\"?";
|
|
6636
|
-
}
|
|
6637
|
-
throw CatalogException(error_context.FormatError("%s with name %s does not exist!%s",
|
|
6638
|
-
CatalogTypeToString(type), entry_name, did_you_mean));
|
|
6639
|
-
}
|
|
6640
|
-
return nullptr;
|
|
6641
|
-
}
|
|
6642
|
-
return entry;
|
|
6643
|
-
}
|
|
6644
|
-
|
|
6645
6729
|
void SchemaCatalogEntry::Scan(ClientContext &context, CatalogType type,
|
|
6646
6730
|
const std::function<void(CatalogEntry *)> &callback) {
|
|
6647
6731
|
auto &set = GetCatalogSet(type);
|
|
@@ -8518,6 +8602,51 @@ string CatalogEntry::ToSQL() {
|
|
|
8518
8602
|
|
|
8519
8603
|
|
|
8520
8604
|
|
|
8605
|
+
|
|
8606
|
+
|
|
8607
|
+
|
|
8608
|
+
namespace duckdb {
|
|
8609
|
+
|
|
8610
|
+
CatalogSearchPath::CatalogSearchPath(ClientContext &context_p) : context(context_p), paths(ParsePaths("")) {
|
|
8611
|
+
}
|
|
8612
|
+
|
|
8613
|
+
const vector<string> &CatalogSearchPath::Get() {
|
|
8614
|
+
Value value;
|
|
8615
|
+
context.TryGetCurrentSetting("search_path", value);
|
|
8616
|
+
if (value.str_value != last_value) {
|
|
8617
|
+
paths = ParsePaths(value.str_value);
|
|
8618
|
+
last_value = value.str_value;
|
|
8619
|
+
}
|
|
8620
|
+
|
|
8621
|
+
return paths;
|
|
8622
|
+
}
|
|
8623
|
+
|
|
8624
|
+
const string &CatalogSearchPath::GetDefault() {
|
|
8625
|
+
const auto &paths = Get();
|
|
8626
|
+
D_ASSERT(paths.size() >= 2);
|
|
8627
|
+
D_ASSERT(paths[0] == TEMP_SCHEMA);
|
|
8628
|
+
return paths[1];
|
|
8629
|
+
}
|
|
8630
|
+
|
|
8631
|
+
vector<string> CatalogSearchPath::ParsePaths(const string &value) {
|
|
8632
|
+
vector<string> paths;
|
|
8633
|
+
paths.emplace_back(TEMP_SCHEMA);
|
|
8634
|
+
|
|
8635
|
+
auto given_paths = StringUtil::SplitWithQuote(value);
|
|
8636
|
+
for (const auto &p : given_paths) {
|
|
8637
|
+
paths.emplace_back(StringUtil::Lower(p));
|
|
8638
|
+
}
|
|
8639
|
+
|
|
8640
|
+
paths.emplace_back(DEFAULT_SCHEMA);
|
|
8641
|
+
paths.emplace_back("pg_catalog");
|
|
8642
|
+
return paths;
|
|
8643
|
+
}
|
|
8644
|
+
|
|
8645
|
+
} // namespace duckdb
|
|
8646
|
+
|
|
8647
|
+
|
|
8648
|
+
|
|
8649
|
+
|
|
8521
8650
|
//===----------------------------------------------------------------------===//
|
|
8522
8651
|
// DuckDB
|
|
8523
8652
|
//
|
|
@@ -8919,7 +9048,7 @@ CatalogEntry *CatalogSet::GetCommittedEntry(CatalogEntry *current) {
|
|
|
8919
9048
|
return current;
|
|
8920
9049
|
}
|
|
8921
9050
|
|
|
8922
|
-
string CatalogSet::SimilarEntry(ClientContext &context, const string &name) {
|
|
9051
|
+
pair<string, idx_t> CatalogSet::SimilarEntry(ClientContext &context, const string &name) {
|
|
8923
9052
|
lock_guard<mutex> lock(catalog_lock);
|
|
8924
9053
|
|
|
8925
9054
|
string result;
|
|
@@ -8934,7 +9063,7 @@ string CatalogSet::SimilarEntry(ClientContext &context, const string &name) {
|
|
|
8934
9063
|
}
|
|
8935
9064
|
}
|
|
8936
9065
|
}
|
|
8937
|
-
return result;
|
|
9066
|
+
return {result, current_score};
|
|
8938
9067
|
}
|
|
8939
9068
|
|
|
8940
9069
|
CatalogEntry *CatalogSet::CreateEntryInternal(ClientContext &context, unique_ptr<CatalogEntry> entry) {
|
|
@@ -9272,8 +9401,10 @@ static DefaultMacro internal_macros[] = {
|
|
|
9272
9401
|
{"pg_catalog", "pg_ts_template_is_visible", {"template_oid", nullptr}, "true"},
|
|
9273
9402
|
{"pg_catalog", "pg_type_is_visible", {"type_oid", nullptr}, "true"},
|
|
9274
9403
|
|
|
9404
|
+
{DEFAULT_SCHEMA, "round_even", {"x", "n", nullptr}, "CASE ((abs(x) * power(10, n+1)) % 10) WHEN 5 THEN round(x/2, n) * 2 ELSE round(x, n) END"},
|
|
9405
|
+
{DEFAULT_SCHEMA, "roundbankers", {"x", "n", nullptr}, "round_even(x, n)"},
|
|
9275
9406
|
{DEFAULT_SCHEMA, "nullif", {"a", "b", nullptr}, "CASE WHEN a=b THEN NULL ELSE a END"},
|
|
9276
|
-
|
|
9407
|
+
{nullptr, nullptr, {nullptr}, nullptr}};
|
|
9277
9408
|
|
|
9278
9409
|
static unique_ptr<CreateFunctionInfo> GetDefaultFunction(const string &schema, const string &name) {
|
|
9279
9410
|
for (idx_t index = 0; internal_macros[index].name != nullptr; index++) {
|
|
@@ -31142,6 +31273,7 @@ void SortedDataScanner::Scan(DataChunk &chunk) {
|
|
|
31142
31273
|
|
|
31143
31274
|
|
|
31144
31275
|
|
|
31276
|
+
|
|
31145
31277
|
#include <algorithm>
|
|
31146
31278
|
#include <cctype>
|
|
31147
31279
|
#include <iomanip>
|
|
@@ -31207,6 +31339,65 @@ vector<string> StringUtil::Split(const string &str, char delimiter) {
|
|
|
31207
31339
|
return (lines);
|
|
31208
31340
|
}
|
|
31209
31341
|
|
|
31342
|
+
namespace string_util_internal {
|
|
31343
|
+
|
|
31344
|
+
inline void SkipSpaces(const string &str, idx_t &index) {
|
|
31345
|
+
while (index < str.size() && std::isspace(str[index])) {
|
|
31346
|
+
index++;
|
|
31347
|
+
}
|
|
31348
|
+
}
|
|
31349
|
+
|
|
31350
|
+
inline void ConsumeLetter(const string &str, idx_t &index, char expected) {
|
|
31351
|
+
if (index >= str.size() || str[index] != expected) {
|
|
31352
|
+
throw ParserException("Invalid quoted list: %s", str);
|
|
31353
|
+
}
|
|
31354
|
+
|
|
31355
|
+
index++;
|
|
31356
|
+
}
|
|
31357
|
+
|
|
31358
|
+
template <typename F>
|
|
31359
|
+
inline void TakeWhile(const string &str, idx_t &index, const F &cond, string &taker) {
|
|
31360
|
+
while (index < str.size() && cond(str[index])) {
|
|
31361
|
+
taker.push_back(str[index]);
|
|
31362
|
+
index++;
|
|
31363
|
+
}
|
|
31364
|
+
}
|
|
31365
|
+
|
|
31366
|
+
inline string TakePossiblyQuotedItem(const string &str, idx_t &index, char delimiter, char quote) {
|
|
31367
|
+
string entry;
|
|
31368
|
+
|
|
31369
|
+
if (str[index] == quote) {
|
|
31370
|
+
index++;
|
|
31371
|
+
TakeWhile(
|
|
31372
|
+
str, index, [quote](char c) { return c != quote; }, entry);
|
|
31373
|
+
ConsumeLetter(str, index, quote);
|
|
31374
|
+
} else {
|
|
31375
|
+
TakeWhile(
|
|
31376
|
+
str, index, [delimiter, quote](char c) { return c != delimiter && c != quote && !std::isspace(c); }, entry);
|
|
31377
|
+
}
|
|
31378
|
+
|
|
31379
|
+
return entry;
|
|
31380
|
+
}
|
|
31381
|
+
|
|
31382
|
+
} // namespace string_util_internal
|
|
31383
|
+
|
|
31384
|
+
vector<string> StringUtil::SplitWithQuote(const string &str, char delimiter, char quote) {
|
|
31385
|
+
vector<string> entries;
|
|
31386
|
+
idx_t i = 0;
|
|
31387
|
+
|
|
31388
|
+
string_util_internal::SkipSpaces(str, i);
|
|
31389
|
+
while (i < str.size()) {
|
|
31390
|
+
if (!entries.empty()) {
|
|
31391
|
+
string_util_internal::ConsumeLetter(str, i, delimiter);
|
|
31392
|
+
}
|
|
31393
|
+
|
|
31394
|
+
entries.emplace_back(string_util_internal::TakePossiblyQuotedItem(str, i, delimiter, quote));
|
|
31395
|
+
string_util_internal::SkipSpaces(str, i);
|
|
31396
|
+
}
|
|
31397
|
+
|
|
31398
|
+
return entries;
|
|
31399
|
+
}
|
|
31400
|
+
|
|
31210
31401
|
string StringUtil::Join(const vector<string> &input, const string &separator) {
|
|
31211
31402
|
return StringUtil::Join(input, input.size(), separator, [](const string &s) { return s; });
|
|
31212
31403
|
}
|
|
@@ -55315,7 +55506,7 @@ namespace duckdb {
|
|
|
55315
55506
|
//! PhysicalSet represents a SET operation (e.g. SET a = 42)
|
|
55316
55507
|
class PhysicalSet : public PhysicalOperator {
|
|
55317
55508
|
public:
|
|
55318
|
-
PhysicalSet(std::string name_p, Value value_p, SetScope scope_p, idx_t estimated_cardinality)
|
|
55509
|
+
PhysicalSet(const std::string &name_p, Value value_p, SetScope scope_p, idx_t estimated_cardinality)
|
|
55319
55510
|
: PhysicalOperator(PhysicalOperatorType::SET, {LogicalType::BOOLEAN}, estimated_cardinality), name(name_p),
|
|
55320
55511
|
value(value_p), scope(scope_p) {
|
|
55321
55512
|
}
|
|
@@ -55324,9 +55515,13 @@ public:
|
|
|
55324
55515
|
void GetChunkInternal(ExecutionContext &context, DataChunk &chunk, PhysicalOperatorState *state) const override;
|
|
55325
55516
|
|
|
55326
55517
|
public:
|
|
55327
|
-
std::string name;
|
|
55328
|
-
Value value;
|
|
55329
|
-
SetScope scope;
|
|
55518
|
+
const std::string name;
|
|
55519
|
+
const Value value;
|
|
55520
|
+
const SetScope scope;
|
|
55521
|
+
|
|
55522
|
+
private:
|
|
55523
|
+
//! Returns the normalized key name.
|
|
55524
|
+
string ValidateInput(ExecutionContext &context) const;
|
|
55330
55525
|
};
|
|
55331
55526
|
|
|
55332
55527
|
} // namespace duckdb
|
|
@@ -55334,20 +55529,47 @@ public:
|
|
|
55334
55529
|
|
|
55335
55530
|
|
|
55336
55531
|
|
|
55532
|
+
|
|
55533
|
+
|
|
55337
55534
|
namespace duckdb {
|
|
55338
55535
|
|
|
55339
55536
|
void PhysicalSet::GetChunkInternal(ExecutionContext &context, DataChunk &chunk, PhysicalOperatorState *state) const {
|
|
55340
55537
|
D_ASSERT(scope == SetScope::GLOBAL || scope == SetScope::SESSION);
|
|
55341
55538
|
|
|
55539
|
+
auto normalized_name = ValidateInput(context);
|
|
55342
55540
|
if (scope == SetScope::GLOBAL) {
|
|
55343
|
-
context.client.db->config.set_variables[
|
|
55541
|
+
context.client.db->config.set_variables[normalized_name] = value;
|
|
55344
55542
|
} else {
|
|
55345
|
-
context.client.set_variables[
|
|
55543
|
+
context.client.set_variables[normalized_name] = value;
|
|
55346
55544
|
}
|
|
55347
55545
|
|
|
55348
55546
|
state->finished = true;
|
|
55349
55547
|
}
|
|
55350
55548
|
|
|
55549
|
+
string PhysicalSet::ValidateInput(ExecutionContext &context) const {
|
|
55550
|
+
CaseInsensitiveStringEquality case_insensitive_streq;
|
|
55551
|
+
if (case_insensitive_streq(name, "search_path") || case_insensitive_streq(name, "schema")) {
|
|
55552
|
+
auto paths = StringUtil::SplitWithQuote(value.str_value, ',');
|
|
55553
|
+
|
|
55554
|
+
// The PG doc says:
|
|
55555
|
+
// > SET SCHEMA 'value' is an alias for SET search_path TO value.
|
|
55556
|
+
// > Only one schema can be specified using this syntax.
|
|
55557
|
+
if (case_insensitive_streq(name, "schema") && paths.size() > 1) {
|
|
55558
|
+
throw CatalogException("SET schema can set only 1 schema. This has %d", paths.size());
|
|
55559
|
+
}
|
|
55560
|
+
|
|
55561
|
+
for (const auto &path : paths) {
|
|
55562
|
+
if (!context.client.db->GetCatalog().GetSchema(context.client, StringUtil::Lower(path), true)) {
|
|
55563
|
+
throw CatalogException("SET %s: No schema named %s found.", name, path);
|
|
55564
|
+
}
|
|
55565
|
+
}
|
|
55566
|
+
|
|
55567
|
+
return "search_path";
|
|
55568
|
+
}
|
|
55569
|
+
|
|
55570
|
+
return name;
|
|
55571
|
+
}
|
|
55572
|
+
|
|
55351
55573
|
} // namespace duckdb
|
|
55352
55574
|
//===----------------------------------------------------------------------===//
|
|
55353
55575
|
// DuckDB
|
|
@@ -80241,6 +80463,7 @@ bool ConstantOrNull::IsConstantOrNull(BoundFunctionExpression &expr, const Value
|
|
|
80241
80463
|
|
|
80242
80464
|
|
|
80243
80465
|
|
|
80466
|
+
|
|
80244
80467
|
namespace duckdb {
|
|
80245
80468
|
|
|
80246
80469
|
struct CurrentSettingBindData : public FunctionData {
|
|
@@ -80261,6 +80484,16 @@ static void CurrentSettingFunction(DataChunk &args, ExpressionState &state, Vect
|
|
|
80261
80484
|
result.Reference(info.value);
|
|
80262
80485
|
}
|
|
80263
80486
|
|
|
80487
|
+
static string NormalizeSettingName(const string &name) {
|
|
80488
|
+
if (CaseInsensitiveStringEquality()(name, "schema")) {
|
|
80489
|
+
// The PG doc says:
|
|
80490
|
+
// > SET SCHEMA 'value' is an alias for SET search_path TO value.
|
|
80491
|
+
return "search_path";
|
|
80492
|
+
}
|
|
80493
|
+
|
|
80494
|
+
return name;
|
|
80495
|
+
}
|
|
80496
|
+
|
|
80264
80497
|
unique_ptr<FunctionData> CurrentSettingBind(ClientContext &context, ScalarFunction &bound_function,
|
|
80265
80498
|
vector<unique_ptr<Expression>> &arguments) {
|
|
80266
80499
|
|
|
@@ -80276,7 +80509,7 @@ unique_ptr<FunctionData> CurrentSettingBind(ClientContext &context, ScalarFuncti
|
|
|
80276
80509
|
throw ParserException("Key name for struct_extract needs to be neither NULL nor empty");
|
|
80277
80510
|
}
|
|
80278
80511
|
|
|
80279
|
-
const auto &key = key_val.str_value;
|
|
80512
|
+
const auto &key = NormalizeSettingName(key_val.str_value);
|
|
80280
80513
|
Value val;
|
|
80281
80514
|
if (!context.TryGetCurrentSetting(key, val)) {
|
|
80282
80515
|
throw InvalidInputException("Variable '%s' was not SET in this context", key);
|
|
@@ -97139,6 +97372,7 @@ private:
|
|
|
97139
97372
|
|
|
97140
97373
|
|
|
97141
97374
|
|
|
97375
|
+
|
|
97142
97376
|
//===----------------------------------------------------------------------===//
|
|
97143
97377
|
// DuckDB
|
|
97144
97378
|
//
|
|
@@ -97581,6 +97815,7 @@ ClientContext::ClientContext(shared_ptr<DatabaseInstance> database)
|
|
|
97581
97815
|
: profiler(make_unique<QueryProfiler>()), query_profiler_history(make_unique<QueryProfilerHistory>()),
|
|
97582
97816
|
db(move(database)), transaction(db->GetTransactionManager(), *this), interrupted(false), executor(*this),
|
|
97583
97817
|
temporary_objects(make_unique<SchemaCatalogEntry>(&db->GetCatalog(), TEMP_SCHEMA, true)),
|
|
97818
|
+
catalog_search_path(make_unique<CatalogSearchPath>(*this)),
|
|
97584
97819
|
file_opener(make_unique<ClientContextFileOpener>(*this)), open_result(nullptr) {
|
|
97585
97820
|
std::random_device rd;
|
|
97586
97821
|
random_engine.seed(rd());
|
|
@@ -129739,6 +129974,7 @@ unique_ptr<QueryNode> Transformer::TransformSelectNode(duckdb_libpgquery::PGSele
|
|
|
129739
129974
|
|
|
129740
129975
|
|
|
129741
129976
|
|
|
129977
|
+
|
|
129742
129978
|
namespace duckdb {
|
|
129743
129979
|
|
|
129744
129980
|
namespace {
|
|
@@ -133930,6 +134166,7 @@ BoundStatement Binder::Bind(CopyStatement &stmt) {
|
|
|
133930
134166
|
|
|
133931
134167
|
|
|
133932
134168
|
|
|
134169
|
+
|
|
133933
134170
|
//===----------------------------------------------------------------------===//
|
|
133934
134171
|
// DuckDB
|
|
133935
134172
|
//
|
|
@@ -134030,7 +134267,7 @@ namespace duckdb {
|
|
|
134030
134267
|
|
|
134031
134268
|
SchemaCatalogEntry *Binder::BindSchema(CreateInfo &info) {
|
|
134032
134269
|
if (info.schema.empty()) {
|
|
134033
|
-
info.schema = info.temporary ? TEMP_SCHEMA :
|
|
134270
|
+
info.schema = info.temporary ? TEMP_SCHEMA : context.catalog_search_path->GetDefault();
|
|
134034
134271
|
}
|
|
134035
134272
|
|
|
134036
134273
|
if (!info.temporary) {
|
package/src/duckdb.hpp
CHANGED
|
@@ -10,8 +10,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
10
10
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
|
-
#define DUCKDB_SOURCE_ID "
|
|
14
|
-
#define DUCKDB_VERSION "0.2.10-
|
|
13
|
+
#define DUCKDB_SOURCE_ID "20ddfa846"
|
|
14
|
+
#define DUCKDB_VERSION "0.2.10-dev468"
|
|
15
15
|
//===----------------------------------------------------------------------===//
|
|
16
16
|
// DuckDB
|
|
17
17
|
//
|
|
@@ -1770,7 +1770,7 @@ class FileFlags {
|
|
|
1770
1770
|
public:
|
|
1771
1771
|
//! Open file with read access
|
|
1772
1772
|
static constexpr uint8_t FILE_FLAGS_READ = 1 << 0;
|
|
1773
|
-
//! Open file with
|
|
1773
|
+
//! Open file with write access
|
|
1774
1774
|
static constexpr uint8_t FILE_FLAGS_WRITE = 1 << 1;
|
|
1775
1775
|
//! Use direct IO when reading/writing to the file
|
|
1776
1776
|
static constexpr uint8_t FILE_FLAGS_DIRECT_IO = 1 << 2;
|
|
@@ -7313,6 +7313,32 @@ class CatalogSet;
|
|
|
7313
7313
|
class DatabaseInstance;
|
|
7314
7314
|
class DependencyManager;
|
|
7315
7315
|
|
|
7316
|
+
//! Return value of Catalog::LookupEntry
|
|
7317
|
+
struct CatalogEntryLookup {
|
|
7318
|
+
SchemaCatalogEntry *schema;
|
|
7319
|
+
CatalogEntry *entry;
|
|
7320
|
+
|
|
7321
|
+
bool Found() const {
|
|
7322
|
+
return entry;
|
|
7323
|
+
}
|
|
7324
|
+
};
|
|
7325
|
+
|
|
7326
|
+
//! Return value of SimilarEntryInSchemas
|
|
7327
|
+
struct SimilarCatalogEntry {
|
|
7328
|
+
//! The entry name. Empty if absent
|
|
7329
|
+
string name;
|
|
7330
|
+
//! The distance to the given name.
|
|
7331
|
+
idx_t distance;
|
|
7332
|
+
//! The schema of the entry.
|
|
7333
|
+
SchemaCatalogEntry *schema;
|
|
7334
|
+
|
|
7335
|
+
bool Found() const {
|
|
7336
|
+
return !name.empty();
|
|
7337
|
+
}
|
|
7338
|
+
|
|
7339
|
+
string GetQualifiedName() const;
|
|
7340
|
+
};
|
|
7341
|
+
|
|
7316
7342
|
//! The Catalog object represents the catalog of the database.
|
|
7317
7343
|
class Catalog {
|
|
7318
7344
|
public:
|
|
@@ -7384,17 +7410,17 @@ public:
|
|
|
7384
7410
|
void DropEntry(ClientContext &context, DropInfo *info);
|
|
7385
7411
|
|
|
7386
7412
|
//! Returns the schema object with the specified name, or throws an exception if it does not exist
|
|
7387
|
-
SchemaCatalogEntry *GetSchema(ClientContext &context, const string &name = DEFAULT_SCHEMA,
|
|
7413
|
+
SchemaCatalogEntry *GetSchema(ClientContext &context, const string &name = DEFAULT_SCHEMA, bool if_exists = false,
|
|
7388
7414
|
QueryErrorContext error_context = QueryErrorContext());
|
|
7389
7415
|
//! Scans all the schemas in the system one-by-one, invoking the callback for each entry
|
|
7390
7416
|
void ScanSchemas(ClientContext &context, std::function<void(CatalogEntry *)> callback);
|
|
7391
7417
|
//! Gets the "schema.name" entry of the specified type, if if_exists=true returns nullptr if entry does not exist,
|
|
7392
7418
|
//! otherwise an exception is thrown
|
|
7393
|
-
CatalogEntry *GetEntry(ClientContext &context, CatalogType type, string schema, const string &name,
|
|
7419
|
+
CatalogEntry *GetEntry(ClientContext &context, CatalogType type, const string &schema, const string &name,
|
|
7394
7420
|
bool if_exists = false, QueryErrorContext error_context = QueryErrorContext());
|
|
7395
7421
|
|
|
7396
7422
|
template <class T>
|
|
7397
|
-
T *GetEntry(ClientContext &context, string schema_name, const string &name, bool if_exists = false,
|
|
7423
|
+
T *GetEntry(ClientContext &context, const string &schema_name, const string &name, bool if_exists = false,
|
|
7398
7424
|
QueryErrorContext error_context = QueryErrorContext());
|
|
7399
7425
|
|
|
7400
7426
|
//! Alter an existing entry in the catalog.
|
|
@@ -7405,30 +7431,43 @@ private:
|
|
|
7405
7431
|
atomic<idx_t> catalog_version;
|
|
7406
7432
|
|
|
7407
7433
|
private:
|
|
7434
|
+
//! A variation of GetEntry that returns an associated schema as well.
|
|
7435
|
+
CatalogEntryLookup LookupEntry(ClientContext &context, CatalogType type, const string &schema, const string &name,
|
|
7436
|
+
bool if_exists = false, QueryErrorContext error_context = QueryErrorContext());
|
|
7437
|
+
|
|
7438
|
+
//! Return an exception with did-you-mean suggestion.
|
|
7439
|
+
CatalogException CreateMissingEntryException(ClientContext &context, const string &entry_name, CatalogType type,
|
|
7440
|
+
const vector<SchemaCatalogEntry *> &schemas,
|
|
7441
|
+
QueryErrorContext error_context);
|
|
7442
|
+
|
|
7443
|
+
//! Return the close entry name, the distance and the belonging schema.
|
|
7444
|
+
SimilarCatalogEntry SimilarEntryInSchemas(ClientContext &context, const string &entry_name, CatalogType type,
|
|
7445
|
+
const vector<SchemaCatalogEntry *> &schemas);
|
|
7446
|
+
|
|
7408
7447
|
void DropSchema(ClientContext &context, DropInfo *info);
|
|
7409
7448
|
};
|
|
7410
7449
|
|
|
7411
7450
|
template <>
|
|
7412
|
-
TableCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
7413
|
-
QueryErrorContext error_context);
|
|
7451
|
+
TableCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
7452
|
+
bool if_exists, QueryErrorContext error_context);
|
|
7414
7453
|
template <>
|
|
7415
|
-
SequenceCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
7416
|
-
QueryErrorContext error_context);
|
|
7454
|
+
SequenceCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
7455
|
+
bool if_exists, QueryErrorContext error_context);
|
|
7417
7456
|
template <>
|
|
7418
|
-
TableFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
7457
|
+
TableFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
7419
7458
|
bool if_exists, QueryErrorContext error_context);
|
|
7420
7459
|
template <>
|
|
7421
|
-
CopyFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
7460
|
+
CopyFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
7422
7461
|
bool if_exists, QueryErrorContext error_context);
|
|
7423
7462
|
template <>
|
|
7424
|
-
PragmaFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
7463
|
+
PragmaFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
7425
7464
|
bool if_exists, QueryErrorContext error_context);
|
|
7426
7465
|
template <>
|
|
7427
|
-
AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
7466
|
+
AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
7428
7467
|
bool if_exists, QueryErrorContext error_context);
|
|
7429
7468
|
template <>
|
|
7430
|
-
CollateCatalogEntry *Catalog::GetEntry(ClientContext &context, string schema_name, const string &name,
|
|
7431
|
-
QueryErrorContext error_context);
|
|
7469
|
+
CollateCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name,
|
|
7470
|
+
bool if_exists, QueryErrorContext error_context);
|
|
7432
7471
|
|
|
7433
7472
|
} // namespace duckdb
|
|
7434
7473
|
|
|
@@ -9654,6 +9693,166 @@ private:
|
|
|
9654
9693
|
|
|
9655
9694
|
} // namespace duckdb
|
|
9656
9695
|
|
|
9696
|
+
//===----------------------------------------------------------------------===//
|
|
9697
|
+
// DuckDB
|
|
9698
|
+
//
|
|
9699
|
+
// duckdb/common/case_insensitive_map.hpp
|
|
9700
|
+
//
|
|
9701
|
+
//
|
|
9702
|
+
//===----------------------------------------------------------------------===//
|
|
9703
|
+
|
|
9704
|
+
|
|
9705
|
+
|
|
9706
|
+
|
|
9707
|
+
|
|
9708
|
+
|
|
9709
|
+
//===----------------------------------------------------------------------===//
|
|
9710
|
+
// DuckDB
|
|
9711
|
+
//
|
|
9712
|
+
// duckdb/common/string_util.hpp
|
|
9713
|
+
//
|
|
9714
|
+
//
|
|
9715
|
+
//===----------------------------------------------------------------------===//
|
|
9716
|
+
|
|
9717
|
+
|
|
9718
|
+
|
|
9719
|
+
|
|
9720
|
+
|
|
9721
|
+
|
|
9722
|
+
|
|
9723
|
+
namespace duckdb {
|
|
9724
|
+
/**
|
|
9725
|
+
* String Utility Functions
|
|
9726
|
+
* Note that these are not the most efficient implementations (i.e., they copy
|
|
9727
|
+
* memory) and therefore they should only be used for debug messages and other
|
|
9728
|
+
* such things.
|
|
9729
|
+
*/
|
|
9730
|
+
class StringUtil {
|
|
9731
|
+
public:
|
|
9732
|
+
static bool CharacterIsSpace(char c) {
|
|
9733
|
+
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
|
|
9734
|
+
}
|
|
9735
|
+
static bool CharacterIsNewline(char c) {
|
|
9736
|
+
return c == '\n' || c == '\r';
|
|
9737
|
+
}
|
|
9738
|
+
static bool CharacterIsDigit(char c) {
|
|
9739
|
+
return c >= '0' && c <= '9';
|
|
9740
|
+
}
|
|
9741
|
+
static char CharacterToLower(char c) {
|
|
9742
|
+
if (c >= 'A' && c <= 'Z') {
|
|
9743
|
+
return c - ('A' - 'a');
|
|
9744
|
+
}
|
|
9745
|
+
return c;
|
|
9746
|
+
}
|
|
9747
|
+
|
|
9748
|
+
//! Returns true if the needle string exists in the haystack
|
|
9749
|
+
static bool Contains(const string &haystack, const string &needle);
|
|
9750
|
+
|
|
9751
|
+
//! Returns true if the target string starts with the given prefix
|
|
9752
|
+
static bool StartsWith(string str, string prefix);
|
|
9753
|
+
|
|
9754
|
+
//! Returns true if the target string <b>ends</b> with the given suffix.
|
|
9755
|
+
static bool EndsWith(const string &str, const string &suffix);
|
|
9756
|
+
|
|
9757
|
+
//! Repeat a string multiple times
|
|
9758
|
+
static string Repeat(const string &str, const idx_t n);
|
|
9759
|
+
|
|
9760
|
+
//! Split the input string based on newline char
|
|
9761
|
+
static vector<string> Split(const string &str, char delimiter);
|
|
9762
|
+
|
|
9763
|
+
//! Split the input string allong a quote. Note that any escaping is NOT supported.
|
|
9764
|
+
static vector<string> SplitWithQuote(const string &str, char delimiter = ',', char quote = '"');
|
|
9765
|
+
|
|
9766
|
+
//! Join multiple strings into one string. Components are concatenated by the given separator
|
|
9767
|
+
static string Join(const vector<string> &input, const string &separator);
|
|
9768
|
+
|
|
9769
|
+
//! Join multiple items of container with given size, transformed to string
|
|
9770
|
+
//! using function, into one string using the given separator
|
|
9771
|
+
template <typename C, typename S, typename Func>
|
|
9772
|
+
static string Join(const C &input, S count, const string &separator, Func f) {
|
|
9773
|
+
// The result
|
|
9774
|
+
std::string result;
|
|
9775
|
+
|
|
9776
|
+
// If the input isn't empty, append the first element. We do this so we
|
|
9777
|
+
// don't need to introduce an if into the loop.
|
|
9778
|
+
if (count > 0) {
|
|
9779
|
+
result += f(input[0]);
|
|
9780
|
+
}
|
|
9781
|
+
|
|
9782
|
+
// Append the remaining input components, after the first
|
|
9783
|
+
for (size_t i = 1; i < count; i++) {
|
|
9784
|
+
result += separator + f(input[i]);
|
|
9785
|
+
}
|
|
9786
|
+
|
|
9787
|
+
return result;
|
|
9788
|
+
}
|
|
9789
|
+
|
|
9790
|
+
//! Return a string that formats the give number of bytes
|
|
9791
|
+
static string BytesToHumanReadableString(idx_t bytes);
|
|
9792
|
+
|
|
9793
|
+
//! Convert a string to uppercase
|
|
9794
|
+
static string Upper(const string &str);
|
|
9795
|
+
|
|
9796
|
+
//! Convert a string to lowercase
|
|
9797
|
+
static string Lower(const string &str);
|
|
9798
|
+
|
|
9799
|
+
//! Format a string using printf semantics
|
|
9800
|
+
template <typename... Args>
|
|
9801
|
+
static string Format(const string fmt_str, Args... params) {
|
|
9802
|
+
return Exception::ConstructMessage(fmt_str, params...);
|
|
9803
|
+
}
|
|
9804
|
+
|
|
9805
|
+
//! Split the input string into a vector of strings based on the split string
|
|
9806
|
+
static vector<string> Split(const string &input, const string &split);
|
|
9807
|
+
|
|
9808
|
+
//! Remove the whitespace char in the left end of the string
|
|
9809
|
+
static void LTrim(string &str);
|
|
9810
|
+
//! Remove the whitespace char in the right end of the string
|
|
9811
|
+
static void RTrim(string &str);
|
|
9812
|
+
//! Remove the whitespace char in the left and right end of the string
|
|
9813
|
+
static void Trim(string &str);
|
|
9814
|
+
|
|
9815
|
+
static string Replace(string source, const string &from, const string &to);
|
|
9816
|
+
|
|
9817
|
+
//! Get the levenshtein distance from two strings
|
|
9818
|
+
static idx_t LevenshteinDistance(const string &s1, const string &s2);
|
|
9819
|
+
|
|
9820
|
+
//! Get the top-n strings (sorted by the given score distance) from a set of scores.
|
|
9821
|
+
//! At least one entry is returned (if there is one).
|
|
9822
|
+
//! Strings are only returned if they have a score less than the threshold.
|
|
9823
|
+
static vector<string> TopNStrings(vector<std::pair<string, idx_t>> scores, idx_t n = 5, idx_t threshold = 5);
|
|
9824
|
+
//! Computes the levenshtein distance of each string in strings, and compares it to target, then returns TopNStrings
|
|
9825
|
+
//! with the given params.
|
|
9826
|
+
static vector<string> TopNLevenshtein(const vector<string> &strings, const string &target, idx_t n = 5,
|
|
9827
|
+
idx_t threshold = 5);
|
|
9828
|
+
static string CandidatesMessage(const vector<string> &candidates, const string &candidate = "Candidate bindings");
|
|
9829
|
+
};
|
|
9830
|
+
} // namespace duckdb
|
|
9831
|
+
|
|
9832
|
+
|
|
9833
|
+
namespace duckdb {
|
|
9834
|
+
|
|
9835
|
+
struct CaseInsensitiveStringHashFunction {
|
|
9836
|
+
uint64_t operator()(const string &str) const {
|
|
9837
|
+
std::hash<string> hasher;
|
|
9838
|
+
return hasher(StringUtil::Lower(str));
|
|
9839
|
+
}
|
|
9840
|
+
};
|
|
9841
|
+
|
|
9842
|
+
struct CaseInsensitiveStringEquality {
|
|
9843
|
+
bool operator()(const string &a, const string &b) const {
|
|
9844
|
+
return StringUtil::Lower(a) == StringUtil::Lower(b);
|
|
9845
|
+
}
|
|
9846
|
+
};
|
|
9847
|
+
|
|
9848
|
+
template <typename T>
|
|
9849
|
+
using case_insensitive_map_t =
|
|
9850
|
+
unordered_map<string, T, CaseInsensitiveStringHashFunction, CaseInsensitiveStringEquality>;
|
|
9851
|
+
|
|
9852
|
+
using case_insensitive_set_t = unordered_set<string, CaseInsensitiveStringHashFunction, CaseInsensitiveStringEquality>;
|
|
9853
|
+
|
|
9854
|
+
} // namespace duckdb
|
|
9855
|
+
|
|
9657
9856
|
|
|
9658
9857
|
|
|
9659
9858
|
|
|
@@ -9846,7 +10045,7 @@ public:
|
|
|
9846
10045
|
//! Whether or not object cache is used
|
|
9847
10046
|
bool object_cache_enable = false;
|
|
9848
10047
|
//! Database configuration variables as controlled by SET
|
|
9849
|
-
|
|
10048
|
+
case_insensitive_map_t<Value> set_variables;
|
|
9850
10049
|
//! Force checkpoint when CHECKPOINT is called or on shutdown, even if no changes have been made
|
|
9851
10050
|
bool force_checkpoint = false;
|
|
9852
10051
|
//! Run a checkpoint on successful shutdown and delete the WAL, to leave only a single database file behind
|
|
@@ -11747,161 +11946,22 @@ public:
|
|
|
11747
11946
|
} // namespace duckdb
|
|
11748
11947
|
|
|
11749
11948
|
|
|
11750
|
-
//===----------------------------------------------------------------------===//
|
|
11751
|
-
// DuckDB
|
|
11752
|
-
//
|
|
11753
|
-
// duckdb/common/case_insensitive_map.hpp
|
|
11754
|
-
//
|
|
11755
|
-
//
|
|
11756
|
-
//===----------------------------------------------------------------------===//
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
|
|
11760
|
-
|
|
11761
|
-
|
|
11762
11949
|
|
|
11763
11950
|
//===----------------------------------------------------------------------===//
|
|
11764
11951
|
// DuckDB
|
|
11765
11952
|
//
|
|
11766
|
-
// duckdb/common/
|
|
11953
|
+
// duckdb/common/pair.hpp
|
|
11767
11954
|
//
|
|
11768
11955
|
//
|
|
11769
11956
|
//===----------------------------------------------------------------------===//
|
|
11770
11957
|
|
|
11771
11958
|
|
|
11772
11959
|
|
|
11773
|
-
|
|
11774
|
-
|
|
11775
|
-
|
|
11776
|
-
|
|
11777
|
-
namespace duckdb {
|
|
11778
|
-
/**
|
|
11779
|
-
* String Utility Functions
|
|
11780
|
-
* Note that these are not the most efficient implementations (i.e., they copy
|
|
11781
|
-
* memory) and therefore they should only be used for debug messages and other
|
|
11782
|
-
* such things.
|
|
11783
|
-
*/
|
|
11784
|
-
class StringUtil {
|
|
11785
|
-
public:
|
|
11786
|
-
static bool CharacterIsSpace(char c) {
|
|
11787
|
-
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
|
|
11788
|
-
}
|
|
11789
|
-
static bool CharacterIsNewline(char c) {
|
|
11790
|
-
return c == '\n' || c == '\r';
|
|
11791
|
-
}
|
|
11792
|
-
static bool CharacterIsDigit(char c) {
|
|
11793
|
-
return c >= '0' && c <= '9';
|
|
11794
|
-
}
|
|
11795
|
-
static char CharacterToLower(char c) {
|
|
11796
|
-
if (c >= 'A' && c <= 'Z') {
|
|
11797
|
-
return c - ('A' - 'a');
|
|
11798
|
-
}
|
|
11799
|
-
return c;
|
|
11800
|
-
}
|
|
11801
|
-
|
|
11802
|
-
//! Returns true if the needle string exists in the haystack
|
|
11803
|
-
static bool Contains(const string &haystack, const string &needle);
|
|
11804
|
-
|
|
11805
|
-
//! Returns true if the target string starts with the given prefix
|
|
11806
|
-
static bool StartsWith(string str, string prefix);
|
|
11807
|
-
|
|
11808
|
-
//! Returns true if the target string <b>ends</b> with the given suffix.
|
|
11809
|
-
static bool EndsWith(const string &str, const string &suffix);
|
|
11810
|
-
|
|
11811
|
-
//! Repeat a string multiple times
|
|
11812
|
-
static string Repeat(const string &str, const idx_t n);
|
|
11813
|
-
|
|
11814
|
-
//! Split the input string based on newline char
|
|
11815
|
-
static vector<string> Split(const string &str, char delimiter);
|
|
11816
|
-
|
|
11817
|
-
//! Join multiple strings into one string. Components are concatenated by the given separator
|
|
11818
|
-
static string Join(const vector<string> &input, const string &separator);
|
|
11819
|
-
|
|
11820
|
-
//! Join multiple items of container with given size, transformed to string
|
|
11821
|
-
//! using function, into one string using the given separator
|
|
11822
|
-
template <typename C, typename S, typename Func>
|
|
11823
|
-
static string Join(const C &input, S count, const string &separator, Func f) {
|
|
11824
|
-
// The result
|
|
11825
|
-
std::string result;
|
|
11826
|
-
|
|
11827
|
-
// If the input isn't empty, append the first element. We do this so we
|
|
11828
|
-
// don't need to introduce an if into the loop.
|
|
11829
|
-
if (count > 0) {
|
|
11830
|
-
result += f(input[0]);
|
|
11831
|
-
}
|
|
11832
|
-
|
|
11833
|
-
// Append the remaining input components, after the first
|
|
11834
|
-
for (size_t i = 1; i < count; i++) {
|
|
11835
|
-
result += separator + f(input[i]);
|
|
11836
|
-
}
|
|
11837
|
-
|
|
11838
|
-
return result;
|
|
11839
|
-
}
|
|
11840
|
-
|
|
11841
|
-
//! Return a string that formats the give number of bytes
|
|
11842
|
-
static string BytesToHumanReadableString(idx_t bytes);
|
|
11843
|
-
|
|
11844
|
-
//! Convert a string to uppercase
|
|
11845
|
-
static string Upper(const string &str);
|
|
11846
|
-
|
|
11847
|
-
//! Convert a string to lowercase
|
|
11848
|
-
static string Lower(const string &str);
|
|
11849
|
-
|
|
11850
|
-
//! Format a string using printf semantics
|
|
11851
|
-
template <typename... Args>
|
|
11852
|
-
static string Format(const string fmt_str, Args... params) {
|
|
11853
|
-
return Exception::ConstructMessage(fmt_str, params...);
|
|
11854
|
-
}
|
|
11855
|
-
|
|
11856
|
-
//! Split the input string into a vector of strings based on the split string
|
|
11857
|
-
static vector<string> Split(const string &input, const string &split);
|
|
11858
|
-
|
|
11859
|
-
//! Remove the whitespace char in the left end of the string
|
|
11860
|
-
static void LTrim(string &str);
|
|
11861
|
-
//! Remove the whitespace char in the right end of the string
|
|
11862
|
-
static void RTrim(string &str);
|
|
11863
|
-
//! Remove the whitespace char in the left and right end of the string
|
|
11864
|
-
static void Trim(string &str);
|
|
11865
|
-
|
|
11866
|
-
static string Replace(string source, const string &from, const string &to);
|
|
11867
|
-
|
|
11868
|
-
//! Get the levenshtein distance from two strings
|
|
11869
|
-
static idx_t LevenshteinDistance(const string &s1, const string &s2);
|
|
11870
|
-
|
|
11871
|
-
//! Get the top-n strings (sorted by the given score distance) from a set of scores.
|
|
11872
|
-
//! At least one entry is returned (if there is one).
|
|
11873
|
-
//! Strings are only returned if they have a score less than the threshold.
|
|
11874
|
-
static vector<string> TopNStrings(vector<std::pair<string, idx_t>> scores, idx_t n = 5, idx_t threshold = 5);
|
|
11875
|
-
//! Computes the levenshtein distance of each string in strings, and compares it to target, then returns TopNStrings
|
|
11876
|
-
//! with the given params.
|
|
11877
|
-
static vector<string> TopNLevenshtein(const vector<string> &strings, const string &target, idx_t n = 5,
|
|
11878
|
-
idx_t threshold = 5);
|
|
11879
|
-
static string CandidatesMessage(const vector<string> &candidates, const string &candidate = "Candidate bindings");
|
|
11880
|
-
};
|
|
11881
|
-
} // namespace duckdb
|
|
11882
|
-
|
|
11960
|
+
#include <utility>
|
|
11883
11961
|
|
|
11884
11962
|
namespace duckdb {
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
uint64_t operator()(const string &str) const {
|
|
11888
|
-
std::hash<string> hasher;
|
|
11889
|
-
return hasher(StringUtil::Lower(str));
|
|
11890
|
-
}
|
|
11891
|
-
};
|
|
11892
|
-
|
|
11893
|
-
struct CaseInsensitiveStringEquality {
|
|
11894
|
-
bool operator()(const string &a, const string &b) const {
|
|
11895
|
-
return StringUtil::Lower(a) == StringUtil::Lower(b);
|
|
11896
|
-
}
|
|
11897
|
-
};
|
|
11898
|
-
|
|
11899
|
-
template <typename T>
|
|
11900
|
-
using case_insensitive_map_t =
|
|
11901
|
-
unordered_map<string, T, CaseInsensitiveStringHashFunction, CaseInsensitiveStringEquality>;
|
|
11902
|
-
|
|
11903
|
-
using case_insensitive_set_t = unordered_set<string, CaseInsensitiveStringHashFunction, CaseInsensitiveStringEquality>;
|
|
11904
|
-
|
|
11963
|
+
using std::make_pair;
|
|
11964
|
+
using std::pair;
|
|
11905
11965
|
} // namespace duckdb
|
|
11906
11966
|
|
|
11907
11967
|
|
|
@@ -11950,8 +12010,8 @@ public:
|
|
|
11950
12010
|
CatalogEntry *GetEntry(ClientContext &context, const string &name);
|
|
11951
12011
|
|
|
11952
12012
|
//! Gets the entry that is most similar to the given name (i.e. smallest levenshtein distance), or empty string if
|
|
11953
|
-
//! none is found
|
|
11954
|
-
string SimilarEntry(ClientContext &context, const string &name);
|
|
12013
|
+
//! none is found. The returned pair consists of the entry name and the distance (smaller means closer).
|
|
12014
|
+
pair<string, idx_t> SimilarEntry(ClientContext &context, const string &name);
|
|
11955
12015
|
|
|
11956
12016
|
//! Rollback <entry> to be the currently valid entry for a certain catalog
|
|
11957
12017
|
//! entry
|
|
@@ -12059,10 +12119,6 @@ private:
|
|
|
12059
12119
|
CatalogSet collations;
|
|
12060
12120
|
|
|
12061
12121
|
public:
|
|
12062
|
-
//! Gets a catalog entry from the given catalog set matching the given name
|
|
12063
|
-
CatalogEntry *GetEntry(ClientContext &context, CatalogType type, const string &name, bool if_exists,
|
|
12064
|
-
QueryErrorContext error_context = QueryErrorContext());
|
|
12065
|
-
|
|
12066
12122
|
//! Scan the specified catalog set, invoking the callback method for every entry
|
|
12067
12123
|
void Scan(ClientContext &context, CatalogType type, const std::function<void(CatalogEntry *)> &callback);
|
|
12068
12124
|
//! Scan the specified catalog set, invoking the callback method for every committed entry
|
|
@@ -12114,6 +12170,7 @@ private:
|
|
|
12114
12170
|
} // namespace duckdb
|
|
12115
12171
|
|
|
12116
12172
|
|
|
12173
|
+
|
|
12117
12174
|
//===----------------------------------------------------------------------===//
|
|
12118
12175
|
// DuckDB
|
|
12119
12176
|
//
|
|
@@ -12147,22 +12204,6 @@ enum class ExplainOutputType : uint8_t { ALL = 0, OPTIMIZED_ONLY = 1, PHYSICAL_O
|
|
|
12147
12204
|
|
|
12148
12205
|
} // namespace duckdb
|
|
12149
12206
|
|
|
12150
|
-
//===----------------------------------------------------------------------===//
|
|
12151
|
-
// DuckDB
|
|
12152
|
-
//
|
|
12153
|
-
// duckdb/common/pair.hpp
|
|
12154
|
-
//
|
|
12155
|
-
//
|
|
12156
|
-
//===----------------------------------------------------------------------===//
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
#include <utility>
|
|
12161
|
-
|
|
12162
|
-
namespace duckdb {
|
|
12163
|
-
using std::make_pair;
|
|
12164
|
-
using std::pair;
|
|
12165
|
-
} // namespace duckdb
|
|
12166
12207
|
|
|
12167
12208
|
//===----------------------------------------------------------------------===//
|
|
12168
12209
|
// DuckDB
|
|
@@ -13083,6 +13124,7 @@ private:
|
|
|
13083
13124
|
namespace duckdb {
|
|
13084
13125
|
class Appender;
|
|
13085
13126
|
class Catalog;
|
|
13127
|
+
class CatalogSearchPath;
|
|
13086
13128
|
class ChunkCollection;
|
|
13087
13129
|
class DatabaseInstance;
|
|
13088
13130
|
class FileOpener;
|
|
@@ -13132,7 +13174,7 @@ public:
|
|
|
13132
13174
|
unique_ptr<SchemaCatalogEntry> temporary_objects;
|
|
13133
13175
|
unordered_map<string, shared_ptr<PreparedStatementData>> prepared_statements;
|
|
13134
13176
|
|
|
13135
|
-
|
|
13177
|
+
case_insensitive_map_t<Value> set_variables;
|
|
13136
13178
|
|
|
13137
13179
|
// Whether or not aggressive query verification is enabled
|
|
13138
13180
|
bool query_verification_enabled = false;
|
|
@@ -13154,8 +13196,7 @@ public:
|
|
|
13154
13196
|
//! The random generator used by random(). Its seed value can be set by setseed().
|
|
13155
13197
|
std::mt19937 random_engine;
|
|
13156
13198
|
|
|
13157
|
-
|
|
13158
|
-
vector<string> catalog_search_path = {TEMP_SCHEMA, DEFAULT_SCHEMA, "pg_catalog"};
|
|
13199
|
+
const unique_ptr<CatalogSearchPath> catalog_search_path;
|
|
13159
13200
|
|
|
13160
13201
|
unique_ptr<FileOpener> file_opener;
|
|
13161
13202
|
|
|
@@ -13381,7 +13422,7 @@ public:
|
|
|
13381
13422
|
namespace duckdb {
|
|
13382
13423
|
|
|
13383
13424
|
struct CreateFunctionInfo : public CreateInfo {
|
|
13384
|
-
explicit CreateFunctionInfo(CatalogType type) : CreateInfo(type) {
|
|
13425
|
+
explicit CreateFunctionInfo(CatalogType type, string schema = DEFAULT_SCHEMA) : CreateInfo(type, schema) {
|
|
13385
13426
|
D_ASSERT(type == CatalogType::SCALAR_FUNCTION_ENTRY || type == CatalogType::AGGREGATE_FUNCTION_ENTRY ||
|
|
13386
13427
|
type == CatalogType::TABLE_FUNCTION_ENTRY || type == CatalogType::PRAGMA_FUNCTION_ENTRY ||
|
|
13387
13428
|
type == CatalogType::MACRO_ENTRY);
|