Skip to content
Closed
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
13 changes: 13 additions & 0 deletions fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,19 @@ private void replaceTableInternal(Database db, OlapTable origTable, OlapTable ne
throws DdlException {
String oldTblName = origTable.getName();
String newTblName = newTbl.getName();

// Handle constraints for table replacement
TableNameInfo origTableInfo = new TableNameInfo(origTable);
TableNameInfo newTableInfo = new TableNameInfo(newTbl);
if (swapTable) {
Env.getCurrentEnv().getConstraintManager().swapTableConstraints(origTableInfo, newTableInfo);
} else {
if (!isReplay) {
Env.getCurrentEnv().getConstraintManager().checkNoReferencingForeignKeys(origTableInfo);
}
Env.getCurrentEnv().getConstraintManager().dropAndRenameConstraints(origTableInfo, newTableInfo);
}

// drop origin table and new table
db.unregisterTable(oldTblName);
db.unregisterTable(newTblName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
import org.apache.doris.common.util.TimeUtils;
import org.apache.doris.common.util.Util;
import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.info.TableNameInfo;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.nereids.trees.plans.commands.AlterCommand;
import org.apache.doris.nereids.trees.plans.commands.CancelAlterTableCommand;
Expand Down Expand Up @@ -267,6 +268,15 @@ private void processDropColumn(DropColumnClause alterClause, Table externalTable
throws DdlException {
String dropColName = alterClause.getColName();

String constraintName = Env.getCurrentEnv().getConstraintManager()
.findConstraintWithColumn(new TableNameInfo(externalTable), dropColName);
if (constraintName != null) {
throw new DdlException(String.format(
"Cannot drop column '%s' because it is used by constraint '%s'. "
+ "Drop the constraint first.",
dropColName, constraintName));
}

// find column in base index and remove it
boolean found = false;
Iterator<Column> baseIter = newSchema.iterator();
Expand Down Expand Up @@ -303,6 +313,16 @@ private boolean processDropColumn(DropColumnClause alterClause, OlapTable olapTa
throws DdlException {

String dropColName = alterClause.getColName();

String constraintName = Env.getCurrentEnv().getConstraintManager()
.findConstraintWithColumn(new TableNameInfo(olapTable), dropColName);
if (constraintName != null) {
throw new DdlException(String.format(
"Cannot drop column '%s' because it is used by constraint '%s'. "
+ "Drop the constraint first.",
dropColName, constraintName));
}

String targetIndexName = alterClause.getRollupName();
checkIndexExists(olapTable, targetIndexName);

Expand Down
87 changes: 85 additions & 2 deletions fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
import org.apache.doris.catalog.OlapTable.OlapTableState;
import org.apache.doris.catalog.Replica.ReplicaStatus;
import org.apache.doris.catalog.TableIf.TableType;
import org.apache.doris.catalog.constraint.Constraint;
import org.apache.doris.catalog.constraint.ConstraintManager;
import org.apache.doris.clone.ColocateTableCheckerAndBalancer;
import org.apache.doris.clone.DynamicPartitionScheduler;
import org.apache.doris.clone.TabletChecker;
Expand Down Expand Up @@ -102,6 +104,7 @@
import org.apache.doris.datasource.ExternalCatalog;
import org.apache.doris.datasource.ExternalMetaCacheMgr;
import org.apache.doris.datasource.ExternalMetaIdMgr;
import org.apache.doris.datasource.ExternalTable;
import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.datasource.SplitSourceManager;
import org.apache.doris.datasource.es.EsExternalCatalog;
Expand Down Expand Up @@ -551,6 +554,8 @@ public class Env {

private BinlogManager binlogManager;

private ConstraintManager constraintManager;

private BinlogGcer binlogGcer;

private QueryCancelWorker queryCancelWorker;
Expand Down Expand Up @@ -705,6 +710,10 @@ public BinlogManager getBinlogManager() {
return binlogManager;
}

public ConstraintManager getConstraintManager() {
return constraintManager;
}

public KeyManagerInterface getKeyManager() throws Exception {
if (keyManager == null) {
throw new Exception("The keyManager is null, possibly due to a missing implementation of KeyManager");
Expand Down Expand Up @@ -850,6 +859,7 @@ public Env(boolean isCheckpointCatalog) {
this.hiveTransactionMgr = new HiveTransactionMgr();
this.plsqlManager = new PlsqlManager();
this.binlogManager = new BinlogManager();
this.constraintManager = new ConstraintManager();
this.binlogGcer = new BinlogGcer();
this.columnIdFlusher = new ColumnIdFlushDaemon();
this.queryCancelWorker = new QueryCancelWorker(systemInfo);
Expand Down Expand Up @@ -1205,6 +1215,7 @@ public void initialize(String[] args) throws Exception {
// 3. Load image first and replay edits
this.editLog = new EditLog(nodeName);
loadImage(this.imageDir); // load image file
migrateConstraintsFromTables(); // migrate old table-based constraints
editLog.open(); // open bdb env
this.globalTransactionMgr.setEditLog(editLog);
this.idGenerator.setEditLog(editLog);
Expand Down Expand Up @@ -2980,6 +2991,68 @@ public long saveKeyManagerStore(CountingDataOutputStream out, long checksum) thr
return checksum;
}

public long saveConstraintManager(CountingDataOutputStream out, long checksum) throws IOException {
constraintManager.write(out);
LOG.info("finished save ConstraintManager to image");
return checksum;
}

public long loadConstraintManager(DataInputStream in, long checksum) throws IOException {
this.constraintManager = ConstraintManager.read(in);
LOG.info("finished replay ConstraintManager from image");
return checksum;
}

/**
* Migrate constraints from old table-based storage to ConstraintManager.
* Called after image loading to handle upgrade from old format.
*/
@SuppressWarnings("unchecked")
public void migrateConstraintsFromTables() {
if (!constraintManager.isEmpty()) {
return;
}
int migratedCount = 0;
for (CatalogIf catalog : catalogMgr.getCopyOfCatalog()) {
for (Object dbObj : catalog.getAllDbs()) {
DatabaseIf db = (DatabaseIf) dbObj;
for (Object tableObj : db.getTables()) {
TableIf table = (TableIf) tableObj;
try {
Map<String, Constraint> oldConstraints = null;
if (table instanceof Table) {
oldConstraints = ((Table) table)
.getTableAttributes().getConstraintsMap();
} else if (table instanceof ExternalTable) {
oldConstraints = ((ExternalTable) table)
.getTableAttributes().getConstraintsMap();
} else {
LOG.debug("Skipping constraint migration for "
+ "unsupported table type: {} ({})",
table.getName(),
table.getClass().getSimpleName());
}
if (oldConstraints != null && !oldConstraints.isEmpty()) {
String qualifiedName = table.getNameWithFullQualifiers();
constraintManager.migrateFromTable(
new TableNameInfo(qualifiedName), oldConstraints);
migratedCount += oldConstraints.size();
oldConstraints.clear();
}
} catch (Exception e) {
LOG.warn("Failed to migrate constraints for table {}",
table.getName(), e);
}
}
}
}
if (migratedCount > 0) {
LOG.info("Migrated {} constraints from old table-based storage "
+ "to ConstraintManager", migratedCount);
constraintManager.rebuildForeignKeyReferences();
}
}

public void createLabelCleaner() {
labelCleaner = new MasterDaemon("LoadLabelCleaner", Config.label_clean_interval_second * 1000L) {
@Override
Expand Down Expand Up @@ -4990,12 +5063,12 @@ public void dropView(String catalogName, String dbName, String tableName, boolea
}

public boolean unprotectDropTable(Database db, Table table, boolean isForceDrop, boolean isReplay,
Long recycleTime) {
Long recycleTime) throws DdlException {
return getInternalCatalog().unprotectDropTable(db, table, isForceDrop, isReplay, recycleTime);
}

public void replayDropTable(Database db, long tableId, boolean isForceDrop,
Long recycleTime) throws MetaNotFoundException {
Long recycleTime) throws MetaNotFoundException, DdlException {
getInternalCatalog().replayDropTable(db, tableId, isForceDrop, recycleTime);
}

Expand Down Expand Up @@ -5664,6 +5737,11 @@ public void renameTable(Database db, Table table, String newTableName) throws Dd
TableInfo tableInfo = TableInfo.createForTableRename(db.getId(), table.getId(), oldTableName,
newTableName);
editLog.logTableRename(tableInfo);
constraintManager.renameTable(
new TableNameInfo(InternalCatalog.INTERNAL_CATALOG_NAME,
db.getFullName(), oldTableName),
new TableNameInfo(InternalCatalog.INTERNAL_CATALOG_NAME,
db.getFullName(), newTableName));
LOG.info("rename table[{}] to {}", oldTableName, newTableName);
} finally {
table.writeUnlock();
Expand Down Expand Up @@ -5695,6 +5773,11 @@ public void replayRenameTable(TableInfo tableInfo) throws MetaNotFoundException
db.unregisterTable(tableName);
table.setName(newTableName);
db.registerTable(table);
constraintManager.renameTable(
new TableNameInfo(InternalCatalog.INTERNAL_CATALOG_NAME,
db.getFullName(), tableName),
new TableNameInfo(InternalCatalog.INTERNAL_CATALOG_NAME,
db.getFullName(), newTableName));
LOG.info("replay rename table[{}] to {}", tableName, newTableName);
} finally {
table.writeUnlock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.doris.datasource.hive.HMSExternalTable;
import org.apache.doris.datasource.hive.HiveExternalMetaCache;
import org.apache.doris.datasource.iceberg.IcebergExternalTable;
import org.apache.doris.info.TableNameInfo;
import org.apache.doris.persist.OperationType;

import com.google.common.base.Strings;
Expand Down Expand Up @@ -185,6 +186,9 @@ public void replayRefreshTable(ExternalObjectLog log) {
// this is a rename table op
db.get().unregisterTable(log.getTableName());
db.get().resetMetaCacheNames();
Env.getCurrentEnv().getConstraintManager().renameTable(
new TableNameInfo(catalog.getName(), log.getDbName(), log.getTableName()),
new TableNameInfo(catalog.getName(), log.getDbName(), log.getNewTableName()));
} else {
List<String> modifiedPartNames = log.getPartitionNames();
List<String> newPartNames = log.getNewPartitionNames();
Expand Down
16 changes: 8 additions & 8 deletions fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
package org.apache.doris.catalog;

import org.apache.doris.alter.AlterCancelException;
import org.apache.doris.catalog.constraint.Constraint;
import org.apache.doris.common.Config;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.ErrorCode;
Expand Down Expand Up @@ -121,6 +120,7 @@ public abstract class Table extends MetaObject implements Writable, TableIf, Gso
@SerializedName(value = "comment")
protected String comment = "";

@Deprecated
@SerializedName(value = "ta")
protected TableAttributes tableAttributes = new TableAttributes();

Expand Down Expand Up @@ -385,13 +385,13 @@ public String getDisplayName() {
return isTemporary ? Util.getTempTableDisplayName(name) : name;
}

public Constraint getConstraint(String name) {
return getConstraintsMap().get(name);
}

@Override
public Map<String, Constraint> getConstraintsMapUnsafe() {
return tableAttributes.getConstraintsMap();
/**
* @deprecated Use ConstraintManager for constraint access.
* This method will be removed in a future version.
*/
@Deprecated
public TableAttributes getTableAttributes() {
return tableAttributes;
}

public TableType getType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ public TableAttributes() {
this.visibleVersionTime = System.currentTimeMillis();
}

/**
* @deprecated Constraints are now managed by ConstraintManager.
* This method will be removed in a future version.
*/
@Deprecated
public Map<String, Constraint> getConstraintsMap() {
return constraintsMap;
}
Expand Down
Loading
Loading