Skip to content

Commit

Permalink
Merge pull request #2009 from kuzudb/issue-1888
Browse files Browse the repository at this point in the history
Support defining multiple FROM TO in CREATE REL TABLE GROUP
  • Loading branch information
andyfengHKU committed Sep 8, 2023
2 parents d03d306 + 8fd6d3f commit 46f4039
Show file tree
Hide file tree
Showing 55 changed files with 4,790 additions and 4,101 deletions.
21 changes: 14 additions & 7 deletions src/antlr4/Cypher.g4
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,33 @@ COPY : ( 'C' | 'c' ) ( 'O' | 'o' ) ( 'P' | 'p') ( 'Y' | 'y' ) ;

FROM : ( 'F' | 'f' ) ( 'R' | 'r' ) ( 'O' | 'o' ) ( 'M' | 'm' ) ;

NPY : ( 'N' | 'n' ) ( 'P' | 'p' ) ( 'Y' | 'y' ) ;

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

kU_DDL
: kU_CreateNode
| kU_CreateRel
: kU_CreateNodeTable
| kU_CreateRelTable
| kU_CreateRelTableGroup
| kU_CreateRdfGraph
| kU_DropTable
| kU_AlterTable;

kU_CreateNode
kU_CreateNodeTable
: CREATE SP NODE SP TABLE SP oC_SchemaName SP? '(' SP? kU_PropertyDefinitions SP? ( ',' SP? kU_CreateNodeConstraint ) SP? ')' ;

NODE : ( 'N' | 'n' ) ( 'O' | 'o' ) ( 'D' | 'd' ) ( 'E' | 'e' ) ;

TABLE: ( 'T' | 't' ) ( 'A' | 'a' ) ( 'B' | 'b' ) ( 'L' | 'l' ) ( 'E' | 'e' ) ;

kU_CreateRel
: CREATE SP REL SP TABLE SP oC_SchemaName SP? '(' SP? FROM SP oC_SchemaName SP TO SP oC_SchemaName SP? ( ',' SP? kU_PropertyDefinitions SP? )? ( ',' SP? oC_SymbolicName SP? )? ')' ;
kU_CreateRelTable
: CREATE SP REL SP TABLE SP oC_SchemaName SP? '(' SP? kU_RelTableConnection SP? ( ',' SP? kU_PropertyDefinitions SP? )? ( ',' SP? oC_SymbolicName SP? )? ')' ;

kU_CreateRelTableGroup
: CREATE SP REL SP TABLE SP GROUP SP oC_SchemaName SP? '(' SP? kU_RelTableConnection SP ? (',' SP? kU_RelTableConnection)+ SP? ( ',' SP? kU_PropertyDefinitions SP? )? ( ',' SP? oC_SymbolicName SP? )? ')' ;

GROUP : ( 'G' | 'g' ) ( 'R' | 'r' ) ( 'O' | 'o' ) ( 'U' | 'u' ) ( 'P' | 'p' ) ;

kU_RelTableConnection
: FROM SP oC_SchemaName SP TO SP oC_SchemaName ;

kU_CreateRdfGraph
: CREATE SP RDF SP GRAPH SP oC_SchemaName ;
Expand Down
1 change: 1 addition & 0 deletions src/binder/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_subdirectory(bind)
add_subdirectory(bind_expression)
add_subdirectory(copy)
add_subdirectory(ddl)
add_subdirectory(expression)
add_subdirectory(query)
add_subdirectory(rewriter)
Expand Down
293 changes: 162 additions & 131 deletions src/binder/bind/bind_ddl.cpp

Large diffs are not rendered by default.

20 changes: 7 additions & 13 deletions src/binder/binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,8 @@ namespace binder {
std::unique_ptr<BoundStatement> Binder::bind(const Statement& statement) {
std::unique_ptr<BoundStatement> boundStatement;
switch (statement.getStatementType()) {
case StatementType::CREATE_NODE_TABLE: {
boundStatement = bindCreateNodeTableClause(statement);
} break;
case StatementType::CREATE_REL_TABLE: {
boundStatement = bindCreateRelTableClause(statement);
} break;
case StatementType::CREATE_RDF_GRAPH: {
boundStatement = bindCreateRdfGraphClause(statement);
case StatementType::CREATE_TABLE: {
boundStatement = bindCreateTable(statement);
} break;
case StatementType::COPY_FROM: {
boundStatement = bindCopyFromClause(statement);
Expand All @@ -30,19 +24,19 @@ std::unique_ptr<BoundStatement> Binder::bind(const Statement& statement) {
boundStatement = bindCopyToClause(statement);
} break;
case StatementType::DROP_TABLE: {
boundStatement = bindDropTableClause(statement);
boundStatement = bindDropTable(statement);
} break;
case StatementType::RENAME_TABLE: {
boundStatement = bindRenameTableClause(statement);
boundStatement = bindRenameTable(statement);
} break;
case StatementType::ADD_PROPERTY: {
boundStatement = bindAddPropertyClause(statement);
boundStatement = bindAddProperty(statement);
} break;
case StatementType::DROP_PROPERTY: {
boundStatement = bindDropPropertyClause(statement);
boundStatement = bindDropProperty(statement);
} break;
case StatementType::RENAME_PROPERTY: {
boundStatement = bindRenamePropertyClause(statement);
boundStatement = bindRenameProperty(statement);
} break;
case StatementType::QUERY: {
boundStatement = bindQuery((const RegularQuery&)statement);
Expand Down
10 changes: 2 additions & 8 deletions src/binder/bound_statement_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,8 @@ void BoundStatementVisitor::visit(const kuzu::binder::BoundStatement& statement)
case StatementType::QUERY: {
visitRegularQuery((BoundRegularQuery&)statement);
} break;
case StatementType::CREATE_NODE_TABLE: {
visitCreateNodeTable(statement);
} break;
case StatementType::CREATE_REL_TABLE: {
visitCreateRelTable(statement);
} break;
case StatementType::CREATE_RDF_GRAPH: {
visitCreateRdfGraph(statement);
case StatementType::CREATE_TABLE: {
visitCreateTable(statement);
} break;
case StatementType::DROP_TABLE: {
visitDropTable(statement);
Expand Down
8 changes: 8 additions & 0 deletions src/binder/ddl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_library(
kuzu_binder_ddl
OBJECT
bound_create_table_info.cpp)

set(ALL_OBJECT_FILES
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:kuzu_binder_ddl>
PARENT_SCOPE)
17 changes: 17 additions & 0 deletions src/binder/ddl/bound_create_table_info.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "binder/ddl/bound_create_table_info.h"

namespace kuzu {
namespace binder {

std::vector<std::unique_ptr<BoundCreateTableInfo>> BoundCreateTableInfo::copy(
const std::vector<std::unique_ptr<BoundCreateTableInfo>>& infos) {
std::vector<std::unique_ptr<BoundCreateTableInfo>> result;
result.reserve(infos.size());
for (auto& info : infos) {
result.push_back(info->copy());
}
return result;
}

} // namespace binder
} // namespace kuzu
3 changes: 2 additions & 1 deletion src/catalog/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ add_library(kuzu_catalog
catalog.cpp
catalog_content.cpp
table_schema.cpp
property.cpp)
property.cpp
rel_table_group_schema.cpp)

set(ALL_OBJECT_FILES
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:kuzu_catalog>
Expand Down
14 changes: 14 additions & 0 deletions src/catalog/catalog.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "catalog/catalog.h"

#include "catalog/rel_table_group_schema.h"
#include "common/ser_deser.h"
#include "common/string_utils.h"
#include "storage/storage_utils.h"
Expand Down Expand Up @@ -52,6 +53,19 @@ table_id_t Catalog::addRelTableSchema(const binder::BoundCreateTableInfo& info)
return tableID;
}

common::table_id_t Catalog::addRelTableGroupSchema(const binder::BoundCreateTableInfo& info) {
initCatalogContentForWriteTrxIfNecessary();
auto tableID = catalogContentForWriteTrx->addRelTableGroupSchema(info);
auto relTableGroupSchema =
(RelTableGroupSchema*)catalogContentForWriteTrx->getTableSchema(tableID);
// TODO(Ziyi): remove this when we can log variable size record. See also wal_record.h
for (auto relTableID : relTableGroupSchema->getRelTableIDs()) {
wal->logRelTableRecord(relTableID);
}
wal->logRelTableGroupRecord(tableID, relTableGroupSchema->getRelTableIDs());
return tableID;
}

common::table_id_t Catalog::addRdfGraphSchema(const binder::BoundCreateTableInfo& info) {
initCatalogContentForWriteTrxIfNecessary();
auto tableID = catalogContentForWriteTrx->addRdfGraphSchema(info);
Expand Down
32 changes: 24 additions & 8 deletions src/catalog/catalog_content.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "catalog/catalog_content.h"

#include "catalog/rel_table_group_schema.h"
#include "common/ser_deser.h"
#include "common/string_utils.h"
#include "storage/storage_utils.h"
Expand Down Expand Up @@ -31,9 +32,9 @@ static void assignPropertyIDAndTableID(

table_id_t CatalogContent::addNodeTableSchema(const BoundCreateTableInfo& info) {
table_id_t tableID = assignNextTableID();
auto properties = Property::copy(info.properties);
auto extraInfo = reinterpret_cast<BoundExtraCreateNodeTableInfo*>(info.extraInfo.get());
auto properties = Property::copy(extraInfo->properties);
assignPropertyIDAndTableID(properties, tableID);
auto extraInfo = (BoundNodeExtraCreateTableInfo*)info.extraInfo.get();
auto nodeTableSchema = std::make_unique<NodeTableSchema>(
info.tableName, tableID, extraInfo->primaryKeyIdx, std::move(properties));
tableNameToIDMap.emplace(nodeTableSchema->tableName, tableID);
Expand All @@ -50,10 +51,10 @@ static void addRelInternalIDProperty(std::vector<std::unique_ptr<Property>>& pro

table_id_t CatalogContent::addRelTableSchema(const BoundCreateTableInfo& info) {
table_id_t tableID = assignNextTableID();
auto properties = Property::copy(info.properties);
auto extraInfo = reinterpret_cast<BoundExtraCreateRelTableInfo*>(info.extraInfo.get());
auto properties = Property::copy(extraInfo->properties);
addRelInternalIDProperty(properties);
assignPropertyIDAndTableID(properties, tableID);
auto extraInfo = (BoundRelExtraCreateTableInfo*)info.extraInfo.get();
getNodeTableSchema(extraInfo->srcTableID)->addFwdRelTableID(tableID);
getNodeTableSchema(extraInfo->dstTableID)->addBwdRelTableID(tableID);
auto relTableSchema = std::make_unique<RelTableSchema>(info.tableName, tableID,
Expand All @@ -64,13 +65,28 @@ table_id_t CatalogContent::addRelTableSchema(const BoundCreateTableInfo& info) {
return tableID;
}

common::table_id_t CatalogContent::addRdfGraphSchema(const BoundCreateTableInfo& info) {
table_id_t CatalogContent::addRelTableGroupSchema(const binder::BoundCreateTableInfo& info) {
table_id_t relTableGroupID = assignNextTableID();
auto extraInfo = (BoundExtraCreateRelTableGroupInfo*)info.extraInfo.get();
std::vector<table_id_t> relTableIDs;
relTableIDs.reserve(extraInfo->infos.size());
for (auto& childInfo : extraInfo->infos) {
relTableIDs.push_back(addRelTableSchema(*childInfo));
}
auto relTableGroupName = info.tableName;
auto relTableGroupSchema = std::make_unique<RelTableGroupSchema>(
relTableGroupName, relTableGroupID, std::move(relTableIDs));
tableNameToIDMap.emplace(relTableGroupName, relTableGroupID);
tableSchemas.emplace(relTableGroupID, std::move(relTableGroupSchema));
return relTableGroupID;
}

table_id_t CatalogContent::addRdfGraphSchema(const BoundCreateTableInfo& info) {
table_id_t rdfGraphID = assignNextTableID();
auto extraInfo = (BoundRdfExtraCreateTableInfo*)info.extraInfo.get();
auto extraInfo = reinterpret_cast<BoundExtraCreateRdfGraphInfo*>(info.extraInfo.get());
auto nodeInfo = extraInfo->nodeInfo.get();
auto relInfo = extraInfo->relInfo.get();
auto nodeExtraInfo = (BoundNodeExtraCreateTableInfo*)nodeInfo->extraInfo.get();
auto relExtraInfo = (BoundRelExtraCreateTableInfo*)relInfo->extraInfo.get();
auto relExtraInfo = (BoundExtraCreateRelTableInfo*)relInfo->extraInfo.get();
// Node table schema
auto nodeTableID = addNodeTableSchema(*nodeInfo);
// Rel table schema
Expand Down
22 changes: 22 additions & 0 deletions src/catalog/rel_table_group_schema.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "catalog/rel_table_group_schema.h"

#include "common/ser_deser.h"

using namespace kuzu::common;

namespace kuzu {
namespace catalog {

void RelTableGroupSchema::serializeInternal(FileInfo* fileInfo, uint64_t& offset) {
SerDeser::serializeVector(relTableIDs, fileInfo, offset);
}

std::unique_ptr<RelTableGroupSchema> RelTableGroupSchema::deserialize(
FileInfo* fileInfo, uint64_t& offset) {
std::vector<table_id_t> relTableIDs;
SerDeser::deserializeVector(relTableIDs, fileInfo, offset);
return std::make_unique<RelTableGroupSchema>(std::move(relTableIDs));
}

} // namespace catalog
} // namespace kuzu
4 changes: 4 additions & 0 deletions src/catalog/table_schema.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "catalog/table_schema.h"

#include "catalog/rel_table_group_schema.h"
#include "common/exception.h"
#include "common/ser_deser.h"
#include "common/string_utils.h"
Expand Down Expand Up @@ -124,6 +125,9 @@ std::unique_ptr<TableSchema> TableSchema::deserialize(FileInfo* fileInfo, uint64
case TableType::REL: {
result = RelTableSchema::deserialize(fileInfo, offset);
} break;
case TableType::REL_GROUP: {
result = RelTableGroupSchema::deserialize(fileInfo, offset);
} break;
case TableType::RDF: {
result = RdfGraphSchema::deserialize(fileInfo, offset);
} break;
Expand Down
35 changes: 21 additions & 14 deletions src/include/binder/binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#include "parser/query/regular_query.h"

namespace kuzu {
namespace parser {
struct CreateTableInfo;
}

namespace main {
class ClientContext;
}
Expand Down Expand Up @@ -80,22 +84,25 @@ class Binder {
const std::string& name, const common::LogicalType& dataType);

/*** bind DDL ***/
std::unique_ptr<BoundStatement> bindCreateNodeTableClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindCreateRelTableClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindCreateRdfGraphClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindDropTableClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindRenameTableClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindAddPropertyClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindDropPropertyClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindRenamePropertyClause(const parser::Statement& statement);

std::vector<std::unique_ptr<catalog::Property>> bindProperties(
std::vector<std::pair<std::string, std::string>> propertyNameDataTypes);
uint32_t bindPrimaryKey(const std::string& pkColName,
std::vector<std::pair<std::string, std::string>> propertyNameDataTypes);
std::unique_ptr<BoundCreateTableInfo> bindCreateTableInfo(const parser::CreateTableInfo* info);
std::unique_ptr<BoundCreateTableInfo> bindCreateNodeTableInfo(
const parser::CreateTableInfo* info);
std::unique_ptr<BoundCreateTableInfo> bindCreateRelTableInfo(
const parser::CreateTableInfo* info);
std::unique_ptr<BoundCreateTableInfo> bindCreateRelTableGroupInfo(
const parser::CreateTableInfo* info);
std::unique_ptr<BoundCreateTableInfo> bindCreateRdfGraphInfo(
const parser::CreateTableInfo* info);
std::unique_ptr<BoundStatement> bindCreateTable(const parser::Statement& statement);

std::unique_ptr<BoundStatement> bindDropTable(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::NodeTableSchema::TableSchema* tableSchema, const std::string& propertyName);
std::unique_ptr<common::LogicalType> bindDataType(const std::string& dataType);

/*** bind copy from/to ***/
static bool bindContainsSerial(
Expand Down
4 changes: 1 addition & 3 deletions src/include/binder/bound_statement_visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ class BoundStatementVisitor {
virtual void visitQueryPart(const NormalizedQueryPart& queryPart);

protected:
virtual void visitCreateNodeTable(const BoundStatement& statement) {}
virtual void visitCreateRelTable(const BoundStatement& statement) {}
virtual void visitCreateRdfGraph(const BoundStatement& statement) {}
virtual void visitCreateTable(const BoundStatement& statement) {}
virtual void visitDropTable(const BoundStatement& statement) {}
virtual void visitRenameTable(const BoundStatement& statement) {}
virtual void visitAddProperty(const BoundStatement& statement) {}
Expand Down
6 changes: 3 additions & 3 deletions src/include/binder/ddl/bound_create_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace binder {

class BoundCreateTable : public BoundDDL {
public:
explicit BoundCreateTable(common::StatementType statementType, std::string tableName,
std::unique_ptr<BoundCreateTableInfo> info)
: BoundDDL{statementType, std::move(tableName)}, info{std::move(info)} {}
explicit BoundCreateTable(std::string tableName, std::unique_ptr<BoundCreateTableInfo> info)
: BoundDDL{common::StatementType::CREATE_TABLE, std::move(tableName)}, info{std::move(
info)} {}

inline BoundCreateTableInfo* getBoundCreateTableInfo() const { return info.get(); }

Expand Down
Loading

0 comments on commit 46f4039

Please sign in to comment.