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

Scan rel ID blindly #1074

Merged
merged 1 commit into from
Nov 28, 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
4 changes: 4 additions & 0 deletions src/binder/bind/bind_graph_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ void Binder::bindQueryRel(const RelPattern& relPattern, const shared_ptr<NodeExp
}
auto queryRel = make_shared<RelExpression>(
getUniqueExpressionName(parsedName), tableID, srcNode, dstNode, lowerBound, upperBound);
if (!queryRel->isVariableLength()) {
queryRel->setInternalIDProperty(expressionBinder.bindInternalIDExpression(queryRel));
}
queryRel->setAlias(parsedName);
queryRel->setRawName(parsedName);
if (!parsedName.empty()) {
Expand Down Expand Up @@ -141,6 +144,7 @@ shared_ptr<NodeExpression> Binder::createQueryNode(const NodePattern& nodePatter
auto parsedName = nodePattern.getVariableName();
auto tableIDs = bindNodeTableIDs(nodePattern.getTableNames());
auto queryNode = make_shared<NodeExpression>(getUniqueExpressionName(parsedName), tableIDs);
queryNode->setInternalIDProperty(expressionBinder.bindInternalIDExpression(queryNode));
queryNode->setAlias(parsedName);
queryNode->setRawName(parsedName);
if (!parsedName.empty()) {
Expand Down
4 changes: 2 additions & 2 deletions src/binder/expression/existential_subquery_expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ unordered_set<string> ExistentialSubqueryExpression::getDependentVariableNames()
// expressions from predicates and return clause. Plus nodeID expressions from query graph.
expression_vector ExistentialSubqueryExpression::getChildren() const {
expression_vector result;
for (auto& nodeIDExpression : queryGraphCollection->getNodeIDExpressions()) {
result.push_back(nodeIDExpression);
for (auto& node : queryGraphCollection->getQueryNodes()) {
result.push_back(node->getInternalIDProperty());
}
if (hasWhereExpression()) {
result.push_back(whereExpression);
Expand Down
24 changes: 19 additions & 5 deletions src/binder/expression_binder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,16 +307,30 @@ shared_ptr<Expression> ExpressionBinder::bindInternalIDExpression(
shared_ptr<Expression> ExpressionBinder::bindInternalIDExpression(
shared_ptr<Expression> nodeOrRel) {
if (nodeOrRel->dataType.typeID == NODE) {
return ((NodeExpression*)nodeOrRel.get())->getNodeIDPropertyExpression();
return bindInternalNodeIDExpression(nodeOrRel);
} else {
assert(nodeOrRel->dataType.typeID == REL);
auto rel = (RelExpression*)nodeOrRel.get();
auto relTableSchema =
binder->catalog.getReadOnlyVersion()->getRelTableSchema(rel->getTableID());
return bindRelPropertyExpression(nodeOrRel, relTableSchema->getRelIDDefinition());
return bindInternalRelIDExpression(nodeOrRel);
}
}

shared_ptr<Expression> ExpressionBinder::bindInternalNodeIDExpression(shared_ptr<Expression> node) {
auto nodeExpression = (NodeExpression*)node.get();
unordered_map<table_id_t, property_id_t> propertyIDPerTable;
for (auto tableID : nodeExpression->getTableIDs()) {
propertyIDPerTable.insert({tableID, INVALID_PROPERTY_ID});
}
return make_unique<PropertyExpression>(
DataType(NODE_ID), INTERNAL_ID_SUFFIX, std::move(propertyIDPerTable), node);
}

shared_ptr<Expression> ExpressionBinder::bindInternalRelIDExpression(shared_ptr<Expression> rel) {
auto relExpression = (RelExpression*)rel.get();
auto relTableSchema =
binder->catalog.getReadOnlyVersion()->getRelTableSchema(relExpression->getTableID());
return bindRelPropertyExpression(rel, relTableSchema->getRelIDDefinition());
}

shared_ptr<Expression> ExpressionBinder::bindParameterExpression(
const ParsedExpression& parsedExpression) {
auto& parsedParameterExpression = (ParsedParameterExpression&)parsedExpression;
Expand Down
5 changes: 5 additions & 0 deletions src/binder/query/bound_delete_clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ expression_vector BoundDeleteClause::getPropertiesToRead() const {
for (auto& deleteNode : deleteNodes) {
result.push_back(deleteNode->getPrimaryKeyExpression());
}
for (auto& deleteRel : deleteRels) {
if (deleteRel->hasInternalIDProperty()) {
result.push_back(deleteRel->getInternalIDProperty());
}
}
return result;
}

Expand Down
26 changes: 14 additions & 12 deletions src/binder/query/query_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,6 @@ bool QueryGraph::isConnected(const QueryGraph& other) {
return false;
}

vector<shared_ptr<Expression>> QueryGraph::getNodeIDExpressions() const {
vector<shared_ptr<Expression>> result;
for (auto& queryNode : queryNodes) {
result.push_back(queryNode->getNodeIDPropertyExpression());
}
return result;
}

void QueryGraphCollection::addAndMergeQueryGraphIfConnected(
unique_ptr<QueryGraph> queryGraphToAdd) {
bool isMerged = false;
Expand All @@ -209,11 +201,21 @@ void QueryGraphCollection::addAndMergeQueryGraphIfConnected(
}
}

expression_vector QueryGraphCollection::getNodeIDExpressions() const {
expression_vector result;
vector<shared_ptr<NodeExpression>> QueryGraphCollection::getQueryNodes() const {
vector<shared_ptr<NodeExpression>> result;
for (auto& queryGraph : queryGraphs) {
for (auto& node : queryGraph->getQueryNodes()) {
result.push_back(node);
}
}
return result;
}

vector<shared_ptr<RelExpression>> QueryGraphCollection::getQueryRels() const {
vector<shared_ptr<RelExpression>> result;
for (auto& queryGraph : queryGraphs) {
for (auto& nodeID : queryGraph->getNodeIDExpressions()) {
result.push_back(nodeID);
for (auto& rel : queryGraph->getQueryRels()) {
result.push_back(rel);
}
}
return result;
Expand Down
19 changes: 10 additions & 9 deletions src/include/binder/expression/node_expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,20 @@ class NodeExpression : public Expression {
return *tableIDs.begin();
}

inline string getIDProperty() const { return uniqueName + "." + INTERNAL_ID_SUFFIX; }

inline shared_ptr<Expression> getNodeIDPropertyExpression() {
unordered_map<table_id_t, property_id_t> propertyIDPerTable;
for (auto tableID : tableIDs) {
propertyIDPerTable.insert({tableID, INVALID_PROPERTY_ID});
}
return make_unique<PropertyExpression>(DataType(NODE_ID), INTERNAL_ID_SUFFIX,
std::move(propertyIDPerTable), shared_from_this());
inline void setInternalIDProperty(shared_ptr<Expression> expression) {
internalIDExpression = std::move(expression);
}
inline shared_ptr<Expression> getInternalIDProperty() const {
assert(internalIDExpression != nullptr);
return internalIDExpression;
}
inline string getInternalIDPropertyName() const {
return internalIDExpression->getUniqueName();
}

private:
unordered_set<table_id_t> tableIDs;
shared_ptr<Expression> internalIDExpression;
};

} // namespace binder
Expand Down
19 changes: 16 additions & 3 deletions src/include/binder/expression/rel_expression.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#pragma once

#include "common/exception.h"
#include "node_expression.h"

namespace kuzu {
namespace binder {

class RelExpression : public Expression {

public:
RelExpression(const string& uniqueName, table_id_t tableID, shared_ptr<NodeExpression> srcNode,
shared_ptr<NodeExpression> dstNode, uint64_t lowerBound, uint64_t upperBound)
: Expression{VARIABLE, REL, uniqueName}, tableID{tableID}, srcNode{move(srcNode)},
dstNode{move(dstNode)}, lowerBound{lowerBound}, upperBound{upperBound} {}
: Expression{VARIABLE, REL, uniqueName}, tableID{tableID}, srcNode{std::move(srcNode)},
dstNode{std::move(dstNode)}, lowerBound{lowerBound}, upperBound{upperBound} {}

inline table_id_t getTableID() const { return tableID; }

Expand All @@ -29,12 +29,25 @@ class RelExpression : public Expression {

inline bool isVariableLength() const { return !(lowerBound == 1 && upperBound == 1); }

inline void setInternalIDProperty(shared_ptr<Expression> expression) {
internalIDExpression = std::move(expression);
}
inline bool hasInternalIDProperty() const { return internalIDExpression != nullptr; }
inline shared_ptr<Expression> getInternalIDProperty() const {
if (!hasInternalIDProperty()) {
throw NotImplementedException(
"Cannot read internal ID property for variable length rel " + getRawName());
}
return internalIDExpression;
}

private:
table_id_t tableID;
shared_ptr<NodeExpression> srcNode;
shared_ptr<NodeExpression> dstNode;
uint64_t lowerBound;
uint64_t upperBound;
shared_ptr<Expression> internalIDExpression;
};

} // namespace binder
Expand Down
2 changes: 2 additions & 0 deletions src/include/binder/expression_binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class ExpressionBinder {

shared_ptr<Expression> bindInternalIDExpression(const ParsedExpression& parsedExpression);
shared_ptr<Expression> bindInternalIDExpression(shared_ptr<Expression> nodeOrRel);
shared_ptr<Expression> bindInternalNodeIDExpression(shared_ptr<Expression> node);
shared_ptr<Expression> bindInternalRelIDExpression(shared_ptr<Expression> rel);

shared_ptr<Expression> bindParameterExpression(const ParsedExpression& parsedExpression);

Expand Down
5 changes: 5 additions & 0 deletions src/include/binder/query/reading_clause/bound_match_clause.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ class BoundMatchClause : public BoundReadingClause {

inline expression_vector getSubPropertyExpressions() const override {
expression_vector expressions;
for (auto& rel : queryGraphCollection->getQueryRels()) {
if (rel->hasInternalIDProperty()) {
expressions.push_back(rel->getInternalIDProperty());
}
}
if (this->hasWhereExpression()) {
for (auto& property : this->getWhereExpression()->getSubPropertyExpressions()) {
expressions.push_back(property);
Expand Down
7 changes: 4 additions & 3 deletions src/include/binder/query/reading_clause/query_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class QueryGraph {
inline bool containsQueryNode(const string& queryNodeName) const {
return queryNodeNameToPosMap.contains(queryNodeName);
}
inline vector<shared_ptr<NodeExpression>> getQueryNodes() const { return queryNodes; }
inline shared_ptr<NodeExpression> getQueryNode(const string& queryNodeName) const {
return queryNodes[getQueryNodePos(queryNodeName)];
}
Expand All @@ -112,6 +113,7 @@ class QueryGraph {
inline bool containsQueryRel(const string& queryRelName) const {
return queryRelNameToPosMap.contains(queryRelName);
}
inline vector<shared_ptr<RelExpression>> getQueryRels() const { return queryRels; }
inline shared_ptr<RelExpression> getQueryRel(const string& queryRelName) const {
return queryRels.at(queryRelNameToPosMap.at(queryRelName));
}
Expand All @@ -129,8 +131,6 @@ class QueryGraph {

void merge(const QueryGraph& other);

vector<shared_ptr<Expression>> getNodeIDExpressions() const;

inline unique_ptr<QueryGraph> copy() const { return make_unique<QueryGraph>(*this); }

private:
Expand All @@ -150,7 +150,8 @@ class QueryGraphCollection {
inline uint32_t getNumQueryGraphs() const { return queryGraphs.size(); }
inline QueryGraph* getQueryGraph(uint32_t idx) const { return queryGraphs[idx].get(); }

expression_vector getNodeIDExpressions() const;
vector<shared_ptr<NodeExpression>> getQueryNodes() const;
vector<shared_ptr<RelExpression>> getQueryRels() const;

unique_ptr<QueryGraphCollection> copy() const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ class LogicalExtend : public LogicalOperator {
}

inline void computeSchema(Schema& schema) {
auto boundGroupPos = schema.getGroupPos(boundNode->getIDProperty());
auto boundGroupPos = schema.getGroupPos(boundNode->getInternalIDPropertyName());
uint32_t nbrGroupPos = 0u;
if (isColumn) {
nbrGroupPos = boundGroupPos;
} else {
assert(schema.getGroup(boundGroupPos)->getIsFlat());
nbrGroupPos = schema.createGroup();
}
schema.insertToGroupAndScope(nbrNode->getNodeIDPropertyExpression(), nbrGroupPos);
schema.insertToGroupAndScope(nbrNode->getInternalIDProperty(), nbrGroupPos);
}

inline shared_ptr<NodeExpression> getBoundNodeExpression() const { return boundNode; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class LogicalScanNode : public LogicalOperator {

inline virtual void computeSchema(Schema& schema) {
auto groupPos = schema.createGroup();
schema.insertToGroupAndScope(node->getNodeIDPropertyExpression(), groupPos);
schema.insertToGroupAndScope(node->getInternalIDProperty(), groupPos);
}

inline shared_ptr<NodeExpression> getNode() const { return node; }
Expand All @@ -43,7 +43,7 @@ class LogicalIndexScanNode : public LogicalScanNode {

inline void computeSchema(Schema& schema) override {
LogicalScanNode::computeSchema(schema);
auto groupPos = schema.getGroupPos(node->getIDProperty());
auto groupPos = schema.getGroupPos(node->getInternalIDPropertyName());
schema.getGroup(groupPos)->setIsFlat(true);
}

Expand Down
11 changes: 7 additions & 4 deletions src/include/processor/operator/update/delete.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,16 @@ struct DeleteRelInfo {
table_id_t srcNodeTableID;
DataPos dstNodePos;
table_id_t dstNodeTableID;
DataPos relIDPos;

DeleteRelInfo(RelTable* table, const DataPos& srcNodePos, table_id_t srcNodeTableID,
const DataPos& dstNodePos, table_id_t dstNodeTableID)
const DataPos& dstNodePos, table_id_t dstNodeTableID, const DataPos& relIDPos)
: table{table}, srcNodePos{srcNodePos}, srcNodeTableID{srcNodeTableID},
dstNodePos{dstNodePos}, dstNodeTableID{dstNodeTableID} {}
dstNodePos{dstNodePos}, dstNodeTableID{dstNodeTableID}, relIDPos{relIDPos} {}

inline unique_ptr<DeleteRelInfo> clone() {
return make_unique<DeleteRelInfo>(
table, srcNodePos, srcNodeTableID, dstNodePos, dstNodeTableID);
table, srcNodePos, srcNodeTableID, dstNodePos, dstNodeTableID, relIDPos);
}
};

Expand Down Expand Up @@ -95,7 +96,9 @@ class DeleteRel : public PhysicalOperator {
private:
RelsStatistics& relsStatistics;
vector<unique_ptr<DeleteRelInfo>> deleteRelInfos;
vector<pair<ValueVector*, ValueVector*>> srcDstNodeIDVectorPairs;
vector<ValueVector*> srcNodeVectors;
vector<ValueVector*> dstNodeVectors;
vector<ValueVector*> relIDVectors;
};

} // namespace processor
Expand Down
Loading