Skip to content

Commit

Permalink
support alter table add property
Browse files Browse the repository at this point in the history
  • Loading branch information
acquamarin committed Jan 18, 2023
1 parent c9653c0 commit 67dba6c
Show file tree
Hide file tree
Showing 68 changed files with 4,828 additions and 3,486 deletions.
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ add_subdirectory(storage)
add_subdirectory(transaction)

add_library(kuzu STATIC ${ALL_OBJECT_FILES})
target_link_libraries(kuzu PUBLIC antlr4_cypher antlr4_runtime utf8proc
target_link_libraries(kuzu PUBLIC antlr4_cypher antlr4_runtime utf8proc
parquet_lib arrow_lib arrow_deps Threads::Threads)
target_include_directories(
kuzu PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
Expand Down
18 changes: 17 additions & 1 deletion src/antlr4/Cypher.g4
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,26 @@ kU_DropTable
DROP : ( 'D' | 'd' ) ( 'R' | 'r' ) ( 'O' | 'o' ) ( 'P' | 'p' ) ;

kU_AlterTable
: ALTER SP TABLE SP oC_SchemaName SP DROP SP oC_PropertyKeyName ;
: ALTER SP TABLE SP oC_SchemaName SP kU_AlterOptions ;

ALTER: ( 'A' | 'a' ) ( 'L' | 'l' ) ( 'T' | 't' ) ( 'E' | 'e' ) ( 'R' | 'r' ) ;

kU_AlterOptions
: kU_AddProperty
| kU_DropProperty;

kU_AddProperty
: ADD SP ( COLUMN 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 ;

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

COLUMN: ( 'C' | 'c' ) ( 'O' | 'o' ) ( 'L' | 'l' ) ( 'U' | 'u' ) ( 'M' | 'm' ) ( 'N' | 'n' ) ;

kU_RelConnections : kU_RelConnection ( SP? ',' SP? kU_RelConnection )* ;

kU_RelConnection: FROM SP kU_NodeLabels SP TO SP kU_NodeLabels ;
Expand Down
3 changes: 1 addition & 2 deletions src/binder/bind/bind_copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ unique_ptr<BoundStatement> Binder::bindCopy(const Statement& statement) {
auto tableName = copyCSV.getTableName();
validateTableExist(catalog, tableName);
auto isNodeTable = catalogContent->containNodeTable(tableName);
auto tableID = isNodeTable ? catalogContent->getNodeTableIDFromName(tableName) :
catalogContent->getRelTableIDFromName(tableName);
auto tableID = catalogContent->getTableID(tableName);
auto filePath = copyCSV.getCSVFileName();
auto csvReaderConfig = bindParsingOptions(copyCSV.getParsingOptions());
return make_unique<BoundCopy>(CopyDescription(filePath, csvReaderConfig), tableID, tableName);
Expand Down
24 changes: 20 additions & 4 deletions src/binder/bind/bind_ddl.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#include "binder/binder.h"
#include "binder/ddl/bound_add_property.h"
#include "binder/ddl/bound_create_node_clause.h"
#include "binder/ddl/bound_create_rel_clause.h"
#include "binder/ddl/bound_drop_property.h"
#include "binder/ddl/bound_drop_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"
Expand Down Expand Up @@ -49,8 +51,7 @@ unique_ptr<BoundStatement> Binder::bindDropTable(const Statement& statement) {
validateTableExist(catalog, tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto isNodeTable = catalogContent->containNodeTable(tableName);
auto tableID = isNodeTable ? catalogContent->getNodeTableIDFromName(tableName) :
catalogContent->getRelTableIDFromName(tableName);
auto tableID = catalogContent->getTableID(tableName);
if (isNodeTable) {
validateNodeTableHasNoEdge(catalog, tableID);
}
Expand All @@ -63,8 +64,7 @@ unique_ptr<BoundStatement> Binder::bindDropProperty(const Statement& statement)
validateTableExist(catalog, tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto isNodeTable = catalogContent->containNodeTable(tableName);
auto tableID = isNodeTable ? catalogContent->getNodeTableIDFromName(tableName) :
catalogContent->getRelTableIDFromName(tableName);
auto tableID = catalogContent->getTableID(tableName);
auto propertyID =
bindPropertyName(catalogContent->getTableSchema(tableID), dropProperty.getPropertyName());
if (isNodeTable &&
Expand All @@ -75,6 +75,22 @@ 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();
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.");
}
return make_unique<BoundAddProperty>(tableID, addProperty.getPropertyName(), dataType,
ExpressionBinder::implicitCastIfNecessary(
expressionBinder.bindExpression(*addProperty.getDefaultValue()), dataType),
tableName);
}

vector<PropertyNameDataType> Binder::bindPropertyNameDataTypes(
vector<pair<string, string>> propertyNameDataTypes) {
vector<PropertyNameDataType> boundPropertyNameDataTypes;
Expand Down
7 changes: 5 additions & 2 deletions src/binder/binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ unique_ptr<BoundStatement> Binder::bind(const Statement& statement) {
case StatementType::DROP_PROPERTY: {
return bindDropProperty(statement);
}
case StatementType::ADD_PROPERTY: {
return bindAddProperty(statement);
}
case StatementType::QUERY: {
return bindQuery((const RegularQuery&)statement);
}
Expand All @@ -38,14 +41,14 @@ table_id_t Binder::bindRelTableID(const string& tableName) const {
if (!catalog.getReadOnlyVersion()->containRelTable(tableName)) {
throw BinderException("Rel table " + tableName + " does not exist.");
}
return catalog.getReadOnlyVersion()->getRelTableIDFromName(tableName);
return catalog.getReadOnlyVersion()->getTableID(tableName);
}

table_id_t Binder::bindNodeTableID(const string& tableName) const {
if (!catalog.getReadOnlyVersion()->containNodeTable(tableName)) {
throw BinderException("Node table " + tableName + " does not exist.");
}
return catalog.getReadOnlyVersion()->getNodeTableIDFromName(tableName);
return catalog.getReadOnlyVersion()->getTableID(tableName);
}

shared_ptr<Expression> Binder::createVariable(const string& name, const DataType& dataType) {
Expand Down
8 changes: 7 additions & 1 deletion src/catalog/catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,15 @@ void Catalog::dropTableSchema(table_id_t tableID) {

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

void Catalog::addProperty(table_id_t tableID, string propertyName, DataType dataType) {
initCatalogContentForWriteTrxIfNecessary();
catalogContentForWriteTrx->getTableSchema(tableID)->addProperty(
std::move(propertyName), std::move(dataType));
}

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

property_id_t TableSchema::getPropertyID(string propertyName) const {
for (auto& property : properties) {
if (property.name == propertyName) {
return property.propertyID;
}
}
throw RuntimeException(
StringUtils::string_format("Table: %s doesn't have a property with propertyName=%s.",
tableName.c_str(), propertyName.c_str()));
}

Property TableSchema::getProperty(property_id_t propertyID) const {
for (auto& property : properties) {
if (property.propertyID == propertyID) {
return property;
}
}
throw RuntimeException(StringUtils::string_format(
"Table: %s doesn't have a property with propertyID=%d.", tableName.c_str(), propertyID));
}

unordered_set<table_id_t> RelTableSchema::getAllNodeTableIDs() const {
unordered_set<table_id_t> allNodeTableIDs;
for (auto& [srcTableID, dstTableID] : srcDstTableIDs) {
Expand Down
1 change: 1 addition & 0 deletions src/include/binder/binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Binder {
unique_ptr<BoundStatement> bindCreateRelClause(const Statement& statement);
unique_ptr<BoundStatement> bindDropTable(const Statement& statement);
unique_ptr<BoundStatement> bindDropProperty(const Statement& statement);
unique_ptr<BoundStatement> bindAddProperty(const Statement& statement);

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

#include "bound_ddl.h"

namespace kuzu {
namespace binder {

class BoundAddProperty : public BoundDDL {
public:
explicit BoundAddProperty(table_id_t tableID, string propertyName, DataType dataType,
shared_ptr<Expression> defaultValue, string tableName)
: BoundDDL{StatementType::ADD_PROPERTY, std::move(tableName)}, tableID{tableID},
propertyName{std::move(propertyName)}, dataType{std::move(dataType)}, defaultValue{
defaultValue} {}

inline table_id_t getTableID() const { return tableID; }

inline string getPropertyName() const { return propertyName; }

inline DataType getDataType() const { return dataType; }

inline shared_ptr<Expression> getDefaultValue() const { return defaultValue; }

private:
table_id_t tableID;
string propertyName;
DataType dataType;
shared_ptr<Expression> defaultValue;
};

} // namespace binder
} // namespace kuzu
14 changes: 5 additions & 9 deletions src/include/catalog/catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,10 @@ class CatalogContent {
return relTableNameToIDMap.contains(tableName);
}

inline table_id_t getNodeTableIDFromName(const string& tableName) const {
return nodeTableNameToIDMap.at(tableName);
inline table_id_t getTableID(const string& tableName) const {
return nodeTableNameToIDMap.contains(tableName) ? nodeTableNameToIDMap.at(tableName) :
relTableNameToIDMap.at(tableName);
}
inline table_id_t getRelTableIDFromName(const string& tableName) const {
return relTableNameToIDMap.at(tableName);
}

inline bool isSingleMultiplicityInDirection(table_id_t tableID, RelDirection direction) const {
return relTableSchemas.at(tableID)->isSingleMultiplicityInDirection(direction);
}
Expand Down Expand Up @@ -126,9 +123,6 @@ class CatalogContent {
return direction == FWD ? relTableSchema->getUniqueSrcTableIDs() :
relTableSchema->getUniqueDstTableIDs();
}
inline void dropProperty(table_id_t tableID, property_id_t propertyID) {
getTableSchema(tableID)->dropProperty(propertyID);
}

void dropTableSchema(table_id_t tableID);

Expand Down Expand Up @@ -199,6 +193,8 @@ class Catalog {

void dropProperty(table_id_t tableID, property_id_t propertyID);

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

protected:
unique_ptr<BuiltInVectorOperations> builtInVectorOperations;
unique_ptr<BuiltInAggregateFunctions> builtInAggregateFunctions;
Expand Down
37 changes: 26 additions & 11 deletions src/include/catalog/catalog_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,22 @@ struct PropertyNameDataType {
};

struct Property : PropertyNameDataType {
private:
Property(string name, DataType dataType, uint32_t propertyID, table_id_t tableID)
: PropertyNameDataType{std::move(name), std::move(dataType)},
propertyID{propertyID}, tableID{tableID} {}

public:
// This constructor is needed for ser/deser functions
Property() {}
Property() = default;

Property(string name, DataType dataType, property_id_t propertyID, table_id_t tableID)
: PropertyNameDataType{std::move(name), std::move(dataType)},
propertyID{propertyID}, tableID{tableID} {}

static Property constructNodeProperty(
const PropertyNameDataType& nameDataType, uint32_t propertyID, table_id_t tableID) {
return Property(nameDataType.name, nameDataType.dataType, propertyID, tableID);
const PropertyNameDataType& nameDataType, property_id_t propertyID, table_id_t tableID) {
return {nameDataType.name, nameDataType.dataType, propertyID, tableID};
}

static inline Property constructRelProperty(
const PropertyNameDataType& nameDataType, uint32_t propertyID, table_id_t tableID) {
return Property(nameDataType.name, nameDataType.dataType, propertyID, tableID);
const PropertyNameDataType& nameDataType, property_id_t propertyID, table_id_t tableID) {
return {nameDataType.name, nameDataType.dataType, propertyID, tableID};
}

property_id_t propertyID;
Expand All @@ -60,7 +59,8 @@ struct TableSchema {
public:
TableSchema(string tableName, table_id_t tableID, bool isNodeTable, vector<Property> properties)
: tableName{std::move(tableName)}, tableID{tableID}, isNodeTable{isNodeTable},
properties{std::move(properties)} {}
properties{std::move(properties)}, nextPropertyID{
(property_id_t)this->properties.size()} {}

virtual ~TableSchema() = default;

Expand All @@ -83,13 +83,28 @@ struct TableSchema {
[&propertyName](const Property& property) { return property.name == propertyName; });
}

inline void addProperty(string propertyName, DataType dataType) {
properties.emplace_back(
std::move(propertyName), std::move(dataType), increaseNextPropertyID(), tableID);
}

string getPropertyName(property_id_t propertyID) const;

property_id_t getPropertyID(string propertyName) const;

Property getProperty(property_id_t propertyID) const;

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

public:
string tableName;
table_id_t tableID;
bool isNodeTable;
vector<Property> properties;

private:
property_id_t nextPropertyID;
};

struct NodeTableSchema : TableSchema {
Expand Down
1 change: 1 addition & 0 deletions src/include/common/statement_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ enum class StatementType : uint8_t {
COPY_CSV = 3,
DROP_TABLE = 4,
DROP_PROPERTY = 5,
ADD_PROPERTY = 6,
};

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

#include "common/types/types.h"
#include "parser/ddl/ddl.h"
#include "parser/expression/parsed_expression.h"

namespace kuzu {
namespace parser {

using namespace std;

class AddProperty : public DDL {
public:
explicit AddProperty(string tableName, string propertyName, string dataType,
unique_ptr<ParsedExpression> defaultValue)
: DDL{StatementType::ADD_PROPERTY, std::move(tableName)}, propertyName{std::move(
propertyName)},
dataType{std::move(dataType)}, defaultValue{std::move(defaultValue)} {}

inline string getPropertyName() const { return propertyName; }

inline string getDataType() const { return dataType; }

inline ParsedExpression* getDefaultValue() const { return defaultValue.get(); }

private:
string propertyName;
string dataType;
unique_ptr<ParsedExpression> defaultValue;
};

} // namespace parser
} // namespace kuzu
1 change: 0 additions & 1 deletion src/include/parser/query/updating_clause/create_clause.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ class CreateClause : public UpdatingClause {
public:
CreateClause(vector<unique_ptr<PatternElement>> patternElements)
: UpdatingClause{ClauseType::CREATE}, patternElements{std::move(patternElements)} {};
~CreateClause() override = default;

inline const vector<unique_ptr<PatternElement>>& getPatternElements() const {
return patternElements;
Expand Down
4 changes: 4 additions & 0 deletions src/include/parser/transformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ class Transformer {

unique_ptr<Statement> transformAlterTable(CypherParser::KU_AlterTableContext& ctx);

unique_ptr<Statement> transformAddProperty(CypherParser::KU_AlterTableContext& ctx);

unique_ptr<Statement> transformDropProperty(CypherParser::KU_AlterTableContext& ctx);

string transformDataType(CypherParser::KU_DataTypeContext& ctx);

string transformListIdentifiers(CypherParser::KU_ListIdentifiersContext& ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace planner {

enum class LogicalOperatorType : uint8_t {
ACCUMULATE,
ADD_PROPERTY,
AGGREGATE,
COPY_CSV,
CREATE_NODE,
Expand Down
Loading

0 comments on commit 67dba6c

Please sign in to comment.