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

Refactor ALTER statement #2097

Merged
merged 1 commit into from
Sep 27, 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
138 changes: 89 additions & 49 deletions src/binder/bind/bind_ddl.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
#include "binder/binder.h"
#include "binder/ddl/bound_add_property.h"
#include "binder/ddl/bound_alter.h"
#include "binder/ddl/bound_create_table.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 "catalog/node_table_schema.h"
#include "catalog/rel_table_schema.h"
#include "common/exception/binder.h"
#include "common/string_utils.h"
#include "parser/ddl/add_property.h"
#include "parser/ddl/alter.h"
#include "parser/ddl/create_table.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"
#include "parser/ddl/drop.h"

using namespace kuzu::common;
using namespace kuzu::parser;
Expand Down Expand Up @@ -219,11 +213,11 @@
throw BinderException(tableName + " already exists in catalog.");
}
auto boundCreateInfo = bindCreateTableInfo(createTable.getInfo());
return std::make_unique<BoundCreateTable>(tableName, std::move(boundCreateInfo));
return std::make_unique<BoundCreateTable>(std::move(boundCreateInfo));
}

std::unique_ptr<BoundStatement> Binder::bindDropTable(const Statement& statement) {
auto& dropTable = (DropTable&)statement;
auto& dropTable = reinterpret_cast<const Drop&>(statement);
auto tableName = dropTable.getTableName();
validateNodeRelTableExist(tableName);
auto catalogContent = catalog.getReadOnlyVersion();
Expand All @@ -234,76 +228,122 @@
return make_unique<BoundDropTable>(tableID, tableName);
}

std::unique_ptr<BoundStatement> Binder::bindAlter(const parser::Statement& statement) {
auto& alter = reinterpret_cast<const Alter&>(statement);
switch (alter.getInfo()->type) {
case AlterType::RENAME_TABLE: {
return bindRenameTable(statement);
}
case AlterType::ADD_PROPERTY: {
return bindAddProperty(statement);
}
case AlterType::DROP_PROPERTY: {
return bindDropProperty(statement);
}
case AlterType::RENAME_PROPERTY: {
return bindRenameProperty(statement);
}
default:
throw NotImplementedException("Binder::bindAlter");

Check warning on line 247 in src/binder/bind/bind_ddl.cpp

View check run for this annotation

Codecov / codecov/patch

src/binder/bind/bind_ddl.cpp#L246-L247

Added lines #L246 - L247 were not covered by tests
}
}

std::unique_ptr<BoundStatement> Binder::bindRenameTable(const Statement& statement) {
auto renameTable = (RenameTable&)statement;
auto tableName = renameTable.getTableName();
auto& alter = reinterpret_cast<const Alter&>(statement);
auto info = alter.getInfo();
auto extraInfo = reinterpret_cast<ExtraRenameTableInfo*>(info->extraInfo.get());
auto tableName = info->tableName;
auto newName = extraInfo->newName;
auto catalogContent = catalog.getReadOnlyVersion();
validateNodeRelTableExist(tableName);
if (catalogContent->containsTable(renameTable.getNewName())) {
throw BinderException("Table: " + renameTable.getNewName() + " already exists.");
if (catalogContent->containsTable(newName)) {
throw BinderException("Table: " + newName + " already exists.");
}
auto tableID = catalogContent->getTableID(tableName);
auto boundExtraInfo = std::make_unique<BoundExtraRenameTableInfo>(newName);
auto boundInfo = std::make_unique<BoundAlterInfo>(
AlterType::RENAME_TABLE, tableName, tableID, std::move(boundExtraInfo));
return std::make_unique<BoundAlter>(std::move(boundInfo));
}

static void validatePropertyExist(TableSchema* tableSchema, const std::string& propertyName) {
if (!tableSchema->containProperty(propertyName)) {
throw BinderException(
tableSchema->tableName + " table doesn't have property " + propertyName + ".");
}
}

static void validatePropertyNotExist(TableSchema* tableSchema, const std::string& propertyName) {
if (tableSchema->containProperty(propertyName)) {
throw BinderException(
tableSchema->tableName + " table already has property " + propertyName + ".");
}
return make_unique<BoundRenameTable>(
catalogContent->getTableID(tableName), tableName, renameTable.getNewName());
}

std::unique_ptr<BoundStatement> Binder::bindAddProperty(const Statement& statement) {
auto& addProperty = (AddProperty&)statement;
auto tableName = addProperty.getTableName();
auto& alter = reinterpret_cast<const Alter&>(statement);
auto info = alter.getInfo();
auto extraInfo = reinterpret_cast<ExtraAddPropertyInfo*>(info->extraInfo.get());
auto tableName = info->tableName;
auto dataType = bindDataType(extraInfo->dataType);
auto propertyName = extraInfo->propertyName;
validateNodeRelTableExist(tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto tableID = catalogContent->getTableID(tableName);
auto dataType = bindDataType(addProperty.getDataType());
if (catalogContent->getTableSchema(tableID)->containProperty(addProperty.getPropertyName())) {
throw BinderException("Property: " + addProperty.getPropertyName() + " already exists.");
}
auto tableSchema = catalogContent->getTableSchema(tableID);
validatePropertyNotExist(tableSchema, propertyName);
if (dataType->getLogicalTypeID() == LogicalTypeID::SERIAL) {
throw BinderException("Serial property in node table must be the primary key.");
}
auto defaultVal = ExpressionBinder::implicitCastIfNecessary(
expressionBinder.bindExpression(*addProperty.getDefaultValue()), *dataType);
return make_unique<BoundAddProperty>(
tableID, addProperty.getPropertyName(), std::move(dataType), defaultVal, tableName);
expressionBinder.bindExpression(*extraInfo->defaultValue), *dataType);
auto boundExtraInfo = std::make_unique<BoundExtraAddPropertyInfo>(
propertyName, dataType->copy(), std::move(defaultVal));
auto boundInfo = std::make_unique<BoundAlterInfo>(
AlterType::ADD_PROPERTY, tableName, tableID, std::move(boundExtraInfo));
return std::make_unique<BoundAlter>(std::move(boundInfo));
}

std::unique_ptr<BoundStatement> Binder::bindDropProperty(const Statement& statement) {
auto& dropProperty = (DropProperty&)statement;
auto tableName = dropProperty.getTableName();
auto& alter = reinterpret_cast<const Alter&>(statement);
auto info = alter.getInfo();
auto extraInfo = reinterpret_cast<ExtraDropPropertyInfo*>(info->extraInfo.get());
auto tableName = info->tableName;
auto propertyName = extraInfo->propertyName;
validateNodeRelTableExist(tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto tableID = catalogContent->getTableID(tableName);
auto tableSchema = catalogContent->getTableSchema(tableID);
auto propertyID = bindPropertyName(tableSchema, dropProperty.getPropertyName());
validatePropertyExist(tableSchema, propertyName);
auto propertyID = tableSchema->getPropertyID(propertyName);
if (tableSchema->getTableType() == TableType::NODE &&
reinterpret_cast<NodeTableSchema*>(tableSchema)->getPrimaryKeyPropertyID() == propertyID) {
throw BinderException("Cannot drop primary key of a node table.");
}
return make_unique<BoundDropProperty>(tableID, propertyID, tableName);
auto boundExtraInfo = std::make_unique<BoundExtraDropPropertyInfo>(propertyID);
auto boundInfo = std::make_unique<BoundAlterInfo>(
AlterType::DROP_PROPERTY, tableName, tableID, std::move(boundExtraInfo));
return make_unique<BoundAlter>(std::move(boundInfo));
}

std::unique_ptr<BoundStatement> Binder::bindRenameProperty(const Statement& statement) {
auto& renameProperty = (RenameProperty&)statement;
auto tableName = renameProperty.getTableName();
auto& alter = reinterpret_cast<const Alter&>(statement);
auto info = alter.getInfo();
auto extraInfo = reinterpret_cast<ExtraRenamePropertyInfo*>(info->extraInfo.get());
auto tableName = info->tableName;
auto propertyName = extraInfo->propertyName;
auto newName = extraInfo->newName;
validateNodeRelTableExist(tableName);
auto catalogContent = catalog.getReadOnlyVersion();
auto tableID = catalogContent->getTableID(tableName);
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<BoundRenameProperty>(
tableID, tableName, propertyID, renameProperty.getNewName());
}

property_id_t Binder::bindPropertyName(TableSchema* tableSchema, const std::string& propertyName) {
for (auto& property : tableSchema->properties) {
if (property->getName() == propertyName) {
return property->getPropertyID();
}
}
throw BinderException(
tableSchema->tableName + " table doesn't have property: " + propertyName + ".");
validatePropertyExist(tableSchema, propertyName);
auto propertyID = tableSchema->getPropertyID(propertyName);
validatePropertyNotExist(tableSchema, newName);
auto boundExtraInfo = std::make_unique<BoundExtraRenamePropertyInfo>(propertyID, newName);
auto boundInfo = std::make_unique<BoundAlterInfo>(
AlterType::RENAME_PROPERTY, tableName, tableID, std::move(boundExtraInfo));
return std::make_unique<BoundAlter>(std::move(boundInfo));
}

} // namespace binder
Expand Down
13 changes: 2 additions & 11 deletions src/binder/binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,8 @@ std::unique_ptr<BoundStatement> Binder::bind(const Statement& statement) {
case StatementType::DROP_TABLE: {
boundStatement = bindDropTable(statement);
} break;
case StatementType::RENAME_TABLE: {
boundStatement = bindRenameTable(statement);
} break;
case StatementType::ADD_PROPERTY: {
boundStatement = bindAddProperty(statement);
} break;
case StatementType::DROP_PROPERTY: {
boundStatement = bindDropProperty(statement);
} break;
case StatementType::RENAME_PROPERTY: {
boundStatement = bindRenameProperty(statement);
case StatementType::ALTER: {
boundStatement = bindAlter(statement);
} break;
case StatementType::QUERY: {
boundStatement = bindQuery((const RegularQuery&)statement);
Expand Down
17 changes: 5 additions & 12 deletions src/binder/bound_statement_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,14 @@ void BoundStatementVisitor::visit(const kuzu::binder::BoundStatement& statement)
case StatementType::DROP_TABLE: {
visitDropTable(statement);
} break;
case StatementType::RENAME_TABLE: {
visitRenameTable(statement);
case StatementType::ALTER: {
visitAlter(statement);
} break;
case StatementType::ADD_PROPERTY: {
visitAddProperty(statement);
case StatementType::COPY_FROM: {
visitCopyFrom(statement);
} break;
case StatementType::DROP_PROPERTY: {
visitDropProperty(statement);
} break;
case StatementType::RENAME_PROPERTY: {
visitRenameProperty(statement);
} break;
case StatementType::COPY_FROM:
case StatementType::COPY_TO: {
visitCopy(statement);
visitCopyTo(statement);
} break;
case StatementType::STANDALONE_CALL: {
visitStandaloneCall(statement);
Expand Down
4 changes: 1 addition & 3 deletions src/include/binder/binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,12 @@ class Binder {
std::unique_ptr<BoundStatement> bindCreateTable(const parser::Statement& statement);

std::unique_ptr<BoundStatement> bindDropTable(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindAlter(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindRenameTable(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindAddProperty(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindDropProperty(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindRenameProperty(const parser::Statement& statement);

common::property_id_t bindPropertyName(
catalog::TableSchema* tableSchema, const std::string& propertyName);

/*** bind copy ***/
std::unique_ptr<BoundStatement> bindCopyFromClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindCopyNodeFrom(
Expand Down
8 changes: 3 additions & 5 deletions src/include/binder/bound_statement_visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@ class BoundStatementVisitor {
protected:
virtual void visitCreateTable(const BoundStatement& statement) {}
virtual void visitDropTable(const BoundStatement& statement) {}
virtual void visitRenameTable(const BoundStatement& statement) {}
virtual void visitAddProperty(const BoundStatement& statement) {}
virtual void visitDropProperty(const BoundStatement& statement) {}
virtual void visitRenameProperty(const BoundStatement& statement) {}
virtual void visitCopy(const BoundStatement& statement) {}
virtual void visitAlter(const BoundStatement& statement) {}
virtual void visitCopyFrom(const BoundStatement& statement) {}
virtual void visitCopyTo(const BoundStatement& statement) {}
virtual void visitStandaloneCall(const BoundStatement& statement) {}
virtual void visitCommentOn(const BoundStatement& statement) {}
virtual void visitExplain(const BoundStatement& statement);
Expand Down
33 changes: 0 additions & 33 deletions src/include/binder/ddl/bound_add_property.h

This file was deleted.

23 changes: 23 additions & 0 deletions src/include/binder/ddl/bound_alter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include "binder/bound_statement.h"
#include "bound_alter_info.h"

namespace kuzu {
namespace binder {

class BoundAlter : public BoundStatement {
public:
BoundAlter(std::unique_ptr<BoundAlterInfo> info)
: BoundStatement{common::StatementType::ALTER,
BoundStatementResult::createSingleStringColumnResult()},
info{std::move(info)} {}

inline BoundAlterInfo* getInfo() const { return info.get(); }

private:
std::unique_ptr<BoundAlterInfo> info;
};

} // namespace binder
} // namespace kuzu
Loading