Skip to content

Commit

Permalink
Merge pull request #1198 from kuzudb/alter-rename
Browse files Browse the repository at this point in the history
add support to rename property/table
  • Loading branch information
acquamarin committed Jan 23, 2023
2 parents 299faf1 + 1963dc5 commit 9253d89
Show file tree
Hide file tree
Showing 34 changed files with 4,320 additions and 3,634 deletions.
16 changes: 13 additions & 3 deletions src/antlr4/Cypher.g4
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,25 @@ ALTER: ( 'A' | 'a' ) ( 'L' | 'l' ) ( 'T' | 't' ) ( 'E' | 'e' ) ( 'R' | 'r' ) ;

kU_AlterOptions
: kU_AddProperty
| kU_DropProperty;
| kU_DropProperty
| kU_RenameTable
| kU_RenameProperty;

kU_AddProperty
: ADD SP ( COLUMN SP )? oC_PropertyKeyName SP kU_DataType ( SP DEFAULT SP oC_Expression )? ;
: ADD SP oC_PropertyKeyName SP kU_DataType ( SP DEFAULT SP oC_Expression )? ;

DEFAULT : ( 'D' | 'd' ) ( 'E' | 'e' ) ( 'F' | 'f' ) ( 'A' | 'a' ) ( 'U' | 'u' ) ( 'L' | 'l' ) ( 'T' | 't' ) ;

kU_DropProperty
: DROP SP ( COLUMN SP )? oC_PropertyKeyName ;
: DROP SP oC_PropertyKeyName ;

kU_RenameTable
: RENAME SP TO SP oC_SchemaName ;

kU_RenameProperty
: RENAME SP oC_PropertyKeyName SP TO SP oC_PropertyKeyName ;

RENAME: ( 'R' | 'r' ) ( 'E' | 'e' ) ( 'N' | 'n' ) ( 'A' | 'a' ) ( 'M' | 'm' ) ( 'E' | 'e' ) ;

ADD: ( 'A' | 'a' ) ( 'D' | 'd' ) ( 'D' | 'd' ) ;

Expand Down
59 changes: 45 additions & 14 deletions src/binder/bind/bind_ddl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@
#include "binder/ddl/bound_create_rel_clause.h"
#include "binder/ddl/bound_drop_property.h"
#include "binder/ddl/bound_drop_table.h"
#include "binder/ddl/bound_rename_property.h"
#include "binder/ddl/bound_rename_table.h"
#include "parser/ddl/add_property.h"
#include "parser/ddl/create_node_clause.h"
#include "parser/ddl/create_rel_clause.h"
#include "parser/ddl/drop_property.h"
#include "parser/ddl/drop_table.h"
#include "parser/ddl/rename_property.h"
#include "parser/ddl/rename_table.h"

namespace kuzu {
namespace binder {

unique_ptr<BoundStatement> Binder::bindCreateNodeClause(const Statement& statement) {
auto& createNodeClause = (CreateNodeClause&)statement;
auto tableName = createNodeClause.getTableName();
if (catalog.getReadOnlyVersion()->containNodeTable(tableName)) {
if (catalog.getReadOnlyVersion()->containTable(tableName)) {
throw BinderException("Node " + tableName + " already exists.");
}
auto boundPropertyNameDataTypes =
Expand All @@ -30,7 +34,7 @@ unique_ptr<BoundStatement> Binder::bindCreateNodeClause(const Statement& stateme
unique_ptr<BoundStatement> Binder::bindCreateRelClause(const Statement& statement) {
auto& createRelClause = (CreateRelClause&)statement;
auto tableName = createRelClause.getTableName();
if (catalog.getReadOnlyVersion()->containRelTable(tableName)) {
if (catalog.getReadOnlyVersion()->containTable(tableName)) {
throw BinderException("Rel " + tableName + " already exists.");
}
auto propertyNameDataTypes =
Expand All @@ -50,14 +54,41 @@ unique_ptr<BoundStatement> Binder::bindDropTable(const Statement& statement) {
auto tableName = dropTable.getTableName();
validateTableExist(catalog, tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto isNodeTable = catalogContent->containNodeTable(tableName);
auto tableID = catalogContent->getTableID(tableName);
if (isNodeTable) {
if (catalogContent->containNodeTable(tableName)) {
validateNodeTableHasNoEdge(catalog, tableID);
}
return make_unique<BoundDropTable>(tableID, tableName);
}

unique_ptr<BoundStatement> Binder::bindRenameTable(const Statement& statement) {
auto renameTable = (RenameTable&)statement;
auto tableName = renameTable.getTableName();
auto catalogContent = catalog.getReadOnlyVersion();
validateTableExist(catalog, tableName);
if (catalogContent->containTable(renameTable.getNewName())) {
throw BinderException("Table: " + renameTable.getNewName() + " already exists.");
}
return make_unique<BoundRenameTable>(
catalogContent->getTableID(tableName), tableName, renameTable.getNewName());
}

unique_ptr<BoundStatement> Binder::bindAddProperty(const Statement& statement) {
auto& addProperty = (AddProperty&)statement;
auto tableName = addProperty.getTableName();
validateTableExist(catalog, tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto tableID = catalogContent->getTableID(tableName);
auto dataType = Types::dataTypeFromString(addProperty.getDataType());
if (catalogContent->getTableSchema(tableID)->containProperty(addProperty.getPropertyName())) {
throw BinderException("Property: " + addProperty.getPropertyName() + " already exists.");
}
auto defaultVal = ExpressionBinder::implicitCastIfNecessary(
expressionBinder.bindExpression(*addProperty.getDefaultValue()), dataType);
return make_unique<BoundAddProperty>(
tableID, addProperty.getPropertyName(), dataType, defaultVal, tableName);
}

unique_ptr<BoundStatement> Binder::bindDropProperty(const Statement& statement) {
auto& dropProperty = (DropProperty&)statement;
auto tableName = dropProperty.getTableName();
Expand All @@ -75,20 +106,20 @@ unique_ptr<BoundStatement> Binder::bindDropProperty(const Statement& statement)
return make_unique<BoundDropProperty>(tableID, propertyID, tableName);
}

unique_ptr<BoundStatement> Binder::bindAddProperty(const Statement& statement) {
auto& addProperty = (AddProperty&)statement;
auto tableName = addProperty.getTableName();
unique_ptr<BoundStatement> Binder::bindRenameProperty(const Statement& statement) {
auto& renameProperty = (RenameProperty&)statement;
auto tableName = renameProperty.getTableName();
validateTableExist(catalog, tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto tableID = catalogContent->getTableID(tableName);
auto dataType = Types::dataTypeFromString(addProperty.getDataType());
if (catalogContent->getTableSchema(tableID)->containProperty(addProperty.getPropertyName())) {
throw BinderException("Property: " + addProperty.getPropertyName() + " already exists.");
auto tableSchema = catalogContent->getTableSchema(tableID);
auto propertyID = bindPropertyName(tableSchema, renameProperty.getPropertyName());
if (tableSchema->containProperty(renameProperty.getNewName())) {
throw BinderException("Property " + renameProperty.getNewName() +
" already exists in table: " + tableName + ".");
}
return make_unique<BoundAddProperty>(tableID, addProperty.getPropertyName(), dataType,
ExpressionBinder::implicitCastIfNecessary(
expressionBinder.bindExpression(*addProperty.getDefaultValue()), dataType),
tableName);
return make_unique<BoundRenameProperty>(
tableID, tableName, propertyID, renameProperty.getNewName());
}

vector<PropertyNameDataType> Binder::bindPropertyNameDataTypes(
Expand Down
14 changes: 10 additions & 4 deletions src/binder/binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,23 @@ unique_ptr<BoundStatement> Binder::bind(const Statement& statement) {
case StatementType::CREATE_REL_CLAUSE: {
return bindCreateRelClause(statement);
}
case StatementType::COPY_CSV: {
return bindCopy(statement);
}
case StatementType::DROP_TABLE: {
return bindDropTable(statement);
}
case StatementType::COPY_CSV: {
return bindCopy(statement);
case StatementType::RENAME_TABLE: {
return bindRenameTable(statement);
}
case StatementType::ADD_PROPERTY: {
return bindAddProperty(statement);
}
case StatementType::DROP_PROPERTY: {
return bindDropProperty(statement);
}
case StatementType::ADD_PROPERTY: {
return bindAddProperty(statement);
case StatementType::RENAME_PROPERTY: {
return bindRenameProperty(statement);
}
case StatementType::QUERY: {
return bindQuery((const RegularQuery&)statement);
Expand Down
24 changes: 21 additions & 3 deletions src/catalog/catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ void CatalogContent::dropTableSchema(table_id_t tableID) {
}
}

void CatalogContent::renameTable(table_id_t tableID, string newName) {
auto tableSchema = getTableSchema(tableID);
auto& tableNameToIDMap = tableSchema->isNodeTable ? nodeTableNameToIDMap : relTableNameToIDMap;
tableNameToIDMap.erase(tableSchema->tableName);
tableNameToIDMap.emplace(newName, tableID);
tableSchema->tableName = newName;
}

void CatalogContent::saveToFile(const string& directory, DBFileType dbFileType) {
auto catalogPath = StorageUtils::getCatalogFilePath(directory, dbFileType);
auto fileInfo = FileUtils::openFile(catalogPath, O_WRONLY | O_CREAT);
Expand Down Expand Up @@ -378,10 +386,9 @@ void Catalog::dropTableSchema(table_id_t tableID) {
wal->logDropTableRecord(tableID);
}

void Catalog::dropProperty(table_id_t tableID, property_id_t propertyID) {
void Catalog::renameTable(table_id_t tableID, string newName) {
initCatalogContentForWriteTrxIfNecessary();
catalogContentForWriteTrx->getTableSchema(tableID)->dropProperty(propertyID);
wal->logDropPropertyRecord(tableID, propertyID);
catalogContentForWriteTrx->renameTable(tableID, newName);
}

void Catalog::addProperty(table_id_t tableID, string propertyName, DataType dataType) {
Expand All @@ -392,5 +399,16 @@ void Catalog::addProperty(table_id_t tableID, string propertyName, DataType data
catalogContentForWriteTrx->getTableSchema(tableID)->getPropertyID(std::move(propertyName)));
}

void Catalog::dropProperty(table_id_t tableID, property_id_t propertyID) {
initCatalogContentForWriteTrxIfNecessary();
catalogContentForWriteTrx->getTableSchema(tableID)->dropProperty(propertyID);
wal->logDropPropertyRecord(tableID, propertyID);
}

void Catalog::renameProperty(table_id_t tableID, property_id_t propertyID, string newName) {
initCatalogContentForWriteTrxIfNecessary();
catalogContentForWriteTrx->getTableSchema(tableID)->renameProperty(propertyID, newName);
}

} // namespace catalog
} // namespace kuzu
10 changes: 10 additions & 0 deletions src/catalog/catalog_structs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ Property TableSchema::getProperty(property_id_t propertyID) const {
"Table: %s doesn't have a property with propertyID=%d.", tableName.c_str(), propertyID));
}

void TableSchema::renameProperty(property_id_t propertyID, const string& newName) {
for (auto& property : properties) {
if (property.propertyID == propertyID) {
property.name = newName;
return;
}
}
throw InternalException("Property with id=" + to_string(propertyID) + " not found.");
}

unordered_set<table_id_t> RelTableSchema::getAllNodeTableIDs() const {
unordered_set<table_id_t> allNodeTableIDs;
for (auto& [srcTableID, dstTableID] : srcDstTableIDs) {
Expand Down
4 changes: 3 additions & 1 deletion src/include/binder/binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ class Binder {
unique_ptr<BoundStatement> bindCreateNodeClause(const Statement& statement);
unique_ptr<BoundStatement> bindCreateRelClause(const Statement& statement);
unique_ptr<BoundStatement> bindDropTable(const Statement& statement);
unique_ptr<BoundStatement> bindDropProperty(const Statement& statement);
unique_ptr<BoundStatement> bindRenameTable(const Statement& statement);
unique_ptr<BoundStatement> bindAddProperty(const Statement& statement);
unique_ptr<BoundStatement> bindDropProperty(const Statement& statement);
unique_ptr<BoundStatement> bindRenameProperty(const Statement& statement);

vector<PropertyNameDataType> bindPropertyNameDataTypes(
vector<pair<string, string>> propertyNameDataTypes);
Expand Down
28 changes: 28 additions & 0 deletions src/include/binder/ddl/bound_rename_property.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include "bound_ddl.h"

namespace kuzu {
namespace binder {

class BoundRenameProperty : public BoundDDL {
public:
explicit BoundRenameProperty(
table_id_t tableID, string tableName, property_id_t propertyID, string newName)
: BoundDDL{StatementType::RENAME_PROPERTY, std::move(tableName)}, tableID{tableID},
propertyID{propertyID}, newName{std::move(newName)} {}

inline table_id_t getTableID() const { return tableID; }

inline property_id_t getPropertyID() const { return propertyID; }

inline string getNewName() const { return newName; }

private:
table_id_t tableID;
property_id_t propertyID;
string newName;
};

} // namespace binder
} // namespace kuzu
24 changes: 24 additions & 0 deletions src/include/binder/ddl/bound_rename_table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "bound_ddl.h"

namespace kuzu {
namespace binder {

class BoundRenameTable : public BoundDDL {
public:
explicit BoundRenameTable(table_id_t tableID, string tableName, string newName)
: BoundDDL{StatementType::RENAME_TABLE, std::move(tableName)}, tableID{tableID},
newName{std::move(newName)} {}

inline table_id_t getTableID() const { return tableID; }

inline string getNewName() const { return newName; }

private:
table_id_t tableID;
string newName;
};

} // namespace binder
} // namespace kuzu
11 changes: 10 additions & 1 deletion src/include/catalog/catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class CatalogContent {
inline bool containRelTable(table_id_t tableID) const {
return relTableSchemas.contains(tableID);
}
inline bool containTable(const string& name) const {
return containNodeTable(name) || containRelTable(name);
}

inline string getTableName(table_id_t tableID) const {
return getTableSchema(tableID)->tableName;
Expand Down Expand Up @@ -126,6 +129,8 @@ class CatalogContent {

void dropTableSchema(table_id_t tableID);

void renameTable(table_id_t tableID, string newName);

void saveToFile(const string& directory, DBFileType dbFileType);
void readFromFile(const string& directory, DBFileType dbFileType);

Expand Down Expand Up @@ -191,10 +196,14 @@ class Catalog {

void dropTableSchema(table_id_t tableID);

void dropProperty(table_id_t tableID, property_id_t propertyID);
void renameTable(table_id_t tableID, string newName);

void addProperty(table_id_t tableID, string propertyName, DataType dataType);

void dropProperty(table_id_t tableID, property_id_t propertyID);

void renameProperty(table_id_t tableID, property_id_t propertyID, string newName);

protected:
unique_ptr<BuiltInVectorOperations> builtInVectorOperations;
unique_ptr<BuiltInAggregateFunctions> builtInAggregateFunctions;
Expand Down
2 changes: 2 additions & 0 deletions src/include/catalog/catalog_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ struct TableSchema {

Property getProperty(property_id_t propertyID) const;

void renameProperty(property_id_t propertyID, const string& newName);

private:
inline property_id_t increaseNextPropertyID() { return nextPropertyID++; }

Expand Down
4 changes: 3 additions & 1 deletion src/include/common/statement_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ enum class StatementType : uint8_t {
CREATE_REL_CLAUSE = 2,
COPY_CSV = 3,
DROP_TABLE = 4,
DROP_PROPERTY = 5,
RENAME_TABLE = 5,
ADD_PROPERTY = 6,
DROP_PROPERTY = 7,
RENAME_PROPERTY = 8,
};

class StatementTypeUtils {
Expand Down
26 changes: 26 additions & 0 deletions src/include/parser/ddl/rename_property.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "parser/ddl/ddl.h"

namespace kuzu {
namespace parser {

using namespace std;

class RenameProperty : public DDL {
public:
explicit RenameProperty(string tableName, string propertyName, string newName)
: DDL{StatementType::RENAME_PROPERTY, std::move(tableName)},
propertyName{std::move(propertyName)}, newName{std::move(newName)} {}

inline string getPropertyName() const { return propertyName; }

inline string getNewName() const { return newName; }

private:
string propertyName;
string newName;
};

} // namespace parser
} // namespace kuzu
22 changes: 22 additions & 0 deletions src/include/parser/ddl/rename_table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include "parser/ddl/ddl.h"

namespace kuzu {
namespace parser {

using namespace std;

class RenameTable : public DDL {
public:
explicit RenameTable(string tableName, string newName)
: DDL{StatementType::RENAME_TABLE, std::move(tableName)}, newName{std::move(newName)} {}

inline string getNewName() const { return newName; }

private:
string newName;
};

} // namespace parser
} // namespace kuzu
Loading

0 comments on commit 9253d89

Please sign in to comment.