Skip to content

Commit

Permalink
[Feature] Support external catlog (StarRocks#17554)
Browse files Browse the repository at this point in the history
Change the id of DbPEntryObject and TablePEntryObject to uuid in string
format.

Signed-off-by: Dejun Xia <[email protected]>
  • Loading branch information
nshangyiming authored Feb 9, 2023
1 parent 7e2a178 commit 4d83213
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 91 deletions.
11 changes: 11 additions & 0 deletions fe/fe-core/src/main/java/com/starrocks/catalog/Database.java
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,17 @@ public long getId() {
return id;
}

/**
* Get the unique id of database in string format, since we already ensure
* the uniqueness of id for internal database, we just convert it to string
* and return, for external database it's up to the implementation of connector.
*
* @return unique id of database in string format
*/
public String getUUID() {
return Long.toString(id);
}

public String getOriginName() {
return fullQualifiedName;
}
Expand Down
11 changes: 11 additions & 0 deletions fe/fe-core/src/main/java/com/starrocks/catalog/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,17 @@ public long getId() {
return id;
}

/**
* Get the unique id of table in string format, since we already ensure
* the uniqueness of id for internal table, we just convert it to string
* and return, for external table it's up to the implementation of connector.
*
* @return unique id of table in string format
*/
public String getUUID() {
return Long.toString(id);
}

public void setId(long id) {
this.id = id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@
import java.util.Objects;

public class DbPEntryObject implements PEntryObject {
public static final long ALL_DATABASE_ID = -2; // -2 represent all
public static final String ALL_DATABASES_UUID = "ALL_DATABASES_UUID"; // represent all databases

@SerializedName(value = "i")
private long id;
private String uuid;

public long getId() {
return id;
public String getUUID() {
return uuid;
}

protected DbPEntryObject(String uuid) {
this.uuid = uuid;
}

public static DbPEntryObject generate(GlobalStateMgr mgr, List<String> tokens) throws PrivilegeException {
Expand All @@ -38,18 +42,23 @@ public static DbPEntryObject generate(GlobalStateMgr mgr, List<String> tokens) t
}

if (tokens.get(0).equals("*")) {
return new DbPEntryObject(ALL_DATABASE_ID);
return new DbPEntryObject(ALL_DATABASES_UUID);
}

Database database = mgr.getDb(tokens.get(0));
if (database == null) {
throw new PrivObjNotFoundException("cannot find db: " + tokens.get(0));
}
return new DbPEntryObject(database.getId());
return new DbPEntryObject(database.getUUID());
}

protected DbPEntryObject(long dbId) {
id = dbId;
public static DbPEntryObject generate(
List<String> allTypes, String restrictType, String restrictName) throws PrivilegeException {
// only support ON ALL DATABASE
if (allTypes.size() != 1 || restrictType != null || restrictName != null) {
throw new PrivilegeException("invalid ALL statement for databases! only support ON ALL DATABASES");
}
return new DbPEntryObject(ALL_DATABASES_UUID);
}

/**
Expand All @@ -65,25 +74,26 @@ public boolean match(Object obj) {
return false;
}
DbPEntryObject other = (DbPEntryObject) obj;
if (other.id == ALL_DATABASE_ID) {
if (Objects.equals(other.uuid, ALL_DATABASES_UUID)) {
return true;
}
return other.id == id;
return Objects.equals(other.uuid, uuid);
}

@Override
public boolean isFuzzyMatching() {
return ALL_DATABASE_ID == id;
return ALL_DATABASES_UUID.equals(uuid);
}

@Override
public boolean validate(GlobalStateMgr globalStateMgr) {
return globalStateMgr.getDbIncludeRecycleBin(this.id) != null;
// TODO(yiming): change validation method for external catalog
return globalStateMgr.getDbIncludeRecycleBin(Long.parseLong(this.uuid)) != null;
}

@Override
public PEntryObject clone() {
return new DbPEntryObject(id);
return new DbPEntryObject(uuid);
}

@Override
Expand All @@ -92,7 +102,17 @@ public int compareTo(PEntryObject obj) {
throw new ClassCastException("cannot cast " + obj.getClass().toString() + " to " + this.getClass());
}
DbPEntryObject o = (DbPEntryObject) obj;
return Long.compare(this.id, o.id);
// Always put the fuzzy matching object at the front of the privilege entry list
// when sorting in ascendant order.
if (Objects.equals(this.uuid, o.uuid)) {
return 0;
} else if (Objects.equals(this.uuid, ALL_DATABASES_UUID)) {
return -1;
} else if (Objects.equals(o.uuid, ALL_DATABASES_UUID)) {
return 1;
} else {
return this.uuid.compareTo(o.uuid);
}
}

@Override
Expand All @@ -104,11 +124,11 @@ public boolean equals(Object o) {
return false;
}
DbPEntryObject that = (DbPEntryObject) o;
return id == that.id;
return Objects.equals(uuid, that.uuid);
}

@Override
public int hashCode() {
return Objects.hash(id);
return Objects.hash(uuid);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,40 @@

public class MaterializedViewPEntryObject extends TablePEntryObject {

protected MaterializedViewPEntryObject(long databaseId, long tableId) {
super(databaseId, tableId);
protected MaterializedViewPEntryObject(String dbUUID, String tblUUID) {
super(dbUUID, tblUUID);
}

public static MaterializedViewPEntryObject generate(GlobalStateMgr mgr, List<String> tokens)
throws PrivilegeException {
if (tokens.size() != 2) {
throw new PrivilegeException("invalid object tokens, should have two: " + tokens);
}
long dbId;
long tableId;
String dbUUID;
String tblUUID;

if (tokens.get(0).equals("*")) {
dbId = ALL_DATABASE_ID;
tableId = ALL_TABLES_ID;
dbUUID = ALL_DATABASE_UUID;
tblUUID = ALL_TABLES_UUID;
} else {
Database database = mgr.getDb(tokens.get(0));
if (database == null) {
throw new PrivObjNotFoundException("cannot find db: " + tokens.get(0));
}
dbId = database.getId();
dbUUID = database.getUUID();

if (tokens.get(1).equals("*")) {
tableId = ALL_TABLES_ID;
tblUUID = ALL_TABLES_UUID;
} else {
Table table = database.getTable(tokens.get(1));
if (table == null || !table.getType().equals(Table.TableType.MATERIALIZED_VIEW)) {
throw new PrivObjNotFoundException(
"cannot find materialized view " + tokens.get(1) + " in db " + tokens.get(0));
}
tableId = table.getId();
tblUUID = table.getUUID();
}
}

return new MaterializedViewPEntryObject(dbId, tableId);
return new MaterializedViewPEntryObject(dbUUID, tblUUID);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,9 @@ public void initBuiltinRolesAndUsers() {
rolePrivilegeCollection = initBuiltinRoleUnlocked(PUBLIC_ROLE_ID, publicRoleName);
// GRANT SELECT ON ALL TABLES IN information_schema
List<PEntryObject> object = Collections.singletonList(new TablePEntryObject(
SystemId.INFORMATION_SCHEMA_DB_ID, TablePEntryObject.ALL_TABLES_ID));
rolePrivilegeCollection.grant(ObjectType.TABLE, Collections.singletonList(PrivilegeType.SELECT), object, false);
Long.toString(SystemId.INFORMATION_SCHEMA_DB_ID), TablePEntryObject.ALL_TABLES_UUID));
rolePrivilegeCollection.grant(ObjectType.TABLE, Collections.singletonList(PrivilegeType.SELECT), object,
false);

// 6. builtin user root
UserPrivilegeCollection rootCollection = new UserPrivilegeCollection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,56 +24,56 @@
import java.util.Objects;

public class TablePEntryObject implements PEntryObject {
public static final long ALL_DATABASE_ID = -2; // -2 represent all databases
public static final long ALL_TABLES_ID = -3; // -3 represent all tables
public static final String ALL_DATABASE_UUID = "ALL_DATABASES_UUID"; // represent all databases
public static final String ALL_TABLES_UUID = "ALL_TABLES_UUID"; // represent all tables

@SerializedName(value = "d")
protected long databaseId;
protected String databaseUUID;
@SerializedName(value = "t")
protected long tableId;
protected String tableUUID;

public long getDatabaseId() {
return databaseId;
public String getDatabaseUUID() {
return databaseUUID;
}

public long getTableId() {
return tableId;
public String getTableUUID() {
return tableUUID;
}

public static TablePEntryObject generate(GlobalStateMgr mgr, List<String> tokens) throws PrivilegeException {
if (tokens.size() != 2) {
throw new PrivilegeException("invalid object tokens, should have two: " + tokens);
}
long dbId;
long tableId;
String dbUUID;
String tblUUID;

if (tokens.get(0).equals("*")) {
dbId = ALL_DATABASE_ID;
tableId = ALL_TABLES_ID;
dbUUID = ALL_DATABASE_UUID;
tblUUID = ALL_TABLES_UUID;
} else {
Database database = mgr.getDb(tokens.get(0));
if (database == null) {
throw new PrivObjNotFoundException("cannot find db: " + tokens.get(0));
}
dbId = database.getId();
dbUUID = database.getUUID();

if (tokens.get(1).equals("*")) {
tableId = ALL_TABLES_ID;
tblUUID = ALL_TABLES_UUID;
} else {
Table table = database.getTable(tokens.get(1));
if (table == null) {
throw new PrivObjNotFoundException("cannot find table " + tokens.get(1) + " in db " + tokens.get(0));
}
tableId = table.getId();
tblUUID = table.getUUID();
}
}

return new TablePEntryObject(dbId, tableId);
return new TablePEntryObject(dbUUID, tblUUID);
}

protected TablePEntryObject(long databaseId, long tableId) {
this.tableId = tableId;
this.databaseId = databaseId;
protected TablePEntryObject(String databaseUUID, String tableUUID) {
this.tableUUID = tableUUID;
this.databaseUUID = databaseUUID;
}

/**
Expand All @@ -89,43 +89,56 @@ public boolean match(Object obj) {
return false;
}
TablePEntryObject other = (TablePEntryObject) obj;
if (other.databaseId == ALL_DATABASE_ID) {
if (Objects.equals(other.databaseUUID, ALL_DATABASE_UUID)) {
return true;
}
if (other.tableId == ALL_TABLES_ID) {
return databaseId == other.databaseId;
if (Objects.equals(other.tableUUID, ALL_TABLES_UUID)) {
return Objects.equals(databaseUUID, other.databaseUUID);
}
return other.databaseId == databaseId && other.tableId == tableId;
return Objects.equals(other.databaseUUID, databaseUUID) && Objects.equals(other.tableUUID, tableUUID);
}

@Override
public boolean isFuzzyMatching() {
return databaseId == ALL_DATABASE_ID || tableId == ALL_TABLES_ID;
return Objects.equals(databaseUUID, ALL_DATABASE_UUID) || Objects.equals(tableUUID, ALL_TABLES_UUID);
}


@Override
public boolean validate(GlobalStateMgr globalStateMgr) {
Database db = globalStateMgr.getDbIncludeRecycleBin(this.databaseId);
// TODO(yiming): change validation method for external catalog
Database db = globalStateMgr.getDbIncludeRecycleBin(Long.parseLong(this.databaseUUID));
if (db == null) {
return false;
}
return globalStateMgr.getTableIncludeRecycleBin(db, this.tableId) != null;
return globalStateMgr.getTableIncludeRecycleBin(db, Long.parseLong(this.tableUUID)) != null;
}

@Override
public int compareTo(PEntryObject obj) {
if (!(obj instanceof TablePEntryObject)) {
throw new ClassCastException("cannot cast " + obj.getClass().toString() + " to " + this.getClass());
}
TablePEntryObject o = (TablePEntryObject) obj;

if (this.databaseId > o.databaseId) {
return 1;
} else if (this.databaseId < o.databaseId) {
TablePEntryObject o = (TablePEntryObject) obj;
// Always put the fuzzy matching object at the front of the privilege entry list
// when sorting in ascendant order.
if (Objects.equals(this.databaseUUID, o.databaseUUID)) {
if (Objects.equals(this.tableUUID, o.tableUUID)) {
return 0;
} else if (Objects.equals(this.tableUUID, ALL_TABLES_UUID)) {
return -1;
} else if (Objects.equals(o.tableUUID, ALL_TABLES_UUID)) {
return 1;
} else {
return this.tableUUID.compareTo(o.tableUUID);
}
} else if (Objects.equals(this.databaseUUID, ALL_DATABASE_UUID)) {
return -1;
} else if (Objects.equals(o.databaseUUID, ALL_DATABASE_UUID)) {
return 1;
} else {
return Long.compare(this.tableId, o.tableId);
return this.databaseUUID.compareTo(o.databaseUUID);
}
}

Expand All @@ -138,16 +151,16 @@ public boolean equals(Object o) {
return false;
}
TablePEntryObject that = (TablePEntryObject) o;
return databaseId == that.databaseId && tableId == that.tableId;
return Objects.equals(databaseUUID, that.databaseUUID) && Objects.equals(tableUUID, that.tableUUID);
}

@Override
public int hashCode() {
return Objects.hash(databaseId, tableId);
return Objects.hash(databaseUUID, tableUUID);
}

@Override
public PEntryObject clone() {
return new TablePEntryObject(databaseId, tableId);
return new TablePEntryObject(databaseUUID, tableUUID);
}
}
Loading

0 comments on commit 4d83213

Please sign in to comment.