[feature](multi-catalog) add catalog comment and create time info (#18778)

add catalog comment and create time info
```
create catalog hms_ctl
comment 'your comment' 
properties (
'type'='hms',
'hive.metastore.uris' = 'thrift://xx:1234' );
```
Create Time will generate when the catalog is created.

use show catalogs and show create catalog to get these info.
This commit is contained in:
slothever
2023-04-19 15:08:42 +08:00
committed by GitHub
parent 1a25f110ec
commit 93b35bbfbf
14 changed files with 121 additions and 37 deletions

View File

@ -36,17 +36,23 @@ import java.util.Map;
*/
public class AlterCatalogPropertyStmt extends DdlStmt {
private final String catalogName;
private final String comment;
private final Map<String, String> newProperties;
public AlterCatalogPropertyStmt(String catalogName, Map<String, String> newProperties) {
this.catalogName = catalogName;
this.newProperties = newProperties;
this.comment = newProperties.getOrDefault("comment", "");
}
public String getCatalogName() {
return catalogName;
}
public String getComment() {
return comment;
}
public Map<String, String> getNewProperties() {
return newProperties;
}

View File

@ -32,24 +32,30 @@ import org.apache.doris.qe.ConnectContext;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;
/**
* Statement for create a new catalog.
*/
public class CreateCatalogStmt extends DdlStmt {
public static final String CREATE_TIME_PROP = "create_time";
private final boolean ifNotExists;
private final String catalogName;
private final String resource;
private final String comment;
private final Map<String, String> properties;
/**
* Statement for create a new catalog.
*/
public CreateCatalogStmt(boolean ifNotExists, String catalogName, String resource, Map<String, String> properties) {
public CreateCatalogStmt(boolean ifNotExists, String catalogName, String resource, Map<String, String> properties,
String comment) {
this.ifNotExists = ifNotExists;
this.catalogName = catalogName;
this.resource = resource == null ? "" : resource;
this.resource = Strings.nullToEmpty(resource);
this.comment = Strings.nullToEmpty(comment);
this.properties = properties == null ? Maps.newHashMap() : properties;
}
@ -61,6 +67,10 @@ public class CreateCatalogStmt extends DdlStmt {
return resource;
}
public String getComment() {
return comment;
}
public Map<String, String> getProperties() {
return properties;
}
@ -82,6 +92,8 @@ public class CreateCatalogStmt extends DdlStmt {
ErrorReport.reportAnalysisException(ErrorCode.ERR_CATALOG_ACCESS_DENIED,
analyzer.getQualifiedUser(), catalogName);
}
String currentDateTime = LocalDateTime.now(ZoneId.systemDefault()).toString().replace("T", " ");
properties.put(CREATE_TIME_PROP, currentDateTime);
PropertyAnalyzer.checkCatalogProperties(properties, false);
}
@ -97,6 +109,9 @@ public class CreateCatalogStmt extends DdlStmt {
if (!Strings.isNullOrEmpty(resource)) {
stringBuilder.append(" WITH RESOURCE `").append(resource).append("`");
}
if (!Strings.isNullOrEmpty(comment)) {
stringBuilder.append("\nCOMMENT \"").append(comment).append("\"");
}
if (properties.size() > 0) {
stringBuilder.append("\nPROPERTIES (\n");
stringBuilder.append(new PrintableMap<>(properties, "=", true, true, false));

View File

@ -31,6 +31,8 @@ public class ShowCatalogStmt extends ShowStmt {
.addColumn(new Column("CatalogName", ScalarType.createVarchar(64)))
.addColumn(new Column("Type", ScalarType.createStringType()))
.addColumn(new Column("IsCurrent", ScalarType.createStringType()))
.addColumn(new Column("CreateTime", ScalarType.createStringType()))
.addColumn(new Column("Comment", ScalarType.createStringType()))
.build();
private static final ShowResultSetMetaData META_DATA_SPECIFIC =

View File

@ -48,12 +48,17 @@ public class CatalogFactory {
log.setCatalogId(catalogId);
log.setCatalogName(((CreateCatalogStmt) stmt).getCatalogName());
log.setResource(((CreateCatalogStmt) stmt).getResource());
log.setComment(((CreateCatalogStmt) stmt).getComment());
log.setProps(((CreateCatalogStmt) stmt).getProperties());
} else if (stmt instanceof DropCatalogStmt) {
log.setCatalogId(catalogId);
} else if (stmt instanceof AlterCatalogPropertyStmt) {
log.setCatalogId(catalogId);
log.setNewProps(((AlterCatalogPropertyStmt) stmt).getNewProperties());
String newComment = ((AlterCatalogPropertyStmt) stmt).getComment();
if (!Strings.isNullOrEmpty(newComment)) {
log.setComment(newComment);
}
} else if (stmt instanceof AlterCatalogNameStmt) {
log.setCatalogId(catalogId);
log.setNewCatalogName(((AlterCatalogNameStmt) stmt).getNewCatalogName());
@ -70,11 +75,12 @@ public class CatalogFactory {
* create the catalog instance from catalog log.
*/
public static CatalogIf constructorFromLog(CatalogLog log) throws DdlException {
return constructorCatalog(log.getCatalogId(), log.getCatalogName(), log.getResource(), log.getProps());
return constructorCatalog(log.getCatalogId(), log.getCatalogName(), log.getResource(),
log.getComment(), log.getProps());
}
private static CatalogIf constructorCatalog(
long catalogId, String name, String resource, Map<String, String> props) throws DdlException {
private static CatalogIf constructorCatalog(long catalogId, String name, String resource, String comment,
Map<String, String> props) throws DdlException {
// get catalog type from resource or properties
String catalogType;
if (!Strings.isNullOrEmpty(resource)) {
@ -116,6 +122,9 @@ public class CatalogFactory {
default:
throw new DdlException("Unknown catalog type: " + catalogType);
}
if (catalog instanceof ExternalCatalog && !Strings.isNullOrEmpty(comment)) {
((ExternalCatalog) catalog).setComment(comment);
}
return catalog;
}
}

View File

@ -143,4 +143,6 @@ public interface CatalogIf<T extends DatabaseIf> {
default void onClose() {
Env.getCurrentEnv().getRefreshManager().removeFromRefreshMap(getId());
}
String getComment();
}

View File

@ -59,6 +59,8 @@ public class CatalogLog implements Writable {
@SerializedName(value = "resource")
private String resource;
@SerializedName(value = "comment")
private String comment;
@Override
public void write(DataOutput out) throws IOException {

View File

@ -373,6 +373,10 @@ public class CatalogMgr implements Writable, GsonPostProcessable {
} else {
row.add("");
}
Map<String, String> props = catalog.getProperties();
String createTime = props.getOrDefault(CreateCatalogStmt.CREATE_TIME_PROP, "UNRECORDED");
row.add(createTime);
row.add(catalog.getComment());
rows.add(row);
}
@ -421,8 +425,11 @@ public class CatalogMgr implements Writable, GsonPostProcessable {
throw new AnalysisException("No catalog found with name " + showStmt.getCatalog());
}
StringBuilder sb = new StringBuilder();
sb.append("CREATE CATALOG `").append(ClusterNamespace.getNameFromFullName(showStmt.getCatalog()))
sb.append("\nCREATE CATALOG `").append(ClusterNamespace.getNameFromFullName(showStmt.getCatalog()))
.append("`");
if (!com.google.common.base.Strings.isNullOrEmpty(catalog.getComment())) {
sb.append("\nCOMMENT \"").append(catalog.getComment()).append("\"\n");
}
if (catalog.getProperties().size() > 0) {
sb.append(" PROPERTIES (\n");
sb.append(new PrintableMap<>(catalog.getProperties(), "=", true, true, true, true));

View File

@ -82,6 +82,7 @@ public abstract class ExternalCatalog implements CatalogIf<ExternalDatabase>, Wr
protected boolean invalidCacheInInit = true;
private ExternalSchemaCache schemaCache;
private String comment;
public ExternalCatalog(long catalogId, String name) {
this.id = catalogId;
@ -251,6 +252,15 @@ public abstract class ExternalCatalog implements CatalogIf<ExternalDatabase>, Wr
return type;
}
@Override
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
@Override
public List<String> getDbNames() {
return listDatabaseNames(null);
@ -321,10 +331,16 @@ public abstract class ExternalCatalog implements CatalogIf<ExternalDatabase>, Wr
@Override
public void modifyCatalogProps(Map<String, String> props) {
modifyComment(props);
catalogProperty.modifyCatalogProps(props);
notifyPropertiesUpdated(props);
}
private void modifyComment(Map<String, String> props) {
setComment(props.getOrDefault("comment", comment));
props.remove("comment");
}
@Override
public void write(DataOutput out) throws IOException {
Text.writeString(out, GsonUtils.GSON.toJson(this));

View File

@ -236,6 +236,11 @@ public class InternalCatalog implements CatalogIf<Database> {
return "internal";
}
@Override
public String getComment() {
return "Doris internal catalog";
}
@Override
public String getName() {
return INTERNAL_CATALOG_NAME;