Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
duckdb::DuckTableEntry Class Reference

A table catalog entry. More...

Inheritance diagram for duckdb::DuckTableEntry:
Collaboration diagram for duckdb::DuckTableEntry:

Public Member Functions

 DuckTableEntry (Catalog &catalog, SchemaCatalogEntry &schema, BoundCreateTableInfo &info, shared_ptr< DataTable > inherited_storage=nullptr)
 Create a TableCatalogEntry and initialize storage for it.
 
unique_ptr< CatalogEntryAlterEntry (ClientContext &context, AlterInfo &info) override
 
unique_ptr< CatalogEntryAlterEntry (CatalogTransaction, AlterInfo &info) override
 
void UndoAlter (ClientContext &context, AlterInfo &info) override
 
void Rollback (CatalogEntry &prev_entry) override
 
void OnDrop () override
 
DataTableGetStorage () override
 Returns the underlying storage of the table.
 
unique_ptr< BaseStatisticsGetStatistics (ClientContext &context, const StorageIndex &storage_index)
 Get statistics of a column (physical or virtual) within the table.
 
unique_ptr< BaseStatisticsGetStatistics (ClientContext &context, column_t column_id) override
 Get statistics of a column (physical or virtual) within the table.
 
unique_ptr< BlockingSampleGetSample () override
 
unique_ptr< CatalogEntryCopy (ClientContext &context) const override
 
void SetAsRoot () override
 Sets the CatalogEntry as the new root entry (i.e. the newest entry)
 
void CommitAlter (string &column_name)
 
void CommitDrop ()
 
TableFunction GetScanFunction (ClientContext &context, unique_ptr< FunctionData > &bind_data) override
 Returns the scan function that can be used to scan the given table.
 
vector< ColumnSegmentInfoGetColumnSegmentInfo (const QueryContext &context) override
 Returns a list of segment information for this table, if exists.
 
TableStorageInfo GetStorageInfo (ClientContext &context) override
 Returns the storage info of this table.
 
bool IsDuckTable () const override
 
- Public Member Functions inherited from duckdb::TableCatalogEntry
DUCKDB_API TableCatalogEntry (Catalog &catalog, SchemaCatalogEntry &schema, CreateTableInfo &info)
 Create a TableCatalogEntry and initialize storage for it.
 
DUCKDB_API unique_ptr< CreateInfoGetInfo () const override
 
DUCKDB_API bool HasGeneratedColumns () const
 
DUCKDB_API bool ColumnExists (const string &name) const
 Returns whether or not a column with the given name exists.
 
DUCKDB_API const ColumnDefinitionGetColumn (const string &name) const
 
DUCKDB_API const ColumnDefinitionGetColumn (LogicalIndex idx) const
 
DUCKDB_API vector< LogicalTypeGetTypes () const
 Returns a list of types of the table, excluding generated columns.
 
DUCKDB_API const ColumnListGetColumns () const
 Returns a list of the columns of the table.
 
DUCKDB_API const vector< unique_ptr< Constraint > > & GetConstraints () const
 Returns a list of the constraints of the table.
 
DUCKDB_API string ToSQL () const override
 Convert the catalog entry to a SQL string that can be used to re-construct the catalog entry.
 
DUCKDB_API LogicalIndex GetColumnIndex (string &name, bool if_exists=false) const
 
DUCKDB_API StorageIndex GetStorageIndex (const ColumnIndex &column_index) const
 
virtual TableFunction GetScanFunction (ClientContext &context, unique_ptr< FunctionData > &bind_data, const EntryLookupInfo &lookup_info)
 
virtual void BindUpdateConstraints (Binder &binder, LogicalGet &get, LogicalProjection &proj, LogicalUpdate &update, ClientContext &context)
 
optional_ptr< ConstraintGetPrimaryKey () const
 Returns a pointer to the table's primary key, if exists, else nullptr.
 
bool HasPrimaryKey () const
 Returns true, if the table has a primary key, else false.
 
virtual virtual_column_map_t GetVirtualColumns () const
 Returns the virtual columns for this table.
 
virtual vector< column_tGetRowIdColumns () const
 
- Public Member Functions inherited from duckdb::StandardEntry
 StandardEntry (CatalogType type, SchemaCatalogEntry &schema, Catalog &catalog, string name)
 
SchemaCatalogEntryParentSchema () override
 
const SchemaCatalogEntryParentSchema () const override
 
- Public Member Functions inherited from duckdb::InCatalogEntry
 InCatalogEntry (CatalogType type, Catalog &catalog, string name)
 
CatalogParentCatalog () override
 
const CatalogParentCatalog () const override
 
void Verify (Catalog &catalog) override
 
- Public Member Functions inherited from duckdb::CatalogEntry
 CatalogEntry (CatalogType type, Catalog &catalog, string name)
 
 CatalogEntry (CatalogType type, string name, idx_t oid)
 
void Serialize (Serializer &serializer) const
 
void SetChild (unique_ptr< CatalogEntry > child)
 
unique_ptr< CatalogEntryTakeChild ()
 
bool HasChild () const
 
bool HasParent () const
 
CatalogEntryChild ()
 
CatalogEntryParent ()
 
const CatalogEntryParent () const
 
template<class TARGET >
TARGETCast ()
 
template<class TARGET >
const TARGETCast () const
 

Private Member Functions

unique_ptr< CatalogEntryRenameColumn (ClientContext &context, RenameColumnInfo &info)
 
unique_ptr< CatalogEntryRenameField (ClientContext &context, RenameFieldInfo &info)
 
unique_ptr< CatalogEntryAddColumn (ClientContext &context, AddColumnInfo &info)
 
unique_ptr< CatalogEntryAddField (ClientContext &context, AddFieldInfo &info)
 
unique_ptr< CatalogEntryRemoveColumn (ClientContext &context, RemoveColumnInfo &info)
 
unique_ptr< CatalogEntryRemoveField (ClientContext &context, RemoveFieldInfo &info)
 
unique_ptr< CatalogEntrySetDefault (ClientContext &context, SetDefaultInfo &info)
 
unique_ptr< CatalogEntryChangeColumnType (ClientContext &context, ChangeColumnTypeInfo &info)
 
unique_ptr< CatalogEntrySetNotNull (ClientContext &context, SetNotNullInfo &info)
 
unique_ptr< CatalogEntryDropNotNull (ClientContext &context, DropNotNullInfo &info)
 
unique_ptr< CatalogEntryAddForeignKeyConstraint (AlterForeignKeyInfo &info)
 
unique_ptr< CatalogEntryDropForeignKeyConstraint (ClientContext &context, AlterForeignKeyInfo &info)
 
unique_ptr< CatalogEntrySetColumnComment (ClientContext &context, SetColumnCommentInfo &info)
 
unique_ptr< CatalogEntryAddConstraint (ClientContext &context, AddConstraintInfo &info)
 
void UpdateConstraintsOnColumnDrop (const LogicalIndex &removed_index, const vector< LogicalIndex > &adjusted_indices, const RemoveColumnInfo &info, CreateTableInfo &create_info, const vector< unique_ptr< BoundConstraint > > &bound_constraints, bool is_generated)
 

Private Attributes

shared_ptr< DataTablestorage
 A reference to the underlying storage unit used for this table.
 
ColumnDependencyManager column_dependency_manager
 Manages dependencies of the individual columns of the table.
 

Additional Inherited Members

- Static Public Member Functions inherited from duckdb::TableCatalogEntry
static DUCKDB_API string ColumnsToSQL (const ColumnList &columns, const vector< unique_ptr< Constraint > > &constraints)
 
static string ColumnNamesToSQL (const ColumnList &columns)
 Returns the expression string list of the column names e.g. (col1, col2, col3)
 
- Static Public Member Functions inherited from duckdb::CatalogEntry
static unique_ptr< CreateInfoDeserialize (Deserializer &deserializer)
 
- Public Attributes inherited from duckdb::StandardEntry
SchemaCatalogEntryschema
 The schema the entry belongs to.
 
LogicalDependencyList dependencies
 The dependencies of the entry, can be empty.
 
- Public Attributes inherited from duckdb::InCatalogEntry
Catalogcatalog
 The catalog the entry belongs to.
 
- Public Attributes inherited from duckdb::CatalogEntry
idx_t oid
 The oid of the entry.
 
CatalogType type
 The type of this catalog entry.
 
optional_ptr< CatalogSetset
 Reference to the catalog set this entry is stored in.
 
string name
 The name of the entry.
 
bool deleted
 Whether or not the object is deleted.
 
bool temporary
 Whether or not the object is temporary and should not be added to the WAL.
 
bool internal
 Whether or not the entry is an internal entry (cannot be deleted, not dumped, etc)
 
atomic< transaction_ttimestamp
 Timestamp at which the catalog entry was created.
 
Value comment
 (optional) comment on this entry
 
InsertionOrderPreservingMap< string > tags
 (optional) extra data associated with this entry
 
- Static Public Attributes inherited from duckdb::TableCatalogEntry
static constexpr const CatalogType Type = CatalogType::TABLE_ENTRY
 
static constexpr const charName = "table"
 
- Protected Attributes inherited from duckdb::TableCatalogEntry
ColumnList columns
 A list of columns that are part of this table.
 
vector< unique_ptr< Constraint > > constraints
 A list of constraints that are part of this table.
 

Detailed Description

A table catalog entry.

Constructor & Destructor Documentation

◆ DuckTableEntry()

duckdb::DuckTableEntry::DuckTableEntry ( Catalog catalog,
SchemaCatalogEntry schema,
BoundCreateTableInfo info,
shared_ptr< DataTable inherited_storage = nullptr 
)

Create a TableCatalogEntry and initialize storage for it.

13161 : TableCatalogEntry(catalog, schema, info.Base()), storage(std::move(inherited_storage)),
13162 column_dependency_manager(std::move(info.column_dependency_manager)) {
13163 if (storage) {
13164 if (!info.indexes.empty()) {
13165 storage->SetIndexStorageInfo(std::move(info.indexes));
13166 }
13167 return;
13168 }
13169
13170 // create the physical storage
13171 vector<ColumnDefinition> column_defs;
13172 for (auto &col_def : columns.Physical()) {
13173 CheckTypeIsSupported(col_def.Type(), catalog.GetAttached());
13174
13175 column_defs.push_back(col_def.Copy());
13176 }
13177 storage = make_shared_ptr<DataTable>(catalog.GetAttached(), StorageManager::Get(catalog).GetTableIOManager(&info),
13178 schema.name, name, std::move(column_defs), std::move(info.data));
13179
13180 // Create the unique indexes for the UNIQUE, PRIMARY KEY, and FOREIGN KEY constraints.
13181 idx_t indexes_idx = 0;
13182 for (idx_t i = 0; i < constraints.size(); i++) {
13183 auto &constraint = constraints[i];
13184 if (constraint->type == ConstraintType::UNIQUE) {
13185 // UNIQUE constraint: Create a unique index.
13186 auto &unique = constraint->Cast<UniqueConstraint>();
13187 IndexConstraintType constraint_type = IndexConstraintType::UNIQUE;
13188 if (unique.is_primary_key) {
13189 constraint_type = IndexConstraintType::PRIMARY;
13190 }
13191
13192 auto column_indexes = unique.GetLogicalIndexes(columns);
13193 if (info.indexes.empty()) {
13194 auto index_info = GetIndexInfo(constraint_type, false, info.base, i);
13195 storage->AddIndex(columns, column_indexes, constraint_type, std::move(index_info));
13196 continue;
13197 }
13198
13199 // We read the index from an old storage version applying a dummy name.
13200 auto index_storage_info = std::move(info.indexes[indexes_idx++]);
13201 if (index_storage_info.name.empty()) {
13202 auto name_info = GetIndexInfo(constraint_type, true, info.base, i);
13203 index_storage_info.name = name_info.name;
13204 }
13205
13206 storage->AddIndex(columns, column_indexes, constraint_type, std::move(index_storage_info));
13207 continue;
13208 }
13209
13210 if (constraint->type == ConstraintType::FOREIGN_KEY) {
13211 // Create a FOREIGN KEY index.
13212 auto &bfk = constraint->Cast<ForeignKeyConstraint>();
13213 if (bfk.info.type == ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE ||
13214 bfk.info.type == ForeignKeyType::FK_TYPE_SELF_REFERENCE_TABLE) {
13215 vector<LogicalIndex> column_indexes;
13216 for (const auto &physical_index : bfk.info.fk_keys) {
13217 auto &col = columns.GetColumn(physical_index);
13218 column_indexes.push_back(col.Logical());
13219 }
13220
13221 if (info.indexes.empty()) {
13222 auto constraint_type = IndexConstraintType::FOREIGN;
13223 auto index_info = GetIndexInfo(constraint_type, false, info.base, i);
13224 storage->AddIndex(columns, column_indexes, constraint_type, std::move(index_info));
13225 continue;
13226 }
13227
13228 // We read the index from an old storage version applying a dummy name.
13229 auto index_storage_info = std::move(info.indexes[indexes_idx++]);
13230 if (index_storage_info.name.empty()) {
13231 auto name_info = GetIndexInfo(IndexConstraintType::FOREIGN, true, info.base, i);
13232 index_storage_info.name = name_info.name;
13233 }
13234
13235 storage->AddIndex(columns, column_indexes, IndexConstraintType::FOREIGN, std::move(index_storage_info));
13236 }
13237 }
13238 }
13239
13240 // Move any remaining unused IndexStorageInfos to storage.
13241 // These are non-constraint indexes that are still unbound at this point.
13242 vector<IndexStorageInfo> remaining_indexes;
13243 while (indexes_idx < info.indexes.size()) {
13244 remaining_indexes.push_back(std::move(info.indexes[indexes_idx++]));
13245 }
13246 if (!remaining_indexes.empty()) {
13247 storage->SetIndexStorageInfo(std::move(remaining_indexes));
13248 }
13249}
string name
The name of the entry.
Definition duckdb.hpp:6311
ColumnDependencyManager column_dependency_manager
Manages dependencies of the individual columns of the table.
Definition duckdb.cpp:9329
shared_ptr< DataTable > storage
A reference to the underlying storage unit used for this table.
Definition duckdb.cpp:9327
Catalog & catalog
The catalog the entry belongs to.
Definition duckdb.hpp:6387
SchemaCatalogEntry & schema
The schema the entry belongs to.
Definition duckdb.hpp:28008
DUCKDB_API TableCatalogEntry(Catalog &catalog, SchemaCatalogEntry &schema, CreateTableInfo &info)
Create a TableCatalogEntry and initialize storage for it.
Definition duckdb.cpp:20902
ColumnList columns
A list of columns that are part of this table.
Definition duckdb.cpp:2813
vector< unique_ptr< Constraint > > constraints
A list of constraints that are part of this table.
Definition duckdb.cpp:2815

Member Function Documentation

◆ AlterEntry() [1/2]

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::AlterEntry ( ClientContext context,
AlterInfo info 
)
overridevirtual

Reimplemented from duckdb::CatalogEntry.

13293 {
13294 D_ASSERT(!internal);
13295
13296 // Column comments have a special alter type
13297 if (info.type == AlterType::SET_COLUMN_COMMENT) {
13298 auto &comment_on_column_info = info.Cast<SetColumnCommentInfo>();
13299 return SetColumnComment(context, comment_on_column_info);
13300 }
13301
13302 if (info.type != AlterType::ALTER_TABLE) {
13303 throw CatalogException("Can only modify table with ALTER TABLE statement");
13304 }
13305 auto &table_info = info.Cast<AlterTableInfo>();
13306 switch (table_info.alter_table_type) {
13307 case AlterTableType::RENAME_COLUMN: {
13308 auto &rename_info = table_info.Cast<RenameColumnInfo>();
13309 return RenameColumn(context, rename_info);
13310 }
13311 case AlterTableType::RENAME_FIELD: {
13312 auto &rename_info = table_info.Cast<RenameFieldInfo>();
13313 return RenameField(context, rename_info);
13314 }
13315 case AlterTableType::RENAME_TABLE: {
13316 auto &rename_info = table_info.Cast<RenameTableInfo>();
13317 auto copied_table = Copy(context);
13318 copied_table->name = rename_info.new_table_name;
13319 storage->SetTableName(rename_info.new_table_name);
13320 return copied_table;
13321 }
13322 case AlterTableType::ADD_COLUMN: {
13323 auto &add_info = table_info.Cast<AddColumnInfo>();
13324 return AddColumn(context, add_info);
13325 }
13326 case AlterTableType::ADD_FIELD: {
13327 auto &add_info = table_info.Cast<AddFieldInfo>();
13328 return AddField(context, add_info);
13329 }
13330 case AlterTableType::REMOVE_COLUMN: {
13331 auto &remove_info = table_info.Cast<RemoveColumnInfo>();
13332 return RemoveColumn(context, remove_info);
13333 }
13334 case AlterTableType::REMOVE_FIELD: {
13335 auto &remove_info = table_info.Cast<RemoveFieldInfo>();
13336 return RemoveField(context, remove_info);
13337 }
13338 case AlterTableType::SET_DEFAULT: {
13339 auto &set_default_info = table_info.Cast<SetDefaultInfo>();
13340 return SetDefault(context, set_default_info);
13341 }
13342 case AlterTableType::ALTER_COLUMN_TYPE: {
13343 auto &change_type_info = table_info.Cast<ChangeColumnTypeInfo>();
13344 return ChangeColumnType(context, change_type_info);
13345 }
13346 case AlterTableType::FOREIGN_KEY_CONSTRAINT: {
13347 auto &foreign_key_constraint_info = table_info.Cast<AlterForeignKeyInfo>();
13348 if (foreign_key_constraint_info.type == AlterForeignKeyType::AFT_ADD) {
13349 return AddForeignKeyConstraint(foreign_key_constraint_info);
13350 } else {
13351 return DropForeignKeyConstraint(context, foreign_key_constraint_info);
13352 }
13353 }
13354 case AlterTableType::SET_NOT_NULL: {
13355 auto &set_not_null_info = table_info.Cast<SetNotNullInfo>();
13356 return SetNotNull(context, set_not_null_info);
13357 }
13358 case AlterTableType::DROP_NOT_NULL: {
13359 auto &drop_not_null_info = table_info.Cast<DropNotNullInfo>();
13360 return DropNotNull(context, drop_not_null_info);
13361 }
13362 case AlterTableType::ADD_CONSTRAINT: {
13363 auto &add_constraint_info = table_info.Cast<AddConstraintInfo>();
13364 return AddConstraint(context, add_constraint_info);
13365 }
13366 case AlterTableType::SET_PARTITIONED_BY:
13367 throw NotImplementedException("SET PARTITIONED BY is not supported for DuckDB tables");
13368 case AlterTableType::SET_SORTED_BY:
13369 throw NotImplementedException("SET SORTED BY is not supported for DuckDB tables");
13370 case AlterTableType::SET_TABLE_OPTIONS:
13371 throw NotImplementedException("SET (<options>) is not supported for DuckDB tables");
13372 case AlterTableType::RESET_TABLE_OPTIONS: {
13373 throw NotImplementedException("RESET (<options>) is not supported for DuckDB tables");
13374 }
13375 default:
13376 throw InternalException("Unrecognized alter table type!");
13377 }
13378}

◆ AlterEntry() [2/2]

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::AlterEntry ( CatalogTransaction  transaction,
AlterInfo info 
)
overridevirtual

Reimplemented from duckdb::CatalogEntry.

13271 {
13272 if (transaction.HasContext()) {
13273 return AlterEntry(transaction.GetContext(), info);
13274 }
13275 if (info.type != AlterType::ALTER_TABLE) {
13276 return CatalogEntry::AlterEntry(transaction, info);
13277 }
13278
13279 auto &table_info = info.Cast<AlterTableInfo>();
13280 if (table_info.alter_table_type != AlterTableType::FOREIGN_KEY_CONSTRAINT) {
13281 return CatalogEntry::AlterEntry(transaction, info);
13282 }
13283
13284 auto &foreign_key_constraint_info = table_info.Cast<AlterForeignKeyInfo>();
13285 if (foreign_key_constraint_info.type != AlterForeignKeyType::AFT_ADD) {
13286 return CatalogEntry::AlterEntry(transaction, info);
13287 }
13288
13289 // We add foreign key constraints without a client context during checkpoint loading.
13290 return AddForeignKeyConstraint(foreign_key_constraint_info);
13291}

◆ UndoAlter()

void duckdb::DuckTableEntry::UndoAlter ( ClientContext context,
AlterInfo info 
)
overridevirtual

Reimplemented from duckdb::CatalogEntry.

13380 {
13381 D_ASSERT(!internal);
13382 D_ASSERT(info.type == AlterType::ALTER_TABLE);
13383 auto &table_info = info.Cast<AlterTableInfo>();
13384 switch (table_info.alter_table_type) {
13385 case AlterTableType::RENAME_TABLE: {
13386 storage->SetTableName(this->name);
13387 break;
13388 default:
13389 break;
13390 }
13391 }
13392}

◆ Rollback()

void duckdb::DuckTableEntry::Rollback ( CatalogEntry prev_entry)
overridevirtual

Reimplemented from duckdb::CatalogEntry.

14284 {
14285 if (prev_entry.type != CatalogType::TABLE_ENTRY) {
14286 return;
14287 }
14288
14289 // Rolls back any physical index creation.
14290 // FIXME: Currently only works for PKs.
14291 // FIXME: Should be changed to work for any index-based constraint.
14292
14293 auto &table = Cast<DuckTableEntry>();
14294 auto &prev_table = prev_entry.Cast<DuckTableEntry>();
14295 auto &prev_info = prev_table.GetStorage().GetDataTableInfo();
14296 auto &prev_indexes = prev_info->GetIndexes();
14297
14298 // Find all index-based constraints that exist in rollback_table, but not in table.
14299 // Then, remove them.
14300
14301 unordered_set<string> names;
14302 for (const auto &constraint : prev_table.GetConstraints()) {
14303 if (constraint->type != ConstraintType::UNIQUE) {
14304 continue;
14305 }
14306 const auto &unique = constraint->Cast<UniqueConstraint>();
14307 if (unique.is_primary_key) {
14308 auto index_name = unique.GetName(prev_table.name);
14309 names.insert(index_name);
14310 }
14311 }
14312
14313 for (const auto &constraint : GetConstraints()) {
14314 if (constraint->type != ConstraintType::UNIQUE) {
14315 continue;
14316 }
14317 const auto &unique = constraint->Cast<UniqueConstraint>();
14318 if (!unique.IsPrimaryKey()) {
14319 continue;
14320 }
14321 auto index_name = unique.GetName(table.name);
14322 if (names.find(index_name) == names.end()) {
14323 prev_indexes.RemoveIndex(index_name);
14324 }
14325 }
14326}
DuckTableEntry(Catalog &catalog, SchemaCatalogEntry &schema, BoundCreateTableInfo &info, shared_ptr< DataTable > inherited_storage=nullptr)
Create a TableCatalogEntry and initialize storage for it.
Definition duckdb.cpp:13159
DUCKDB_API const vector< unique_ptr< Constraint > > & GetConstraints() const
Returns a list of the constraints of the table.
Definition duckdb.cpp:21129

◆ OnDrop()

void duckdb::DuckTableEntry::OnDrop ( )
overridevirtual

Reimplemented from duckdb::CatalogEntry.

14328 {
14329 storage->SetAsDropped();
14330}

◆ GetStorage()

DataTable & duckdb::DuckTableEntry::GetStorage ( )
overridevirtual

Returns the underlying storage of the table.

Reimplemented from duckdb::TableCatalogEntry.

14397 {
14398 return *storage;
14399}
Here is the caller graph for this function:

◆ GetStatistics() [1/2]

unique_ptr< BaseStatistics > duckdb::DuckTableEntry::GetStatistics ( ClientContext context,
const StorageIndex storage_index 
)

Get statistics of a column (physical or virtual) within the table.

13251 {
13252 return storage->GetStatistics(context, column_id);
13253}

◆ GetStatistics() [2/2]

unique_ptr< BaseStatistics > duckdb::DuckTableEntry::GetStatistics ( ClientContext context,
column_t  column_id 
)
overridevirtual

Get statistics of a column (physical or virtual) within the table.

Implements duckdb::TableCatalogEntry.

13255 {
13256 if (column_id == COLUMN_IDENTIFIER_ROW_ID) {
13257 return nullptr;
13258 }
13259 auto &column = columns.GetColumn(LogicalIndex(column_id));
13260 if (column.Generated()) {
13261 return nullptr;
13262 }
13263 auto storage_index = GetStorageIndex(ColumnIndex(column_id));
13264 return storage->GetStatistics(context, storage_index);
13265}
const column_t COLUMN_IDENTIFIER_ROW_ID
Special value used to signify the ROW ID of a table.
Definition duckdb.cpp:50303

◆ GetSample()

unique_ptr< BlockingSample > duckdb::DuckTableEntry::GetSample ( )
overridevirtual

Reimplemented from duckdb::TableCatalogEntry.

13267 {
13268 return storage->GetSample();
13269}

◆ Copy()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::Copy ( ClientContext context) const
overridevirtual

Reimplemented from duckdb::CatalogEntry.

14360 {
14361 D_ASSERT(!internal);
14362 auto create_info = GetInfo();
14363
14364 auto binder = Binder::CreateBinder(context);
14365 auto bound_create_info = binder->BindCreateTableCheckpoint(std::move(create_info), schema);
14366 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, storage);
14367}

◆ SetAsRoot()

void duckdb::DuckTableEntry::SetAsRoot ( )
overridevirtual

Sets the CatalogEntry as the new root entry (i.e. the newest entry)

Reimplemented from duckdb::CatalogEntry.

14369 {
14370 storage->SetAsMainTable();
14371 storage->SetTableName(name);
14372}

◆ CommitAlter()

void duckdb::DuckTableEntry::CommitAlter ( string &  column_name)
14374 {
14375 D_ASSERT(!column_name.empty());
14376 optional_idx removed_index;
14377 for (auto &col : columns.Logical()) {
14378 if (col.Name() == column_name) {
14379 // No need to alter storage, removed column is generated column
14380 if (col.Generated()) {
14381 return;
14382 }
14383 removed_index = col.Oid();
14384 break;
14385 }
14386 }
14387
14388 auto logical_column_index = LogicalIndex(removed_index.GetIndex());
14389 auto column_index = columns.LogicalToPhysical(logical_column_index).index;
14390 storage->CommitDropColumn(column_index);
14391}

◆ CommitDrop()

void duckdb::DuckTableEntry::CommitDrop ( )
14393 {
14394 storage->CommitDropTable();
14395}

◆ GetScanFunction()

TableFunction duckdb::DuckTableEntry::GetScanFunction ( ClientContext context,
unique_ptr< FunctionData > &  bind_data 
)
overridevirtual

Returns the scan function that can be used to scan the given table.

Implements duckdb::TableCatalogEntry.

14401 {
14402 bind_data = make_uniq<TableScanBindData>(*this);
14403 return TableScanFunction::GetFunction();
14404}

◆ GetColumnSegmentInfo()

vector< ColumnSegmentInfo > duckdb::DuckTableEntry::GetColumnSegmentInfo ( const QueryContext context)
overridevirtual

Returns a list of segment information for this table, if exists.

Reimplemented from duckdb::TableCatalogEntry.

14406 {
14407 return storage->GetColumnSegmentInfo(context);
14408}

◆ GetStorageInfo()

TableStorageInfo duckdb::DuckTableEntry::GetStorageInfo ( ClientContext context)
overridevirtual

Returns the storage info of this table.

Implements duckdb::TableCatalogEntry.

14410 {
14411 return storage->GetStorageInfo();
14412}

◆ IsDuckTable()

bool duckdb::DuckTableEntry::IsDuckTable ( ) const
inlineoverridevirtual

Reimplemented from duckdb::TableCatalogEntry.

9301 {
9302 return true;
9303 }

◆ RenameColumn()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::RenameColumn ( ClientContext context,
RenameColumnInfo info 
)
private
13402 {
13403 auto rename_idx = GetColumnIndex(info.old_name);
13404 if (rename_idx.index == COLUMN_IDENTIFIER_ROW_ID) {
13405 throw CatalogException("Cannot rename rowid column");
13406 }
13407 auto create_info = make_uniq<CreateTableInfo>(schema, name);
13408 create_info->temporary = temporary;
13409 create_info->comment = comment;
13410 create_info->tags = tags;
13411 for (auto &col : columns.Logical()) {
13412 auto copy = col.Copy();
13413 if (rename_idx == col.Logical()) {
13414 copy.SetName(info.new_name);
13415 }
13416 if (col.Generated() && column_dependency_manager.IsDependencyOf(col.Logical(), rename_idx)) {
13417 RenameExpression(copy.GeneratedExpressionMutable(), info);
13418 }
13419 create_info->columns.AddColumn(std::move(copy));
13420 }
13421 for (idx_t c_idx = 0; c_idx < constraints.size(); c_idx++) {
13422 auto copy = constraints[c_idx]->Copy();
13423 switch (copy->type) {
13424 case ConstraintType::NOT_NULL:
13425 // NOT NULL constraint: no adjustments necessary
13426 break;
13427 case ConstraintType::CHECK: {
13428 // CHECK constraint: need to rename column references that refer to the renamed column
13429 auto &check = copy->Cast<CheckConstraint>();
13430 RenameExpression(*check.expression, info);
13431 break;
13432 }
13433 case ConstraintType::UNIQUE: {
13434 // UNIQUE constraint: possibly need to rename columns
13435 auto &unique = copy->Cast<UniqueConstraint>();
13436 for (auto &column_name : unique.GetColumnNamesMutable()) {
13437 if (column_name == info.old_name) {
13438 column_name = info.new_name;
13439 }
13440 }
13441 break;
13442 }
13443 case ConstraintType::FOREIGN_KEY: {
13444 // FOREIGN KEY constraint: possibly need to rename columns
13445 auto &fk = copy->Cast<ForeignKeyConstraint>();
13446 vector<string> columns = fk.pk_columns;
13447 if (fk.info.type == ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE) {
13448 columns = fk.fk_columns;
13449 } else if (fk.info.type == ForeignKeyType::FK_TYPE_SELF_REFERENCE_TABLE) {
13450 for (idx_t i = 0; i < fk.fk_columns.size(); i++) {
13451 columns.push_back(fk.fk_columns[i]);
13452 }
13453 }
13454 for (idx_t i = 0; i < columns.size(); i++) {
13455 if (columns[i] == info.old_name) {
13456 throw CatalogException(
13457 "Cannot rename column \"%s\" because this is involved in the foreign key constraint",
13458 info.old_name);
13459 }
13460 }
13461 break;
13462 }
13463 default:
13464 throw InternalException("Unsupported constraint for entry!");
13465 }
13466 create_info->constraints.push_back(std::move(copy));
13467 }
13468 auto binder = Binder::CreateBinder(context);
13469 auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema);
13470 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, storage);
13471}
InsertionOrderPreservingMap< string > tags
(optional) extra data associated with this entry
Definition duckdb.hpp:6323
Value comment
(optional) comment on this entry
Definition duckdb.hpp:6321
bool temporary
Whether or not the object is temporary and should not be added to the WAL.
Definition duckdb.hpp:6315
DUCKDB_API LogicalIndex GetColumnIndex(string &name, bool if_exists=false) const
Definition duckdb.cpp:20929

◆ RenameField()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::RenameField ( ClientContext context,
RenameFieldInfo info 
)
private
14005 {
14006 if (!ColumnExists(info.column_path[0])) {
14007 throw CatalogException("Cannot rename field from column \"%s\" - it does not exist", info.column_path[0]);
14008 }
14009
14010 // follow the path
14011 auto &col = GetColumn(info.column_path[0]);
14012 auto res = RenameFieldFromStruct(col.Type(), info.column_path, info.new_name, 1);
14013 if (res.error.HasError()) {
14014 res.error.Throw();
14015 }
14016
14017 // construct the struct remapping expression
14018 vector<unique_ptr<ParsedExpression>> children;
14019 children.push_back(make_uniq<ColumnRefExpression>(info.column_path[0]));
14020 children.push_back(make_uniq<ConstantExpression>(Value(res.new_type)));
14021 children.push_back(make_uniq<ConstantExpression>(std::move(res.mapping)));
14022 children.push_back(make_uniq<ConstantExpression>(Value()));
14023
14024 auto function = make_uniq<FunctionExpression>("remap_struct", std::move(children));
14025 ChangeColumnTypeInfo change_column_type(info.GetAlterEntryData(), info.column_path[0], std::move(res.new_type),
14026 std::move(function));
14027 return ChangeColumnType(context, change_column_type);
14028}
DUCKDB_API bool ColumnExists(const string &name) const
Returns whether or not a column with the given name exists.
Definition duckdb.cpp:20950
DUCKDB_API const ColumnDefinition & GetColumn(const string &name) const
Definition duckdb.cpp:20954

◆ AddColumn()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::AddColumn ( ClientContext context,
AddColumnInfo info 
)
private
13473 {
13474 auto col_name = info.new_column.GetName();
13475
13476 // We're checking for the opposite condition (ADD COLUMN IF _NOT_ EXISTS ...).
13477 if (info.if_column_not_exists && ColumnExists(col_name)) {
13478 return nullptr;
13479 }
13480
13481 auto create_info = make_uniq<CreateTableInfo>(schema, name);
13482 create_info->temporary = temporary;
13483 create_info->comment = comment;
13484 create_info->tags = tags;
13485
13486 for (auto &col : columns.Logical()) {
13487 create_info->columns.AddColumn(col.Copy());
13488 }
13489 for (auto &constraint : constraints) {
13490 create_info->constraints.push_back(constraint->Copy());
13491 }
13492
13493 auto binder = Binder::CreateBinder(context);
13494 binder->SetSearchPath(catalog, schema.name);
13495 binder->BindLogicalType(info.new_column.TypeMutable());
13496
13497 // Check if type is supported in this database version
13498 CheckTypeIsSupported(info.new_column.GetType(), catalog.GetAttached());
13499
13500 info.new_column.SetOid(columns.LogicalColumnCount());
13501 info.new_column.SetStorageOid(columns.PhysicalColumnCount());
13502 auto col = info.new_column.Copy();
13503
13504 create_info->columns.AddColumn(std::move(col));
13505
13506 vector<unique_ptr<Expression>> bound_defaults;
13507 auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema, bound_defaults);
13508 auto new_storage = make_shared_ptr<DataTable>(context, *storage, info.new_column, *bound_defaults.back());
13509 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, new_storage);
13510}

◆ AddField()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::AddField ( ClientContext context,
AddFieldInfo info 
)
private
13654 {
13655 // follow the path
13656 auto &col = GetColumn(info.column_path[0]);
13657 auto res = AddFieldToStruct(col.Type(), info.column_path, info.new_field);
13658 if (res.error.HasError()) {
13659 if (!info.if_field_not_exists) {
13660 res.error.Throw();
13661 }
13662 return nullptr;
13663 }
13664
13665 // construct the struct remapping expression
13666 vector<unique_ptr<ParsedExpression>> children;
13667 children.push_back(make_uniq<ColumnRefExpression>(info.column_path[0]));
13668 children.push_back(make_uniq<ConstantExpression>(Value(res.new_type)));
13669 children.push_back(make_uniq<ConstantExpression>(ConstructMapping(col.Name(), col.Type())));
13670 D_ASSERT(res.default_value);
13671 children.push_back(std::move(res.default_value));
13672
13673 auto function = make_uniq<FunctionExpression>("remap_struct", std::move(children));
13674
13675 ChangeColumnTypeInfo change_column_type(info.GetAlterEntryData(), info.column_path[0], std::move(res.new_type),
13676 std::move(function));
13677 return ChangeColumnType(context, change_column_type);
13678}

◆ RemoveColumn()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::RemoveColumn ( ClientContext context,
RemoveColumnInfo info 
)
private
13781 {
13782 auto removed_index = GetColumnIndex(info.removed_column, info.if_column_exists);
13783 if (!removed_index.IsValid()) {
13784 if (!info.if_column_exists) {
13785 throw CatalogException("Cannot drop column: rowid column cannot be dropped");
13786 }
13787 return nullptr;
13788 }
13789
13790 auto create_info = make_uniq<CreateTableInfo>(schema, name);
13791 create_info->temporary = temporary;
13792 create_info->comment = comment;
13793 create_info->tags = tags;
13794
13795 logical_index_set_t removed_columns;
13796 if (column_dependency_manager.HasDependents(removed_index)) {
13797 removed_columns = column_dependency_manager.GetDependents(removed_index);
13798 }
13799 if (!removed_columns.empty() && !info.cascade) {
13800 throw CatalogException("Cannot drop column: column is a dependency of 1 or more generated column(s)");
13801 }
13802 bool dropped_column_is_generated = false;
13803 for (auto &col : columns.Logical()) {
13804 if (col.Logical() == removed_index || removed_columns.count(col.Logical())) {
13805 if (col.Generated()) {
13806 dropped_column_is_generated = true;
13807 }
13808 continue;
13809 }
13810 create_info->columns.AddColumn(col.Copy());
13811 }
13812 if (create_info->columns.empty()) {
13813 throw CatalogException("Cannot drop column: table only has one column remaining!");
13814 }
13815 auto adjusted_indices = column_dependency_manager.RemoveColumn(removed_index, columns.LogicalColumnCount());
13816
13817 auto binder = Binder::CreateBinder(context);
13818 auto bound_constraints = binder->BindConstraints(constraints, name, columns);
13819
13820 UpdateConstraintsOnColumnDrop(removed_index, adjusted_indices, info, *create_info, bound_constraints,
13821 dropped_column_is_generated);
13822
13823 auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema);
13824 info.new_dependencies = make_uniq<LogicalDependencyList>(std::move(bound_create_info->dependencies));
13825 if (columns.GetColumn(LogicalIndex(removed_index)).Generated()) {
13826 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, storage);
13827 }
13828 auto new_storage =
13829 make_shared_ptr<DataTable>(context, *storage, columns.LogicalToPhysical(LogicalIndex(removed_index)).index);
13830 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, new_storage);
13831}
vector< LogicalIndex > RemoveColumn(LogicalIndex index, idx_t column_amount)
Removes the column(s) and outputs the new column indices.
Definition duckdb.cpp:8485

◆ RemoveField()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::RemoveField ( ClientContext context,
RemoveFieldInfo info 
)
private
13904 {
13905 if (!ColumnExists(info.column_path[0])) {
13906 if (!info.if_column_exists) {
13907 throw CatalogException("Cannot drop field from column \"%s\" - it does not exist", info.column_path[0]);
13908 }
13909 return nullptr;
13910 }
13911 // follow the path
13912 auto &col = GetColumn(info.column_path[0]);
13913 auto res = DropFieldFromStruct(col.Type(), info.column_path, 1);
13914 if (res.error.HasError()) {
13915 if (!info.if_column_exists) {
13916 res.error.Throw();
13917 }
13918 return nullptr;
13919 }
13920
13921 // construct the struct remapping expression
13922 vector<unique_ptr<ParsedExpression>> children;
13923 children.push_back(make_uniq<ColumnRefExpression>(info.column_path[0]));
13924 children.push_back(make_uniq<ConstantExpression>(Value(res.new_type)));
13925 children.push_back(make_uniq<ConstantExpression>(std::move(res.mapping)));
13926 children.push_back(make_uniq<ConstantExpression>(Value()));
13927
13928 auto function = make_uniq<FunctionExpression>("remap_struct", std::move(children));
13929
13930 ChangeColumnTypeInfo change_column_type(info.GetAlterEntryData(), info.column_path[0], std::move(res.new_type),
13931 std::move(function));
13932 return ChangeColumnType(context, change_column_type);
13933}

◆ SetDefault()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::SetDefault ( ClientContext context,
SetDefaultInfo info 
)
private
14030 {
14031 auto default_idx = GetColumnIndex(info.column_name);
14032 if (default_idx.index == COLUMN_IDENTIFIER_ROW_ID) {
14033 throw CatalogException("Cannot SET DEFAULT for rowid column");
14034 }
14035
14036 auto create_info = GetInfo();
14037 auto &table_info = create_info->Cast<CreateTableInfo>();
14038
14039 // Modify the column that was specified by 'column_name'
14040 auto &col = table_info.columns.GetColumnMutable(default_idx);
14041 if (col.Generated()) {
14042 throw BinderException("Cannot SET DEFAULT for generated column \"%s\"", col.Name());
14043 }
14044 col.SetDefaultValue(info.expression ? info.expression->Copy() : nullptr);
14045
14046 auto binder = Binder::CreateBinder(context);
14047 auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema);
14048 info.new_dependencies = make_uniq<LogicalDependencyList>(std::move(bound_create_info->dependencies));
14049 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, storage);
14050}

◆ ChangeColumnType()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::ChangeColumnType ( ClientContext context,
ChangeColumnTypeInfo info 
)
private
14113 {
14114 // Bind type
14115 auto type_binder = Binder::CreateBinder(context);
14116 type_binder->SetSearchPath(catalog, schema.name);
14117 type_binder->BindLogicalType(info.target_type);
14118
14119 auto change_idx = GetColumnIndex(info.column_name);
14120 auto create_info = make_uniq<CreateTableInfo>(schema, name);
14121 create_info->temporary = temporary;
14122 create_info->comment = comment;
14123 create_info->tags = tags;
14124
14125 // Bind the USING expression.
14126 auto binder = Binder::CreateBinder(context);
14127 vector<LogicalIndex> bound_columns;
14128 AlterBinder expr_binder(*binder, context, *this, bound_columns, info.target_type);
14129 auto expression = info.expression->Copy();
14130 auto bound_expression = expr_binder.Bind(expression);
14131
14132 // Infer the target_type from the USING expression, if not set explicitly.
14133 if (info.target_type == LogicalType::UNKNOWN) {
14134 info.target_type = bound_expression->return_type;
14135 }
14136
14137 // Check if type is supported in this database version
14138 CheckTypeIsSupported(info.target_type, catalog.GetAttached());
14139
14140 auto bound_constraints = binder->BindConstraints(constraints, name, columns);
14141 for (auto &col : columns.Logical()) {
14142 auto copy = col.Copy();
14143 if (change_idx == col.Logical()) {
14144 // set the type of this column
14145 if (copy.Generated()) {
14146 throw NotImplementedException("Changing types of generated columns is not supported yet");
14147 }
14148 copy.SetType(info.target_type);
14149 }
14150 // TODO: check if the generated_expression breaks, only delete it if it does
14151 if (copy.Generated() && column_dependency_manager.IsDependencyOf(col.Logical(), change_idx)) {
14152 throw BinderException(
14153 "This column is referenced by the generated column \"%s\", so its type can not be changed",
14154 copy.Name());
14155 }
14156 create_info->columns.AddColumn(std::move(copy));
14157 }
14158
14159 for (idx_t constr_idx = 0; constr_idx < constraints.size(); constr_idx++) {
14160 auto constraint = constraints[constr_idx]->Copy();
14161 switch (constraint->type) {
14162 case ConstraintType::CHECK: {
14163 auto &bound_check = bound_constraints[constr_idx]->Cast<BoundCheckConstraint>();
14164 auto physical_index = columns.LogicalToPhysical(change_idx);
14165 if (bound_check.bound_columns.find(physical_index) != bound_check.bound_columns.end()) {
14166 throw BinderException("Cannot change the type of a column that has a CHECK constraint specified");
14167 }
14168 break;
14169 }
14170 case ConstraintType::NOT_NULL:
14171 break;
14172 case ConstraintType::UNIQUE: {
14173 auto &bound_unique = bound_constraints[constr_idx]->Cast<BoundUniqueConstraint>();
14174 auto physical_index = columns.LogicalToPhysical(change_idx);
14175 if (bound_unique.key_set.find(physical_index) != bound_unique.key_set.end()) {
14176 throw BinderException(
14177 "Cannot change the type of a column that has a UNIQUE or PRIMARY KEY constraint specified");
14178 }
14179 break;
14180 }
14181 case ConstraintType::FOREIGN_KEY: {
14182 auto &bfk = bound_constraints[constr_idx]->Cast<BoundForeignKeyConstraint>();
14183 auto key_set = bfk.pk_key_set;
14184 if (bfk.info.type == ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE) {
14185 key_set = bfk.fk_key_set;
14186 } else if (bfk.info.type == ForeignKeyType::FK_TYPE_SELF_REFERENCE_TABLE) {
14187 key_set.insert(bfk.info.fk_keys.begin(), bfk.info.fk_keys.end());
14188 }
14189 if (key_set.find(columns.LogicalToPhysical(change_idx)) != key_set.end()) {
14190 throw BinderException("Cannot change the type of a column that has a FOREIGN KEY constraint specified");
14191 }
14192 break;
14193 }
14194 default:
14195 throw InternalException("Unsupported constraint for entry!");
14196 }
14197 create_info->constraints.push_back(std::move(constraint));
14198 }
14199
14200 auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema);
14201
14202 vector<StorageIndex> storage_oids;
14203 for (idx_t i = 0; i < bound_columns.size(); i++) {
14204 storage_oids.emplace_back(columns.LogicalToPhysical(bound_columns[i]).index);
14205 }
14206 if (storage_oids.empty()) {
14207 storage_oids.emplace_back(COLUMN_IDENTIFIER_ROW_ID);
14208 }
14209
14210 auto new_storage =
14211 make_shared_ptr<DataTable>(context, *storage, columns.LogicalToPhysical(LogicalIndex(change_idx)).index,
14212 info.target_type, std::move(storage_oids), *bound_expression);
14213 auto result = make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, new_storage);
14214 return std::move(result);
14215}

◆ SetNotNull()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::SetNotNull ( ClientContext context,
SetNotNullInfo info 
)
private
14052 {
14053 auto not_null_idx = GetColumnIndex(info.column_name);
14054 if (columns.GetColumn(LogicalIndex(not_null_idx)).Generated()) {
14055 throw BinderException("Unsupported constraint for generated column!");
14056 }
14057
14058 auto create_info = GetInfo();
14059 auto &table_info = create_info->Cast<CreateTableInfo>();
14060
14061 bool has_not_null = false;
14062 for (auto &constraint : table_info.constraints) {
14063 if (constraint->type == ConstraintType::NOT_NULL) {
14064 auto &not_null = constraint->Cast<NotNullConstraint>();
14065 if (not_null.index == not_null_idx) {
14066 has_not_null = true;
14067 break;
14068 }
14069 }
14070 }
14071 if (!has_not_null) {
14072 table_info.constraints.push_back(make_uniq<NotNullConstraint>(not_null_idx));
14073 }
14074
14075 auto binder = Binder::CreateBinder(context);
14076 auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema);
14077
14078 // Early return
14079 if (has_not_null) {
14080 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, storage);
14081 }
14082
14083 // Return with new storage info. Note that we need the bound column index here.
14084 auto physical_columns = columns.LogicalToPhysical(LogicalIndex(not_null_idx));
14085 auto bound_constraint = make_uniq<BoundNotNullConstraint>(physical_columns);
14086 auto new_storage = make_shared_ptr<DataTable>(context, *storage, *bound_constraint);
14087 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, new_storage);
14088}

◆ DropNotNull()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::DropNotNull ( ClientContext context,
DropNotNullInfo info 
)
private
14090 {
14091 auto not_null_idx = GetColumnIndex(info.column_name);
14092
14093 auto create_info = GetInfo();
14094 auto &table_info = create_info->Cast<CreateTableInfo>();
14095
14096 // Remove the NOT NULL constraint for the specified column
14097 for (idx_t i = 0; i < table_info.constraints.size(); i++) {
14098 auto &constraint = table_info.constraints[i];
14099 if (constraint->type == ConstraintType::NOT_NULL) {
14100 auto &not_null = constraint->Cast<NotNullConstraint>();
14101 if (not_null.index == not_null_idx) {
14102 table_info.constraints.erase(table_info.constraints.begin() + static_cast<ptrdiff_t>(i));
14103 break;
14104 }
14105 }
14106 }
14107
14108 auto binder = Binder::CreateBinder(context);
14109 auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema);
14110 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, storage);
14111}

◆ AddForeignKeyConstraint()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::AddForeignKeyConstraint ( AlterForeignKeyInfo info)
private
14235 {
14236 D_ASSERT(info.type == AlterForeignKeyType::AFT_ADD);
14237 auto create_info = make_uniq<CreateTableInfo>(schema, name);
14238 create_info->temporary = temporary;
14239 create_info->comment = comment;
14240 create_info->tags = tags;
14241
14242 create_info->columns = columns.Copy();
14243 for (idx_t i = 0; i < constraints.size(); i++) {
14244 create_info->constraints.push_back(constraints[i]->Copy());
14245 }
14246 ForeignKeyInfo fk_info;
14247 fk_info.type = ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE;
14248 fk_info.schema = info.schema;
14249 fk_info.table = info.fk_table;
14250 fk_info.pk_keys = info.pk_keys;
14251 fk_info.fk_keys = info.fk_keys;
14252 create_info->constraints.push_back(
14253 make_uniq<ForeignKeyConstraint>(info.pk_columns, info.fk_columns, std::move(fk_info)));
14254
14255 unique_ptr<BoundCreateTableInfo> bound_create_info;
14256 bound_create_info = Binder::BindCreateTableCheckpoint(std::move(create_info), schema);
14257 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, storage);
14258}

◆ DropForeignKeyConstraint()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::DropForeignKeyConstraint ( ClientContext context,
AlterForeignKeyInfo info 
)
private
14260 {
14261 D_ASSERT(info.type == AlterForeignKeyType::AFT_DELETE);
14262 auto create_info = make_uniq<CreateTableInfo>(schema, name);
14263 create_info->temporary = temporary;
14264 create_info->comment = comment;
14265 create_info->tags = tags;
14266
14267 create_info->columns = columns.Copy();
14268 for (idx_t i = 0; i < constraints.size(); i++) {
14269 auto constraint = constraints[i]->Copy();
14270 if (constraint->type == ConstraintType::FOREIGN_KEY) {
14271 ForeignKeyConstraint &fk = constraint->Cast<ForeignKeyConstraint>();
14272 if (fk.info.type == ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE && fk.info.table == info.fk_table) {
14273 continue;
14274 }
14275 }
14276 create_info->constraints.push_back(std::move(constraint));
14277 }
14278
14279 auto binder = Binder::CreateBinder(context);
14280 auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema);
14281 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, storage);
14282}

◆ SetColumnComment()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::SetColumnComment ( ClientContext context,
SetColumnCommentInfo info 
)
private
14217 {
14218 auto col_idx = GetColumnIndex(info.column_name);
14219 if (col_idx.index == COLUMN_IDENTIFIER_ROW_ID) {
14220 throw CatalogException("Cannot SET COMMENT for rowid column");
14221 }
14222
14223 auto create_info = GetInfo();
14224 auto &table_info = create_info->Cast<CreateTableInfo>();
14225
14226 // Modify the column that was specified by 'column_name'
14227 auto &col = table_info.columns.GetColumnMutable(col_idx);
14228 col.SetComment(info.comment_value);
14229
14230 auto binder = Binder::CreateBinder(context);
14231 auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema);
14232 return make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, storage);
14233}

◆ AddConstraint()

unique_ptr< CatalogEntry > duckdb::DuckTableEntry::AddConstraint ( ClientContext context,
AddConstraintInfo info 
)
private
14332 {
14333 auto create_info = GetInfo();
14334 auto &table_info = create_info->Cast<CreateTableInfo>();
14335
14336 if (info.constraint->type == ConstraintType::UNIQUE) {
14337 const auto &unique = info.constraint->Cast<UniqueConstraint>();
14338 const auto existing_pk = GetPrimaryKey();
14339
14340 if (unique.is_primary_key && existing_pk) {
14341 auto existing_name = existing_pk->ToString();
14342 throw CatalogException("table \"%s\" can have only one primary key: %s", name, existing_name);
14343 }
14344 table_info.constraints.push_back(info.constraint->Copy());
14345
14346 } else {
14347 throw InternalException("unsupported constraint type in ALTER TABLE statement");
14348 }
14349
14350 // We create a physical table with a new constraint and a new unique index.
14351 const auto binder = Binder::CreateBinder(context);
14352 const auto bound_constraint = binder->BindConstraint(*info.constraint, table_info.table, table_info.columns);
14353 const auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info), schema);
14354
14355 auto new_storage = make_shared_ptr<DataTable>(context, *storage, *bound_constraint);
14356 auto new_entry = make_uniq<DuckTableEntry>(catalog, schema, *bound_create_info, new_storage);
14357 return std::move(new_entry);
14358}
optional_ptr< Constraint > GetPrimaryKey() const
Returns a pointer to the table's primary key, if exists, else nullptr.
Definition duckdb.cpp:21234

◆ UpdateConstraintsOnColumnDrop()

void duckdb::DuckTableEntry::UpdateConstraintsOnColumnDrop ( const LogicalIndex removed_index,
const vector< LogicalIndex > &  adjusted_indices,
const RemoveColumnInfo info,
CreateTableInfo create_info,
const vector< unique_ptr< BoundConstraint > > &  bound_constraints,
bool  is_generated 
)
private
13684 {
13685 // handle constraints for the new table
13686 D_ASSERT(constraints.size() == bound_constraints.size());
13687 for (idx_t constr_idx = 0; constr_idx < constraints.size(); constr_idx++) {
13688 auto &constraint = constraints[constr_idx];
13689 auto &bound_constraint = bound_constraints[constr_idx];
13690 switch (constraint->type) {
13691 case ConstraintType::NOT_NULL: {
13692 auto &not_null_constraint = bound_constraint->Cast<BoundNotNullConstraint>();
13693 auto not_null_index = columns.PhysicalToLogical(not_null_constraint.index);
13694 if (not_null_index != removed_index) {
13695 // the constraint is not about this column: we need to copy it
13696 // we might need to shift the index back by one though, to account for the removed column
13697 auto new_index = adjusted_indices[not_null_index.index];
13698 create_info.constraints.push_back(make_uniq<NotNullConstraint>(new_index));
13699 }
13700 break;
13701 }
13702 case ConstraintType::CHECK: {
13703 // Generated columns can not be part of an index
13704 // CHECK constraint
13705 auto &bound_check = bound_constraint->Cast<BoundCheckConstraint>();
13706 // check if the removed column is part of the check constraint
13707 if (is_generated) {
13708 // generated columns can not be referenced by constraints, we can just add the constraint back
13709 create_info.constraints.push_back(constraint->Copy());
13710 break;
13711 }
13712 auto physical_index = columns.LogicalToPhysical(removed_index);
13713 if (bound_check.bound_columns.find(physical_index) != bound_check.bound_columns.end()) {
13714 if (bound_check.bound_columns.size() > 1) {
13715 // CHECK constraint that concerns mult
13716 throw CatalogException(
13717 "Cannot drop column \"%s\" because there is a CHECK constraint that depends on it",
13718 info.removed_column);
13719 } else {
13720 // CHECK constraint that ONLY concerns this column, strip the constraint
13721 }
13722 } else {
13723 // check constraint does not concern the removed column: simply re-add it
13724 create_info.constraints.push_back(constraint->Copy());
13725 }
13726 break;
13727 }
13728 case ConstraintType::UNIQUE: {
13729 auto copy = constraint->Copy();
13730 auto &unique = copy->Cast<UniqueConstraint>();
13731 if (unique.HasIndex()) {
13732 // Single-column UNIQUE constraint
13733 if (unique.GetIndex() == removed_index) {
13734 throw CatalogException(
13735 "Cannot drop column \"%s\" because there is a UNIQUE constraint that depends on it",
13736 info.removed_column);
13737 }
13738 unique.SetIndex(adjusted_indices[unique.GetIndex().index]);
13739 } else {
13740 // Multi-column UNIQUE constraint - check if any column matches the one being dropped
13741 for (const auto &col_name : unique.GetColumnNames()) {
13742 if (col_name == info.removed_column) {
13743 // Build constraint string for error message: UNIQUE(col1, col2, ...)
13744 auto constraint_str = "UNIQUE(" + StringUtil::Join(unique.GetColumnNames(), ", ") + ")";
13745 throw CatalogException(
13746 "Cannot drop column \"%s\" because it is referenced in unique constraint %s",
13747 info.removed_column, constraint_str);
13748 }
13749 }
13750 }
13751 create_info.constraints.push_back(std::move(copy));
13752 break;
13753 }
13754 case ConstraintType::FOREIGN_KEY: {
13755 auto copy = constraint->Copy();
13756 auto &fk = copy->Cast<ForeignKeyConstraint>();
13757 vector<string> columns = fk.pk_columns;
13758 if (fk.info.type == ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE) {
13759 columns = fk.fk_columns;
13760 } else if (fk.info.type == ForeignKeyType::FK_TYPE_SELF_REFERENCE_TABLE) {
13761 for (idx_t i = 0; i < fk.fk_columns.size(); i++) {
13762 columns.push_back(fk.fk_columns[i]);
13763 }
13764 }
13765 for (idx_t i = 0; i < columns.size(); i++) {
13766 if (columns[i] == info.removed_column) {
13767 throw CatalogException(
13768 "Cannot drop column \"%s\" because there is a FOREIGN KEY constraint that depends on it",
13769 info.removed_column);
13770 }
13771 }
13772 create_info.constraints.push_back(std::move(copy));
13773 break;
13774 }
13775 default:
13776 throw InternalException("Unsupported constraint for entry!");
13777 }
13778 }
13779}
static DUCKDB_API string Join(const vector< string > &input, const string &separator)
Join multiple strings into one string. Components are concatenated by the given separator.

The documentation for this class was generated from the following file: