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

Rework srcDstTableID #1041

Merged
merged 1 commit into from
Nov 19, 2022
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
3 changes: 3 additions & 0 deletions dataset/tinysnb/eBelongs.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
person,0,organisation,1
person,3,organisation,1
organisation,4,country,0
14 changes: 6 additions & 8 deletions src/binder/bind/bind_ddl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,13 @@ unique_ptr<BoundStatement> Binder::bindCreateRelClause(const Statement& statemen
auto propertyNameDataTypes =
bindPropertyNameDataTypes(createRelClause.getPropertyNameDataTypes());
auto relMultiplicity = getRelMultiplicityFromString(createRelClause.getRelMultiplicity());
unordered_set<table_id_t> srcTableIDs, dstTableIDs;
for (auto& srcTableName : createRelClause.getRelConnection().srcTableNames) {
for (auto& dstTableName : createRelClause.getRelConnection().dstTableNames) {
srcTableIDs.insert(bindNodeTable(srcTableName));
dstTableIDs.insert(bindNodeTable(dstTableName));
}
auto relConnections = createRelClause.getRelConnections();
vector<pair<table_id_t, table_id_t>> srcDstTableIDs;
for (auto& [srcTableName, dstTableName] : relConnections) {
srcDstTableIDs.emplace_back(bindNodeTable(srcTableName), bindNodeTable(dstTableName));
}
return make_unique<BoundCreateRelClause>(tableName, move(propertyNameDataTypes),
relMultiplicity, SrcDstTableIDs(move(srcTableIDs), move(dstTableIDs)));
return make_unique<BoundCreateRelClause>(
tableName, move(propertyNameDataTypes), relMultiplicity, srcDstTableIDs);
}

unique_ptr<BoundStatement> Binder::bindDropTable(const Statement& statement) {
Expand Down
6 changes: 2 additions & 4 deletions src/binder/bind/bind_graph_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,10 @@ void Binder::bindQueryRel(const RelPattern& relPattern, const shared_ptr<NodeExp
}
// bind node to rel
auto isLeftNodeSrc = RIGHT == relPattern.getDirection();
validateNodeAndRelTableIsConnected(
catalog, tableID, leftNode->getTableID(), isLeftNodeSrc ? FWD : BWD);
validateNodeAndRelTableIsConnected(
catalog, tableID, rightNode->getTableID(), isLeftNodeSrc ? BWD : FWD);
auto srcNode = isLeftNodeSrc ? leftNode : rightNode;
auto dstNode = isLeftNodeSrc ? rightNode : leftNode;
validateNodeAndRelTableIsConnected(
catalog, tableID, srcNode->getTableID(), dstNode->getTableID());
if (srcNode->getUniqueName() == dstNode->getUniqueName()) {
throw BinderException("Self-loop rel " + parsedName + " is not supported.");
}
Expand Down
22 changes: 10 additions & 12 deletions src/binder/binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,19 @@ void Binder::validateFirstMatchIsNotOptional(const SingleQuery& singleQuery) {
}
}

void Binder::validateNodeAndRelTableIsConnected(const Catalog& catalog_, table_id_t relTableID,
table_id_t nodeTableID, RelDirection direction) {
assert(relTableID != ANY_TABLE_ID);
assert(nodeTableID != ANY_TABLE_ID);
auto connectedRelTableIDs =
catalog_.getReadOnlyVersion()->getRelTableIDsForNodeTableDirection(nodeTableID, direction);
for (auto& connectedRelTableID : connectedRelTableIDs) {
if (relTableID == connectedRelTableID) {
void Binder::validateNodeAndRelTableIsConnected(
const Catalog& catalog_, table_id_t relTableID, table_id_t srcTableID, table_id_t dstTableID) {
assert(relTableID != ANY_TABLE_ID && srcTableID != ANY_TABLE_ID && dstTableID != ANY_TABLE_ID);
for (auto& [srcTableID_, dstTableID_] :
catalog_.getReadOnlyVersion()->getRelTableSchema(relTableID)->srcDstTableIDs) {
acquamarin marked this conversation as resolved.
Show resolved Hide resolved
if (srcTableID_ == srcTableID && dstTableID_ == dstTableID) {
return;
}
}
throw BinderException("Node table " +
catalog_.getReadOnlyVersion()->getNodeTableName(nodeTableID) +
" doesn't connect to rel table " +
catalog_.getReadOnlyVersion()->getRelTableName(relTableID) + ".");
throw BinderException(
"Node table " + catalog_.getReadOnlyVersion()->getNodeTableName(srcTableID) +
" doesn't connect to " + catalog_.getReadOnlyVersion()->getNodeTableName(dstTableID) +
" through rel table " + catalog_.getReadOnlyVersion()->getRelTableName(relTableID) + ".");
}

void Binder::validateProjectionColumnNamesAreUnique(const expression_vector& expressions) {
Expand Down
6 changes: 3 additions & 3 deletions src/binder/bound_ddl/include/bound_create_rel_clause.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ class BoundCreateRelClause : public BoundCreateTable {
public:
explicit BoundCreateRelClause(string tableName,
vector<PropertyNameDataType> propertyNameDataTypes, RelMultiplicity relMultiplicity,
SrcDstTableIDs srcDstTableIDs)
vector<pair<table_id_t, table_id_t>> srcDstTableIDs)
: BoundCreateTable{StatementType::CREATE_REL_CLAUSE, move(tableName),
move(propertyNameDataTypes)},
relMultiplicity{relMultiplicity}, srcDstTableIDs{move(srcDstTableIDs)} {}

RelMultiplicity getRelMultiplicity() const { return relMultiplicity; }

SrcDstTableIDs getSrcDstTableIDs() const { return srcDstTableIDs; }
vector<pair<table_id_t, table_id_t>> getSrcDstTableIDs() const { return srcDstTableIDs; }

private:
RelMultiplicity relMultiplicity;
SrcDstTableIDs srcDstTableIDs;
vector<pair<table_id_t, table_id_t>> srcDstTableIDs;
};

} // namespace binder
Expand Down
2 changes: 1 addition & 1 deletion src/binder/include/binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class Binder {

// E.g. MATCH (:person)-[:studyAt]->(:person) ...
static void validateNodeAndRelTableIsConnected(const Catalog& catalog_, table_id_t relTableID,
table_id_t nodeTableID, RelDirection direction);
table_id_t srcTableID, table_id_t dstTableID);

// E.g. ... RETURN a, b AS a
static void validateProjectionColumnNamesAreUnique(const expression_vector& expressions);
Expand Down
30 changes: 9 additions & 21 deletions src/catalog/catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,8 @@ uint64_t SerDeser::serializeValue<RelTableSchema>(
offset = SerDeser::serializeValue<table_id_t>(value.tableID, fileInfo, offset);
offset = SerDeser::serializeValue<RelMultiplicity>(value.relMultiplicity, fileInfo, offset);
offset = SerDeser::serializeVector<Property>(value.properties, fileInfo, offset);
offset = SerDeser::serializeUnorderedSet<table_id_t>(
value.srcDstTableIDs.srcTableIDs, fileInfo, offset);
return SerDeser::serializeUnorderedSet<table_id_t>(
value.srcDstTableIDs.dstTableIDs, fileInfo, offset);
return SerDeser::serializeVector<pair<table_id_t, table_id_t>>(
value.srcDstTableIDs, fileInfo, offset);
}

template<>
Expand All @@ -169,10 +167,8 @@ uint64_t SerDeser::deserializeValue<RelTableSchema>(
offset = SerDeser::deserializeValue<table_id_t>(value.tableID, fileInfo, offset);
offset = SerDeser::deserializeValue<RelMultiplicity>(value.relMultiplicity, fileInfo, offset);
offset = SerDeser::deserializeVector<Property>(value.properties, fileInfo, offset);
offset = SerDeser::deserializeUnorderedSet<table_id_t>(
value.srcDstTableIDs.srcTableIDs, fileInfo, offset);
return SerDeser::deserializeUnorderedSet<table_id_t>(
value.srcDstTableIDs.dstTableIDs, fileInfo, offset);
return SerDeser::deserializeVector<pair<table_id_t, table_id_t>>(
value.srcDstTableIDs, fileInfo, offset);
}

} // namespace common
Expand Down Expand Up @@ -223,12 +219,11 @@ table_id_t CatalogContent::addNodeTableSchema(string tableName, uint32_t primary
}

table_id_t CatalogContent::addRelTableSchema(string tableName, RelMultiplicity relMultiplicity,
vector<PropertyNameDataType> structuredPropertyDefinitions, SrcDstTableIDs srcDstTableIDs) {
vector<PropertyNameDataType> structuredPropertyDefinitions,
vector<pair<table_id_t, table_id_t>> srcDstTableIDs) {
table_id_t tableID = assignNextTableID();
for (auto& srcTableID : srcDstTableIDs.srcTableIDs) {
for (auto& [srcTableID, dstTableID] : srcDstTableIDs) {
nodeTableSchemas[srcTableID]->addFwdRelTableID(tableID);
}
for (auto& dstTableID : srcDstTableIDs.dstTableIDs) {
nodeTableSchemas[dstTableID]->addBwdRelTableID(tableID);
}
vector<Property> structuredProperties;
Expand Down Expand Up @@ -303,14 +298,6 @@ const unordered_set<table_id_t>& CatalogContent::getRelTableIDsForNodeTableDirec
return nodeTableSchemas.at(tableID)->bwdRelTableIDSet;
}

const unordered_set<table_id_t>& CatalogContent::getNodeTableIDsForRelTableDirection(
table_id_t tableID, RelDirection direction) const {
if (FWD == direction) {
return relTableSchemas.at(tableID)->srcDstTableIDs.srcTableIDs;
}
return relTableSchemas.at(tableID)->srcDstTableIDs.dstTableIDs;
}

void CatalogContent::saveToFile(const string& directory, DBFileType dbFileType) {
auto catalogPath = StorageUtils::getCatalogFilePath(directory, dbFileType);
auto fileInfo = FileUtils::openFile(catalogPath, O_WRONLY | O_CREAT);
Expand Down Expand Up @@ -420,7 +407,8 @@ table_id_t Catalog::addNodeTableSchema(string tableName, uint32_t primaryKeyIdx,
}

table_id_t Catalog::addRelTableSchema(string tableName, RelMultiplicity relMultiplicity,
vector<PropertyNameDataType> structuredPropertyDefinitions, SrcDstTableIDs srcDstTableIDs) {
vector<PropertyNameDataType> structuredPropertyDefinitions,
vector<pair<table_id_t, table_id_t>> srcDstTableIDs) {
initCatalogContentForWriteTrxIfNecessary();
auto tableID = catalogContentForWriteTrx->addRelTableSchema(move(tableName), relMultiplicity,
move(structuredPropertyDefinitions), move(srcDstTableIDs));
Expand Down
35 changes: 33 additions & 2 deletions src/catalog/catalog_structs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,41 @@ vector<Property> NodeTableSchema::getAllNodeProperties() const {

unordered_set<table_id_t> RelTableSchema::getAllNodeTableIDs() const {
unordered_set<table_id_t> allNodeTableIDs;
allNodeTableIDs.insert(srcDstTableIDs.srcTableIDs.begin(), srcDstTableIDs.srcTableIDs.end());
allNodeTableIDs.insert(srcDstTableIDs.dstTableIDs.begin(), srcDstTableIDs.dstTableIDs.end());
for (auto& [srcTableID, dstTableID] : srcDstTableIDs) {
allNodeTableIDs.insert(srcTableID);
allNodeTableIDs.insert(dstTableID);
}
return allNodeTableIDs;
}

unordered_set<table_id_t> RelTableSchema::getUniqueSrcTableIDs() const {
unordered_set<table_id_t> srcTableIDs;
for (auto& [srcTableID, dstTableID] : srcDstTableIDs) {
srcTableIDs.insert(srcTableID);
}
return srcTableIDs;
}

unordered_set<table_id_t> RelTableSchema::getUniqueDstTableIDs() const {
unordered_set<table_id_t> dstTableIDs;
for (auto& [srcTableID, dstTableID] : srcDstTableIDs) {
dstTableIDs.insert(dstTableID);
}
return dstTableIDs;
}

unordered_set<table_id_t> RelTableSchema::getUniqueNbrTableIDsForBoundTableIDDirection(
RelDirection direction, table_id_t boundTableID) const {
unordered_set<table_id_t> nbrTableIDs;
for (auto& [srcTableID, dstTableID] : srcDstTableIDs) {
if (direction == FWD && srcTableID == boundTableID) {
nbrTableIDs.insert(dstTableID);
} else if (direction == BWD && dstTableID == boundTableID) {
nbrTableIDs.insert(srcTableID);
}
}
return nbrTableIDs;
}

} // namespace catalog
} // namespace kuzu
21 changes: 11 additions & 10 deletions src/catalog/include/catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ class CatalogContent {
vector<PropertyNameDataType> structuredPropertyDefinitions);

table_id_t addRelTableSchema(string tableName, RelMultiplicity relMultiplicity,
vector<PropertyNameDataType> structuredPropertyDefinitions, SrcDstTableIDs srcDstTableIDs);
vector<PropertyNameDataType> structuredPropertyDefinitions,
vector<pair<table_id_t, table_id_t>> srcDstTableIDs);

virtual inline string getNodeTableName(table_id_t tableID) const {
return nodeTableSchemas.at(tableID)->tableName;
Expand All @@ -57,12 +58,10 @@ class CatalogContent {
inline NodeTableSchema* getNodeTableSchema(table_id_t tableID) const {
return nodeTableSchemas.at(tableID).get();
}
inline RelTableSchema* getRelTableSchema(table_id_t tableID) const {
virtual inline RelTableSchema* getRelTableSchema(table_id_t tableID) const {
return relTableSchemas.at(tableID).get();
}

inline uint64_t getNumNodeTables() const { return nodeTableSchemas.size(); }

virtual inline bool containNodeTable(const string& tableName) const {
return end(nodeTableNameToIDMap) != nodeTableNameToIDMap.find(tableName);
}
Expand Down Expand Up @@ -96,9 +95,6 @@ class CatalogContent {
const Property& getNodePrimaryKeyProperty(table_id_t tableID) const;

vector<Property> getAllNodeProperties(table_id_t tableID) const;
inline const vector<Property>& getStructuredNodeProperties(table_id_t tableID) const {
return nodeTableSchemas.at(tableID)->structuredProperties;
}
inline const vector<Property>& getUnstructuredNodeProperties(table_id_t tableID) const {
return nodeTableSchemas.at(tableID)->unstructuredProperties;
}
Expand All @@ -115,15 +111,19 @@ class CatalogContent {
inline unordered_map<table_id_t, unique_ptr<RelTableSchema>>& getRelTableSchemas() {
return relTableSchemas;
}
inline const unordered_set<table_id_t> getNodeTableIDsForRelTableDirection(
table_id_t relTableID, RelDirection direction) const {
auto relTableSchema = getRelTableSchema(relTableID);
return direction == FWD ? relTableSchema->getUniqueSrcTableIDs() :
relTableSchema->getUniqueDstTableIDs();
}

void removeTableSchema(TableSchema* tableSchema);

/**
* Graph topology functions.
*/

const unordered_set<table_id_t>& getNodeTableIDsForRelTableDirection(
table_id_t tableID, RelDirection direction) const;
virtual const unordered_set<table_id_t>& getRelTableIDsForNodeTableDirection(
table_id_t tableID, RelDirection direction) const;

Expand Down Expand Up @@ -188,7 +188,8 @@ class Catalog {
vector<PropertyNameDataType> structuredPropertyDefinitions);

table_id_t addRelTableSchema(string tableName, RelMultiplicity relMultiplicity,
vector<PropertyNameDataType> structuredPropertyDefinitions, SrcDstTableIDs srcDstTableIDs);
vector<PropertyNameDataType> structuredPropertyDefinitions,
vector<pair<table_id_t, table_id_t>> srcDstTableIDs);

inline void setUnstructuredPropertiesOfNodeTableSchema(
vector<string>& unstructuredProperties, table_id_t tableID) {
Expand Down
34 changes: 18 additions & 16 deletions src/catalog/include/catalog_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@ using namespace kuzu::common;
namespace kuzu {
namespace catalog {

struct SrcDstTableIDs {
SrcDstTableIDs(unordered_set<table_id_t> srcTableIDs, unordered_set<table_id_t> dstTableIDs)
: srcTableIDs{move(srcTableIDs)}, dstTableIDs{move(dstTableIDs)} {}
SrcDstTableIDs() = default;
unordered_set<table_id_t> srcTableIDs;
unordered_set<table_id_t> dstTableIDs;
};

enum RelMultiplicity : uint8_t { MANY_MANY, MANY_ONE, ONE_MANY, ONE_ONE };
RelMultiplicity getRelMultiplicityFromString(const string& relMultiplicityString);
string getRelMultiplicityAsString(RelMultiplicity relMultiplicity);
Expand Down Expand Up @@ -118,13 +110,11 @@ struct RelTableSchema : TableSchema {
RelTableSchema()
: TableSchema{"", UINT64_MAX, false /* isNodeTable */}, relMultiplicity{MANY_MANY} {}
RelTableSchema(string tableName, table_id_t tableID, RelMultiplicity relMultiplicity,
vector<Property> properties, SrcDstTableIDs srcDstTableIDs)
vector<Property> properties, vector<pair<table_id_t, table_id_t>> srcDstTableIDs)
: TableSchema{move(tableName), tableID, false /* isNodeTable */},
relMultiplicity{relMultiplicity}, properties{move(properties)}, srcDstTableIDs{move(
srcDstTableIDs)} {}

unordered_set<table_id_t> getAllNodeTableIDs() const;

inline Property& getRelIDDefinition() {
for (auto& property : properties) {
if (property.name == INTERNAL_ID_SUFFIX) {
Expand All @@ -139,7 +129,7 @@ struct RelTableSchema : TableSchema {
relMultiplicity == (direction == FWD ? MANY_ONE : ONE_MANY);
}

inline SrcDstTableIDs getSrcDstTableIDs() const { return srcDstTableIDs; }
inline vector<pair<table_id_t, table_id_t>> getSrcDstTableIDs() const { return srcDstTableIDs; }

inline uint32_t getNumProperties() const { return properties.size(); }

Expand All @@ -153,14 +143,26 @@ struct RelTableSchema : TableSchema {
(relMultiplicity == MANY_ONE && relDirection == BWD);
}

bool edgeContainsNodeTable(table_id_t tableID) const {
return srcDstTableIDs.srcTableIDs.contains(tableID) ||
srcDstTableIDs.dstTableIDs.contains(tableID);
inline bool edgeContainsNodeTable(table_id_t tableID) const {
return any_of(srcDstTableIDs.begin(), srcDstTableIDs.end(),
[tableID](pair<table_id_t, table_id_t> srcDstTableID) {
return srcDstTableID.first == tableID || srcDstTableID.second == tableID;
});
}

unordered_set<table_id_t> getAllNodeTableIDs() const;

unordered_set<table_id_t> getUniqueSrcTableIDs() const;

unordered_set<table_id_t> getUniqueDstTableIDs() const;

unordered_set<table_id_t> getUniqueNbrTableIDsForBoundTableIDDirection(
RelDirection direction, table_id_t boundTableID) const;

RelMultiplicity relMultiplicity;
vector<Property> properties;
SrcDstTableIDs srcDstTableIDs;
vector<pair<table_id_t, table_id_t>> srcDstTableIDs;
};

} // namespace catalog
} // namespace kuzu
15 changes: 4 additions & 11 deletions src/parser/ddl/include/create_rel_clause.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,21 @@ namespace parser {

using namespace std;

struct RelConnection {
RelConnection(vector<string> srcTableNames, vector<string> dstTableNames)
: srcTableNames{move(srcTableNames)}, dstTableNames{move(dstTableNames)} {}
vector<string> srcTableNames;
vector<string> dstTableNames;
};

class CreateRelClause : public CreateTable {
public:
explicit CreateRelClause(string tableName, vector<pair<string, string>> propertyNameDataTypes,
string relMultiplicity, RelConnection relConnection)
string relMultiplicity, vector<pair<string, string>> relConnections)
: CreateTable{StatementType::CREATE_REL_CLAUSE, move(tableName),
move(propertyNameDataTypes)},
relMultiplicity{move(relMultiplicity)}, relConnection{move(relConnection)} {}
relMultiplicity{move(relMultiplicity)}, relConnections{move(relConnections)} {}

inline string getRelMultiplicity() const { return relMultiplicity; }

inline RelConnection getRelConnection() const { return relConnection; }
inline vector<pair<string, string>> getRelConnections() const { return relConnections; }

private:
string relMultiplicity;
RelConnection relConnection;
vector<pair<string, string>> relConnections;
};

} // namespace parser
Expand Down
3 changes: 2 additions & 1 deletion src/parser/include/transformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ class Transformer {
vector<pair<string, string>> transformPropertyDefinitions(
CypherParser::KU_PropertyDefinitionsContext& ctx);

RelConnection transformRelConnection(CypherParser::KU_RelConnectionsContext& ctx);
vector<pair<string, string>> transformRelConnections(
CypherParser::KU_RelConnectionsContext& ctx);

vector<string> transformNodeLabels(CypherParser::KU_NodeLabelsContext& ctx);

Expand Down
Loading