Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alter table add column #1186

Merged
merged 1 commit into from
Jan 19, 2023
Merged
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
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' ) ;
acquamarin marked this conversation as resolved.
Show resolved Hide resolved

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