Skip to content

Refactor rel group #5280

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

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
89 changes: 31 additions & 58 deletions src/binder/bind/bind_ddl.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

#include "binder/binder.h"
#include "binder/ddl/bound_alter.h"
#include "binder/ddl/bound_create_sequence.h"
Expand All @@ -8,7 +9,6 @@
#include "catalog/catalog.h"
#include "catalog/catalog_entry/index_catalog_entry.h"
#include "catalog/catalog_entry/rel_group_catalog_entry.h"
#include "catalog/catalog_entry/rel_table_catalog_entry.h"
#include "catalog/catalog_entry/sequence_catalog_entry.h"
#include "common/enums/extend_direction_util.h"
#include "common/exception/binder.h"
Expand Down Expand Up @@ -127,10 +127,6 @@ void Binder::validateNoIndexOnProperty(const std::string& tableName,
const std::string& propertyName) const {
auto transaction = clientContext->getTransaction();
auto catalog = clientContext->getCatalog();
if (catalog->containsRelGroup(transaction, tableName)) {
// RelGroup does not have indexes.
return;
}
auto tableEntry = catalog->getTableCatalogEntry(transaction, tableName);
if (!tableEntry->containsProperty(propertyName)) {
return;
Expand All @@ -151,13 +147,10 @@ void Binder::validateNoIndexOnProperty(const std::string& tableName,

BoundCreateTableInfo Binder::bindCreateTableInfo(const CreateTableInfo* info) {
switch (info->type) {
case CatalogEntryType::NODE_TABLE_ENTRY: {
case TableType::NODE: {
return bindCreateNodeTableInfo(info);
}
case CatalogEntryType::REL_TABLE_ENTRY: {
return bindCreateRelTableInfo(info);
}
case CatalogEntryType::REL_GROUP_ENTRY: {
case TableType::REL_GROUP: {
return bindCreateRelTableGroupInfo(info);
}
default: {
Expand Down Expand Up @@ -205,68 +198,48 @@ static ExtendDirection getStorageDirection(const case_insensitive_map_t<Value>&
return DEFAULT_EXTEND_DIRECTION;
}

BoundCreateTableInfo Binder::bindCreateRelTableInfo(const CreateTableInfo* info) {
auto& extraInfo = info->extraInfo->constCast<ExtraCreateRelTableInfo>();
return bindCreateRelTableInfo(info, extraInfo.options);
}

BoundCreateTableInfo Binder::bindCreateRelTableInfo(const CreateTableInfo* info,
const options_t& parsedOptions) {
std::vector<PropertyDefinition> Binder::bindRelPropertyDefinitions(const CreateTableInfo& info) {
std::vector<PropertyDefinition> propertyDefinitions;
propertyDefinitions.emplace_back(
ColumnDefinition(InternalKeyword::ID, LogicalType::INTERNAL_ID()));
for (auto& definition : bindPropertyDefinitions(info->propertyDefinitions, info->tableName)) {
for (auto& definition : bindPropertyDefinitions(info.propertyDefinitions, info.tableName)) {
propertyDefinitions.push_back(definition.copy());
}
auto& extraInfo = info->extraInfo->constCast<ExtraCreateRelTableInfo>();
auto srcMultiplicity = RelMultiplicityUtils::getFwd(extraInfo.relMultiplicity);
auto dstMultiplicity = RelMultiplicityUtils::getBwd(extraInfo.relMultiplicity);
auto srcEntry = bindNodeTableEntry(extraInfo.srcTableName);
validateNodeTableType(srcEntry);
auto dstEntry = bindNodeTableEntry(extraInfo.dstTableName);
validateNodeTableType(dstEntry);
auto boundOptions = bindParsingOptions(parsedOptions);
auto storageDirection = getStorageDirection(boundOptions);
auto boundExtraInfo = std::make_unique<BoundExtraCreateRelTableInfo>(srcMultiplicity,
dstMultiplicity, storageDirection, srcEntry->getTableID(), dstEntry->getTableID(),
std::move(propertyDefinitions));
return BoundCreateTableInfo(CatalogEntryType::REL_TABLE_ENTRY, info->tableName,
info->onConflict, std::move(boundExtraInfo), clientContext->useInternalCatalogEntry());
return propertyDefinitions;
}

static void validateUniqueFromToPairs(
const std::vector<std::pair<std::string, std::string>>& pairs) {
std::unordered_set<std::string> set;
for (auto [from, to] : pairs) {
auto key = from + to;
if (set.contains(key)) {
throw BinderException(stringFormat("Found duplicate FROM-TO {}-{} pairs.", from, to));
std::vector<common::NodePair> Binder::bindNodePairs(
const std::vector<std::pair<std::string, std::string>>& srcDstTablePairs) {
std::unordered_set<common::NodePair, NodePairHash, NodePairEqual> nodePairs;
for (auto& [srcTableName, dstTableName] : srcDstTablePairs) {
auto srcEntry = bindNodeTableEntry(srcTableName);
validateNodeTableType(srcEntry);
auto dstEntry = bindNodeTableEntry(dstTableName);
validateNodeTableType(dstEntry);
NodePair nodePair{srcEntry->getTableID(), dstEntry->getTableID()};
if (nodePairs.contains(nodePair)) {
throw BinderException(
stringFormat("Found duplicate FROM-TO {}-{} pairs.", srcTableName, dstTableName));
}
set.insert(key);
nodePairs.insert(nodePair);
}
std::vector<common::NodePair> result;
result.insert(result.end(), nodePairs.begin(), nodePairs.end());
return result;
}

BoundCreateTableInfo Binder::bindCreateRelTableGroupInfo(const CreateTableInfo* info) {
auto relGroupName = info->tableName;
auto propertyDefinitions = bindRelPropertyDefinitions(*info);
auto& extraInfo = info->extraInfo->constCast<ExtraCreateRelTableGroupInfo>();
auto relMultiplicity = extraInfo.relMultiplicity;
std::vector<BoundCreateTableInfo> boundCreateRelTableInfos;
auto relCreateInfo =
std::make_unique<CreateTableInfo>(CatalogEntryType::REL_TABLE_ENTRY, "", info->onConflict);
relCreateInfo->propertyDefinitions = copyVector(info->propertyDefinitions);
validateUniqueFromToPairs(extraInfo.srcDstTablePairs);
for (auto& [srcTableName, dstTableName] : extraInfo.srcDstTablePairs) {
relCreateInfo->tableName =
RelGroupCatalogEntry::getChildTableName(relGroupName, srcTableName, dstTableName);
relCreateInfo->extraInfo = std::make_unique<ExtraCreateRelTableInfo>(relMultiplicity,
srcTableName, dstTableName, options_t{});
auto boundInfo = bindCreateRelTableInfo(relCreateInfo.get(), extraInfo.options);
boundInfo.hasParent = true;
boundCreateRelTableInfos.push_back(std::move(boundInfo));
}
auto srcMultiplicity = RelMultiplicityUtils::getFwd(extraInfo.relMultiplicity);
auto dstMultiplicity = RelMultiplicityUtils::getBwd(extraInfo.relMultiplicity);
auto boundOptions = bindParsingOptions(extraInfo.options);
auto storageDirection = getStorageDirection(boundOptions);
auto nodePairs = bindNodePairs(extraInfo.srcDstTablePairs);
auto boundExtraInfo =
std::make_unique<BoundExtraCreateRelTableGroupInfo>(std::move(boundCreateRelTableInfos));
return BoundCreateTableInfo(CatalogEntryType::REL_GROUP_ENTRY, info->tableName,
std::make_unique<BoundExtraCreateRelTableGroupInfo>(std::move(propertyDefinitions),
srcMultiplicity, dstMultiplicity, storageDirection, std::move(nodePairs));
return BoundCreateTableInfo(CatalogEntryType::REL_TABLE_ENTRY, info->tableName,
info->onConflict, std::move(boundExtraInfo), clientContext->useInternalCatalogEntry());
}

Expand Down
21 changes: 13 additions & 8 deletions src/binder/bind/bind_export_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "catalog/catalog.h"
#include "catalog/catalog_entry/index_catalog_entry.h"
#include "catalog/catalog_entry/node_table_catalog_entry.h"
#include "catalog/catalog_entry/rel_table_catalog_entry.h"
#include "catalog/catalog_entry/rel_group_catalog_entry.h"
#include "common/exception/binder.h"
#include "common/file_system/virtual_file_system.h"
#include "common/string_utils.h"
Expand Down Expand Up @@ -63,15 +63,20 @@ static void bindExportNodeTableDataQuery(const TableCatalogEntry& entry, std::st
exportQuery = stringFormat("match (a:`{}`) return a.*", entry.getName());
}

static void bindExportRelTableDataQuery(const TableCatalogEntry& entry, std::string& exportQuery,
// Todo(Ziyi relgroup): fix
static void bindExportRelGroupDataQuery(const TableCatalogEntry& entry, std::string& exportQuery,
const Catalog& catalog, const Transaction* transaction) {
auto relTableEntry = entry.constPtrCast<RelTableCatalogEntry>();
auto& srcTableEntry = catalog.getTableCatalogEntry(transaction, relTableEntry->getSrcTableID())
auto relGroupEntry = entry.constPtrCast<RelGroupCatalogEntry>();
auto& srcTableEntry = catalog
.getTableCatalogEntry(transaction,
relGroupEntry->getRelTableInfos()[0].nodePair.srcTableID)
->constCast<NodeTableCatalogEntry>();
auto& dstTableEntry = catalog.getTableCatalogEntry(transaction, relTableEntry->getDstTableID())
auto& dstTableEntry = catalog
.getTableCatalogEntry(transaction,
relGroupEntry->getRelTableInfos()[0].nodePair.dstTableID)
->constCast<NodeTableCatalogEntry>();
exportQuery = stringFormat("match (a:`{}`)-[r:`{}`]->(b:`{}`) return a.{},b.{},r.*;",
srcTableEntry.getName(), relTableEntry->getName(), dstTableEntry.getName(),
srcTableEntry.getName(), relGroupEntry->getName(), dstTableEntry.getName(),
srcTableEntry.getPrimaryKeyName(), dstTableEntry.getPrimaryKeyName());
}

Expand All @@ -81,8 +86,8 @@ static bool bindExportQuery(std::string& exportQuery, const TableCatalogEntry& e
case TableType::NODE: {
bindExportNodeTableDataQuery(entry, exportQuery);
} break;
case TableType::REL: {
bindExportRelTableDataQuery(entry, exportQuery, catalog, transaction);
case TableType::REL_GROUP: {
bindExportRelGroupDataQuery(entry, exportQuery, catalog, transaction);
} break;
default:
return false;
Expand Down
27 changes: 12 additions & 15 deletions src/binder/bind/bind_graph_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "catalog/catalog.h"
#include "catalog/catalog_entry/node_table_catalog_entry.h"
#include "catalog/catalog_entry/rel_group_catalog_entry.h"
#include "catalog/catalog_entry/rel_table_catalog_entry.h"
#include "common/enums/rel_direction.h"
#include "common/exception/binder.h"
#include "common/string_format.h"
#include "common/utils.h"
Expand Down Expand Up @@ -215,7 +215,7 @@ std::shared_ptr<RelExpression> Binder::bindQueryRel(const RelPattern& relPattern
throw BinderException("Bind relationship " + parsedName +
" to relationship with same name is not supported.");
}
auto entries = bindRelTableEntries(relPattern.getTableNames());
auto entries = bindRelGroupEntries(relPattern.getTableNames());
// bind src & dst node
RelDirectionType directionType = RelDirectionType::UNKNOWN;
std::shared_ptr<NodeExpression> srcNode;
Expand Down Expand Up @@ -347,9 +347,12 @@ std::shared_ptr<RelExpression> Binder::createRecursiveQueryRel(const parser::Rel
auto transaction = clientContext->getTransaction();
table_catalog_entry_set_t entrySet;
for (auto entry : entries) {
auto& relTableEntry = entry->constCast<RelTableCatalogEntry>();
entrySet.insert(catalog->getTableCatalogEntry(transaction, relTableEntry.getSrcTableID()));
entrySet.insert(catalog->getTableCatalogEntry(transaction, relTableEntry.getDstTableID()));
// TODO(Xiyang relgroup): fix this
auto& relGroupEntry = entry->constCast<RelGroupCatalogEntry>();
entrySet.insert(catalog->getTableCatalogEntry(transaction,
relGroupEntry.getRelTableInfos()[0].nodePair.srcTableID));
entrySet.insert(catalog->getTableCatalogEntry(transaction,
relGroupEntry.getRelTableInfos()[0].nodePair.dstTableID));
}
auto recursivePatternInfo = relPattern.getRecursiveInfo();
auto prevScope = saveScope();
Expand Down Expand Up @@ -675,27 +678,21 @@ TableCatalogEntry* Binder::bindNodeTableEntry(const std::string& name) const {
return catalog->getTableCatalogEntry(transaction, name, useInternal);
}

std::vector<TableCatalogEntry*> Binder::bindRelTableEntries(
std::vector<TableCatalogEntry*> Binder::bindRelGroupEntries(
const std::vector<std::string>& tableNames) const {
auto transaction = clientContext->getTransaction();
auto catalog = clientContext->getCatalog();
auto useInternal = clientContext->useInternalCatalogEntry();
table_catalog_entry_set_t entrySet;
if (tableNames.empty()) {
for (auto& entry : catalog->getRelTableEntries(transaction, useInternal)) {
for (auto& entry : catalog->getRelGroupEntries(transaction, useInternal)) {
entrySet.insert(entry);
}
} else {
for (auto& name : tableNames) {
if (catalog->containsRelGroup(transaction, name)) {
auto groupEntry = catalog->getRelGroupEntry(transaction, name);
for (auto& id : groupEntry->getRelTableIDs()) {
auto relEntry = catalog->getTableCatalogEntry(transaction, id);
entrySet.insert(relEntry);
}
} else if (catalog->containsTable(transaction, name)) {
if (catalog->containsTable(transaction, name)) {
auto entry = catalog->getTableCatalogEntry(transaction, name, useInternal);
if (entry->getType() != CatalogEntryType::REL_TABLE_ENTRY) {
if (entry->getType() != CatalogEntryType::REL_GROUP_ENTRY) {
throw BinderException(stringFormat(
"Cannot bind {} as a relationship pattern label.", entry->getName()));
}
Expand Down
12 changes: 6 additions & 6 deletions src/binder/bind/bind_updating_clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "binder/query/updating_clause/bound_set_clause.h"
#include "catalog/catalog.h"
#include "catalog/catalog_entry/node_table_catalog_entry.h"
#include "catalog/catalog_entry/rel_table_catalog_entry.h"
#include "catalog/catalog_entry/rel_group_catalog_entry.h"
#include "common/assert.h"
#include "common/exception/binder.h"
#include "common/string_format.h"
Expand Down Expand Up @@ -191,8 +191,8 @@ static TableCatalogEntry* tryPruneMultiLabeled(const RelExpression& rel, table_i
table_id_t dstTableID) {
std::vector<TableCatalogEntry*> candidates;
for (auto& entry : rel.getEntries()) {
KU_ASSERT(entry->getType() == CatalogEntryType::REL_TABLE_ENTRY);
auto& relEntry = entry->constCast<RelTableCatalogEntry>();
KU_ASSERT(entry->getType() == CatalogEntryType::REL_GROUP_ENTRY);
auto& relEntry = entry->constCast<RelGroupCatalogEntry>();
if (relEntry.getSrcTableID() == srcTableID && relEntry.getDstTableID() == dstTableID) {
candidates.push_back(entry);
}
Expand Down Expand Up @@ -232,7 +232,7 @@ void Binder::bindInsertRel(std::shared_ptr<RelExpression> rel,
// LCOV_EXCL_STOP
}
rel->setEntries(std::vector<TableCatalogEntry*>{entry});
auto insertInfo = BoundInsertInfo(TableType::REL, rel);
auto insertInfo = BoundInsertInfo(TableType::REL_GROUP, rel);
// Because we might prune entries, some property exprs may belong to pruned entry
for (auto& p : entry->getProperties()) {
insertInfo.columnExprs.push_back(rel->getPropertyExpression(p.getName()));
Expand Down Expand Up @@ -292,7 +292,7 @@ BoundSetPropertyInfo Binder::bindSetPropertyInfo(const ParsedExpression* column,
}
return info;
}
return BoundSetPropertyInfo(TableType::REL, expr, boundColumn, boundColumnData);
return BoundSetPropertyInfo(TableType::REL_GROUP, expr, boundColumn, boundColumnData);
}

expression_pair Binder::bindSetItem(const ParsedExpression* column,
Expand Down Expand Up @@ -324,7 +324,7 @@ std::unique_ptr<BoundUpdatingClause> Binder::bindDeleteClause(
if (rel->getDirectionType() == RelDirectionType::BOTH) {
throw BinderException("Delete undirected rel is not supported.");
}
auto deleteRel = BoundDeleteInfo(deleteType, TableType::REL, pattern);
auto deleteRel = BoundDeleteInfo(deleteType, TableType::REL_GROUP, pattern);
boundDeleteClause->addInfo(std::move(deleteRel));
} else {
throw BinderException(stringFormat(
Expand Down
Loading