Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 32 additions & 27 deletions src/duckdb/src/catalog/catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ CatalogTransaction Catalog::GetCatalogTransaction(ClientContext &context) {
return CatalogTransaction(*this, context);
}

SchemaCatalogEntry &Catalog::GetEntrySchema(CatalogTransaction transaction, const QualifiedName &name) {
auto &path = name.Path();
if (path.size() <= 3) {
return GetSchema(transaction, name.Schema());
}
// nested entry ([catalog, schema_path..., name]): navigate the (nested) schema path
vector<Identifier> schema_path(path.begin() + 1, path.end() - 1);
return *GetSchema(transaction, schema_path, OnEntryNotFound::THROW_EXCEPTION);
}

//===--------------------------------------------------------------------===//
// Table
//===--------------------------------------------------------------------===//
Expand All @@ -149,24 +159,15 @@ optional_ptr<CatalogEntry> Catalog::CreateTable(CatalogTransaction transaction,
}

optional_ptr<CatalogEntry> Catalog::CreateTable(CatalogTransaction transaction, BoundCreateTableInfo &info) {
auto &qname = info.base->GetQualifiedName();
auto &path = qname.Path();
optional_ptr<SchemaCatalogEntry> schema;
if (path.size() > 3) {
// nested table ([catalog, schema_path..., name]): navigate the (nested) schema path
vector<Identifier> schema_path(path.begin() + 1, path.end() - 1);
schema = GetSchema(transaction, schema_path, OnEntryNotFound::THROW_EXCEPTION);
} else {
schema = GetSchema(transaction, qname.Schema());
}
return CreateTable(transaction, *schema, info);
auto &schema = GetEntrySchema(transaction, info.base->GetQualifiedName());
return CreateTable(transaction, schema, info);
}

//===--------------------------------------------------------------------===//
// View
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreateView(CatalogTransaction transaction, CreateViewInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return CreateView(transaction, schema, info);
}

Expand All @@ -183,7 +184,7 @@ optional_ptr<CatalogEntry> Catalog::CreateView(CatalogTransaction transaction, S
// Sequence
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreateSequence(CatalogTransaction transaction, CreateSequenceInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return CreateSequence(transaction, schema, info);
}

Expand All @@ -200,7 +201,7 @@ optional_ptr<CatalogEntry> Catalog::CreateSequence(CatalogTransaction transactio
// Type
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreateType(CatalogTransaction transaction, CreateTypeInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return CreateType(transaction, schema, info);
}

Expand All @@ -217,7 +218,7 @@ optional_ptr<CatalogEntry> Catalog::CreateType(CatalogTransaction transaction, S
// Table Function
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return CreateTableFunction(transaction, schema, info);
}

Expand All @@ -239,7 +240,7 @@ optional_ptr<CatalogEntry> Catalog::CreateTableFunction(ClientContext &context,
// Copy Function
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return CreateCopyFunction(transaction, schema, info);
}

Expand All @@ -257,7 +258,7 @@ optional_ptr<CatalogEntry> Catalog::CreateCopyFunction(CatalogTransaction transa
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreatePragmaFunction(CatalogTransaction transaction,
CreatePragmaFunctionInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return CreatePragmaFunction(transaction, schema, info);
}

Expand All @@ -274,7 +275,7 @@ optional_ptr<CatalogEntry> Catalog::CreatePragmaFunction(CatalogTransaction tran
// Function
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreateFunction(CatalogTransaction transaction, CreateFunctionInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return CreateFunction(transaction, schema, info);
}

Expand All @@ -296,7 +297,7 @@ optional_ptr<CatalogEntry> Catalog::AddFunction(ClientContext &context, CreateFu
// Collation
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreateCollation(CatalogTransaction transaction, CreateCollationInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return CreateCollation(transaction, schema, info);
}

Expand All @@ -314,7 +315,7 @@ optional_ptr<CatalogEntry> Catalog::CreateCollation(CatalogTransaction transacti
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreateCoordinateSystem(CatalogTransaction transaction,
CreateCoordinateSystemInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return CreateCoordinateSystem(transaction, schema, info);
}

Expand All @@ -331,7 +332,7 @@ optional_ptr<CatalogEntry> Catalog::CreateCoordinateSystem(CatalogTransaction tr
// Index
//===--------------------------------------------------------------------===//
optional_ptr<CatalogEntry> Catalog::CreateIndex(CatalogTransaction transaction, CreateIndexInfo &info) {
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
auto &table = schema.GetEntry(transaction, CatalogType::TABLE_ENTRY, info.table)->Cast<TableCatalogEntry>();
return schema.CreateIndex(transaction, info, table);
}
Expand Down Expand Up @@ -1109,11 +1110,15 @@ CatalogEntryLookup Catalog::TryLookupEntry(CatalogEntryRetriever &retriever, con
}

// If we have a specific schema name and no schemas were found, the schema doesn't exist.
// Throw an error about the schema instead of the table
if (schemas.empty() && !lookups.empty() && lookup_info.GetCatalogType() == CatalogType::TABLE_ENTRY) {
// Throw an error about the schema instead of the entry. A nested schema path is unambiguous, so we report it
// for every entry type; for a single schema level we only do so for tables (the message would otherwise hide
// the search-path suggestions that are useful for e.g. functions).
auto &lookup_path =
lookups.empty() ? lookup_info.GetQualifiedName().Path() : lookups[0].lookup_info.GetQualifiedName().Path();
bool report_missing_schema = lookup_info.GetCatalogType() == CatalogType::TABLE_ENTRY || lookup_path.size() > 3;
if (schemas.empty() && !lookups.empty() && report_missing_schema) {
// the schema qualification is everything between the catalog and the entry name - for a nested schema this
// is more than one component
auto &lookup_path = lookups[0].lookup_info.GetQualifiedName().Path();
vector<string> schema_components;
for (idx_t i = lookup_path.size() > 2 ? 1 : 0; i + 1 < lookup_path.size(); i++) {
if (!lookup_path[i].empty()) {
Expand All @@ -1125,8 +1130,8 @@ CatalogEntryLookup Catalog::TryLookupEntry(CatalogEntryRetriever &retriever, con
string relation_name = schema_name + "." + lookup_info.GetEntryName();
auto except =
CatalogException(lookup_info.GetErrorContext(),
"Table with name \"%s\" does not exist because schema \"%s\" does not exist.",
relation_name, schema_name);
"%s with name \"%s\" does not exist because schema \"%s\" does not exist.",
CatalogTypeToString(lookup_info.GetCatalogType()), relation_name, schema_name);
return {nullptr, nullptr, ErrorData(except)};
}
}
Expand Down Expand Up @@ -1430,7 +1435,7 @@ void Catalog::Alter(CatalogTransaction transaction, AlterInfo &info) {
return lookup.schema->Alter(transaction, info);
}
D_ASSERT(info.if_not_found == OnEntryNotFound::THROW_EXCEPTION);
auto &schema = GetSchema(transaction, info.GetQualifiedName().Schema());
auto &schema = GetEntrySchema(transaction, info.GetQualifiedName());
return schema.Alter(transaction, info);
}

Expand Down
5 changes: 2 additions & 3 deletions src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ namespace duckdb {
static void FindForeignKeyInformation(TableCatalogEntry &table, AlterForeignKeyType alter_fk_type,
vector<unique_ptr<AlterForeignKeyInfo>> &fk_arrays) {
auto &constraints = table.GetConstraints();
auto &catalog = table.ParentCatalog();
auto &name = table.name;
for (idx_t i = 0; i < constraints.size(); i++) {
auto &cond = constraints[i];
Expand All @@ -57,8 +56,8 @@ static void FindForeignKeyInformation(TableCatalogEntry &table, AlterForeignKeyT
}
auto &fk = cond->Cast<ForeignKeyConstraint>();
if (fk.info.type == ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE) {
AlterEntryData alter_data(QualifiedName(catalog.GetName(), fk.info.schema, fk.info.table),
OnEntryNotFound::THROW_EXCEPTION);
// the referenced table lives in the same (possibly nested) schema as this table
AlterEntryData alter_data(table.schema.GetQualifiedName(fk.info.table), OnEntryNotFound::THROW_EXCEPTION);
fk_arrays.push_back(make_uniq<AlterForeignKeyInfo>(std::move(alter_data), name, fk.pk_columns,
fk.fk_columns, fk.info.pk_keys, fk.info.fk_keys,
alter_fk_type));
Expand Down
5 changes: 4 additions & 1 deletion src/duckdb/src/catalog/catalog_entry/index_catalog_entry.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "duckdb/catalog/catalog_entry/index_catalog_entry.hpp"

#include "duckdb/catalog/catalog_entry/schema_catalog_entry.hpp"

namespace duckdb {

IndexCatalogEntry::IndexCatalogEntry(Catalog &catalog, SchemaCatalogEntry &schema, CreateIndexInfo &info)
Expand All @@ -21,7 +23,7 @@ IndexCatalogEntry::IndexCatalogEntry(Catalog &catalog, SchemaCatalogEntry &schem

unique_ptr<CreateInfo> IndexCatalogEntry::GetInfo() const {
auto result = make_uniq<CreateIndexInfo>();
result->SetQualifiedName(QualifiedName({GetSchemaName()}, name));
result->SetQualifiedName(schema.GetQualifiedName(name));
result->table = GetTableName();

result->temporary = temporary;
Expand All @@ -47,6 +49,7 @@ unique_ptr<CreateInfo> IndexCatalogEntry::GetInfo() const {

string IndexCatalogEntry::ToSQL() const {
auto info = GetInfo();
info->StripCatalogQualification();
return info->ToString();
}

Expand Down
3 changes: 2 additions & 1 deletion src/duckdb/src/catalog/catalog_entry/macro_catalog_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ unique_ptr<CatalogEntry> TableMacroCatalogEntry::Copy(ClientContext &context) co

unique_ptr<CreateInfo> MacroCatalogEntry::GetInfo() const {
auto info = make_uniq<CreateMacroInfo>(type);
info->SetQualifiedName(QualifiedName(catalog.GetName(), schema.name, name));
info->SetQualifiedName(schema.GetQualifiedName(name));
for (auto &function : macros) {
info->macros.push_back(function->Copy());
}
Expand All @@ -54,6 +54,7 @@ unique_ptr<CreateInfo> MacroCatalogEntry::GetInfo() const {

string MacroCatalogEntry::ToSQL() const {
auto create_info = GetInfo();
create_info->StripCatalogQualification();
return create_info->ToString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ unique_ptr<CreateInfo> SchemaCatalogEntry::GetInfo() const {

string SchemaCatalogEntry::ToSQL() const {
auto create_schema_info = GetInfo();
create_schema_info->StripCatalogQualification();
return create_schema_info->ToString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ unique_ptr<CreateInfo> SequenceCatalogEntry::GetInfo() const {
auto seq_data = GetData();

auto result = make_uniq<CreateSequenceInfo>();
result->SetQualifiedName(QualifiedName(catalog.GetName(), schema.name, name));
result->SetQualifiedName(schema.GetQualifiedName(name));
result->usage_count = seq_data.usage_count;
result->increment = seq_data.increment;
result->min_value = seq_data.min_value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ string TableCatalogEntry::ColumnNamesToSQL(const ColumnList &columns) {

string TableCatalogEntry::ToSQL() const {
auto create_info = GetInfo();
create_info->StripCatalogQualification();
return create_info->ToString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ unique_ptr<CatalogEntry> TriggerCatalogEntry::Copy(ClientContext &context) const

unique_ptr<CreateInfo> TriggerCatalogEntry::GetInfo() const {
auto result = make_uniq<CreateTriggerInfo>();
result->SetQualifiedName(QualifiedName(catalog.GetName(), schema.name, name));
result->SetQualifiedName(schema.GetQualifiedName(name));
result->base_table = unique_ptr_cast<TableRef, BaseTableRef>(base_table->Copy());
result->timing = timing;
result->event_type = event_type;
Expand Down Expand Up @@ -60,9 +60,7 @@ string TriggerCatalogEntry::ToSQL() const {
}
}
ss << " ON ";
ss << QualifiedName(base_table->GetQualifiedName().Catalog(), base_table->GetQualifiedName().Schema(),
base_table->Table())
.ToString(QualifiedNameToStringMode::HIDE_DEFAULT_SCHEMA);
ss << base_table->GetQualifiedName().ToString(QualifiedNameToStringMode::HIDE_DEFAULT_SCHEMA);
if (!referencing_new_table.empty() || !referencing_old_table.empty()) {
ss << " REFERENCING";
if (!referencing_new_table.empty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ unique_ptr<CatalogEntry> TypeCatalogEntry::Copy(ClientContext &context) const {

unique_ptr<CreateInfo> TypeCatalogEntry::GetInfo() const {
auto result = make_uniq<CreateTypeInfo>();
result->SetQualifiedName(QualifiedName(catalog.GetName(), schema.name, name));
result->SetQualifiedName(schema.GetQualifiedName(name));
result->type = user_type;
result->extension_name = extension_name;
result->dependencies = dependencies;
Expand Down
3 changes: 2 additions & 1 deletion src/duckdb/src/catalog/catalog_entry/view_catalog_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ ViewCatalogEntry::ViewCatalogEntry(Catalog &catalog, SchemaCatalogEntry &schema,

unique_ptr<CreateInfo> ViewCatalogEntry::GetInfo() const {
auto result = make_uniq<CreateViewInfo>();
result->SetQualifiedName(QualifiedName({schema.name}, name));
result->SetQualifiedName(schema.GetQualifiedName(name));
result->sql = sql;
result->query = query ? unique_ptr_cast<SQLStatement, SelectStatement>(query->Copy()) : nullptr;
result->aliases = aliases;
Expand Down Expand Up @@ -197,6 +197,7 @@ string ViewCatalogEntry::ToSQL() const {
return sql;
}
auto info = GetInfo();
info->StripCatalogQualification();
auto result = info->ToString();
return result;
}
Expand Down
9 changes: 9 additions & 0 deletions src/duckdb/src/catalog/catalog_search_path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ void CatalogSearchPath::Set(vector<CatalogSearchEntry> new_paths, CatalogSetPath
}
}
}
if (!path.GetCatalog().empty()) {
// "a.b" can also name a nested schema - give a clearer error in that case
vector<Identifier> nested_path {path.GetCatalog(), path.GetSchema()};
if (Catalog::GetSchema(context, Identifier(), nested_path, OnEntryNotFound::RETURN_NULL)) {
throw NotImplementedException("%s: \"%s\" is a nested schema - nested schemas cannot be used in the "
"search path",
GetSetName(set_type), path.ToString());
}
}
throw CatalogException("%s: No catalog + schema named \"%s\" found.", GetSetName(set_type), path.ToString());
}
if (set_type == CatalogSetPathType::SET_SCHEMA) {
Expand Down
3 changes: 2 additions & 1 deletion src/duckdb/src/common/exception/catalog_exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ CatalogException CatalogException::MissingEntry(const EntryLookupInfo &lookup_in
}
string version_info;
if (at_clause) {
version_info += " at " + StringUtil::Lower(at_clause->Unit()) + " " + at_clause->GetValue().ToString();
version_info +=
" at " + StringUtil::Lower(at_clause->Unit().GetIdentifierName()) + " " + at_clause->GetValue().ToString();
}

auto extra_info = Exception::InitializeExtraInfo("MISSING_ENTRY", context.query_location);
Expand Down
8 changes: 6 additions & 2 deletions src/duckdb/src/common/hive_partitioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,18 @@ std::map<string, string> HivePartitioning::Parse(const string &filename) {

Value HivePartitioning::GetValue(ClientContext &context, const string &key, const string &str_val,
const LogicalType &type) {
// Handle nulls
if (IsNull(str_val)) {
// On SQLNULL, DuckDB writes "__HIVE_DEFAULT_PARTITION__", instead of string version "NULL".
if (str_val == "__HIVE_DEFAULT_PARTITION__") {
return Value(type);
}
if (type.id() == LogicalTypeId::VARCHAR) {
// for string values we can directly return the type
return Value(Unescape(str_val));
}
// Handle Hive NULL markers for non-string partition types
if (StringUtil::CIEquals(str_val, "NULL")) {
return Value(type);
}
if (str_val.empty()) {
// empty strings are NULL for non-string types
return Value(type);
Expand Down
14 changes: 6 additions & 8 deletions src/duckdb/src/execution/operator/persistent/physical_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ static void WriteCatalogEntries(stringstream &ss, catalog_entry_vector_t &entrie
}
auto create_info = entry.get().GetInfo();
try {
// Strip the catalog from the info
create_info->SetQualifiedName(QualifiedName(Identifier(), create_info->GetQualifiedName().Schema(),
create_info->GetQualifiedName().Name()));
// the catalog is implied by the database the export is imported into - keep only the schema path
create_info->StripCatalogQualification();
auto to_string = create_info->ToString();
ss << to_string;
} catch (const NotImplementedException &) {
Expand All @@ -60,12 +59,11 @@ static void WriteCopyStatement(FileSystem &fs, stringstream &ss, CopyInfo &info,
ss << "COPY ";

//! NOTE: The catalog is explicitly not set here
if (exported_table.qualified_name.Schema() != DEFAULT_SCHEMA && !exported_table.qualified_name.Schema().empty()) {
ss << SQLIdentifier(exported_table.qualified_name.Schema()) << ".";
}

auto table_name = exported_table.qualified_name;
table_name.StripCatalog();
auto file_path = StringUtil::Replace(exported_table.file_path, "\\", "/");
ss << StringUtil::Format("%s FROM %s (", SQLIdentifier(exported_table.qualified_name.Name()), SQLString(file_path));
ss << StringUtil::Format("%s FROM %s (", table_name.ToString(QualifiedNameToStringMode::HIDE_DEFAULT_SCHEMA),
SQLString(file_path));
// write the copy options
ss << "FORMAT '" << info.format << "'";
if (info.format == "csv") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ SourceResultType PhysicalCreateTrigger::GetDataInternal(ExecutionContext &contex
// reference preserves the name exactly as written, which may be a two-part `catalog.table` reference that would
// otherwise be misread as `schema.table` here.
auto &table = Catalog::GetEntry<TableCatalogEntry>(
context.client, QualifiedName(info->GetQualifiedName().Catalog(), info->GetQualifiedName().Schema(),
info->base_table->GetQualifiedName().Name()));
context.client, info->GetQualifiedName().WithName(info->base_table->GetQualifiedName().Name()));
auto transaction = catalog.GetCatalogTransaction(context.client);
table.CreateTrigger(transaction, *info);

Expand Down
Loading
Loading