Skip to content

Commit

Permalink
Merge pull request #1108 from kuzudb/extend-property-reading
Browse files Browse the repository at this point in the history
Extend property reading
  • Loading branch information
andyfengHKU committed Dec 11, 2022
2 parents d954159 + 833ea93 commit 2463999
Show file tree
Hide file tree
Showing 35 changed files with 420 additions and 616 deletions.
10 changes: 1 addition & 9 deletions src/include/planner/join_order_enumerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,8 @@ class JoinOrderEnumerator {

void planRelScan(uint32_t relPos);

void planExtendFiltersAndPropertyScans(shared_ptr<RelExpression> rel, RelDirection direction,
void planExtendAndFilters(shared_ptr<RelExpression> rel, RelDirection direction,
expression_vector& predicates, LogicalPlan& plan);
// Filter push down for rel table.
void planFiltersForRel(const expression_vector& predicates,
shared_ptr<NodeExpression> boundNode, shared_ptr<NodeExpression> nbrNode,
shared_ptr<RelExpression> rel, RelDirection direction, LogicalPlan& plan);
// Property push down for rel table.
void planPropertyScansForRel(const expression_vector& properties,
shared_ptr<NodeExpression> boundNode, shared_ptr<NodeExpression> nbrNode,
shared_ptr<RelExpression> rel, RelDirection direction, LogicalPlan& plan);

void planLevel(uint32_t level);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ enum LogicalOperatorType : uint8_t {
LOGICAL_INDEX_SCAN_NODE,
LOGICAL_UNWIND,
LOGICAL_EXTEND,
LOGICAL_GENERIC_EXTEND,
LOGICAL_FLATTEN,
LOGICAL_FILTER,
LOGICAL_INTERSECT,
LOGICAL_PROJECTION,
LOGICAL_SCAN_NODE_PROPERTY,
LOGICAL_SCAN_REL_PROPERTY,
LOGICAL_CROSS_PRODUCT,
LOGICAL_SEMI_MASKER,
LOGICAL_HASH_JOIN,
Expand All @@ -44,15 +42,14 @@ enum LogicalOperatorType : uint8_t {
};

const string LogicalOperatorTypeNames[] = {"LOGICAL_SCAN_NODE", "LOGICAL_INDEX_SCAN_NODE",
"LOGICAL_UNWIND", "LOGICAL_EXTEND", "LOGICAL_GENERIC_EXTEND", "LOGICAL_FLATTEN",
"LOGICAL_FILTER", "LOGICAL_INTERSECT", "LOGICAL_PROJECTION", "LOGICAL_SCAN_NODE_PROPERTY",
"LOGICAL_SCAN_REL_PROPERTY", "LOGICAL_CROSS_PRODUCT", "LOGICAL_SEMI_MASKER",
"LOGICAL_HASH_JOIN", "LOGICAL_MULTIPLICITY_REDUCER", "LOGICAL_LIMIT", "LOGICAL_SKIP",
"LOGICAL_AGGREGATE", "LOGICAL_ORDER_BY", "LOGICAL_UNION_ALL", "LOGICAL_DISTINCT",
"LOGICAL_CREATE_NODE", "LOGICAL_CREATE_REL", "LOGICAL_SET_NODE_PROPERTY", "LOGICAL_DELETE_NODE",
"LOGICAL_DELETE_REL", "LOGICAL_ACCUMULATE", "LOGICAL_EXPRESSIONS_SCAN", "LOGICAL_FTABLE_SCAN",
"LOGICAL_CREATE_NODE_TABLE", "LOGICAL_CREATE_REL_TABLE", "LOGICAL_COPY_CSV",
"LOGICAL_DROP_TABLE"};
"LOGICAL_UNWIND", "LOGICAL_EXTEND", "LOGICAL_FLATTEN", "LOGICAL_FILTER", "LOGICAL_INTERSECT",
"LOGICAL_PROJECTION", "LOGICAL_SCAN_NODE_PROPERTY", "LOGICAL_CROSS_PRODUCT",
"LOGICAL_SEMI_MASKER", "LOGICAL_HASH_JOIN", "LOGICAL_MULTIPLICITY_REDUCER", "LOGICAL_LIMIT",
"LOGICAL_SKIP", "LOGICAL_AGGREGATE", "LOGICAL_ORDER_BY", "LOGICAL_UNION_ALL",
"LOGICAL_DISTINCT", "LOGICAL_CREATE_NODE", "LOGICAL_CREATE_REL", "LOGICAL_SET_NODE_PROPERTY",
"LOGICAL_DELETE_NODE", "LOGICAL_DELETE_REL", "LOGICAL_ACCUMULATE", "LOGICAL_EXPRESSIONS_SCAN",
"LOGICAL_FTABLE_SCAN", "LOGICAL_CREATE_NODE_TABLE", "LOGICAL_CREATE_REL_TABLE",
"LOGICAL_COPY_CSV", "LOGICAL_DROP_TABLE"};

class LogicalOperator {
public:
Expand Down
55 changes: 14 additions & 41 deletions src/include/planner/logical_plan/logical_operator/logical_extend.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ using namespace kuzu::binder;
class LogicalExtend : public LogicalOperator {
public:
LogicalExtend(shared_ptr<NodeExpression> boundNode, shared_ptr<NodeExpression> nbrNode,
shared_ptr<RelExpression> rel, RelDirection direction, bool extendToNewGroup,
shared_ptr<LogicalOperator> child)
: LogicalOperator{std::move(child)}, boundNode{std::move(boundNode)}, nbrNode{std::move(
nbrNode)},
rel{std::move(rel)}, direction{direction}, extendToNewGroup{extendToNewGroup} {}
shared_ptr<RelExpression> rel, RelDirection direction, expression_vector properties,
bool extendToNewGroup, shared_ptr<LogicalOperator> child)
: LogicalOperator{std::move(child)}, boundNode{std::move(boundNode)},
nbrNode{std::move(nbrNode)}, rel{std::move(rel)}, direction{direction},
properties{std::move(properties)}, extendToNewGroup{extendToNewGroup} {}

LogicalOperatorType getLogicalOperatorType() const override {
inline LogicalOperatorType getLogicalOperatorType() const override {
return LogicalOperatorType::LOGICAL_EXTEND;
}

string getExpressionsForPrinting() const override {
inline string getExpressionsForPrinting() const override {
return boundNode->getRawName() + (direction == RelDirection::FWD ? "->" : "<-") +
nbrNode->getRawName();
}

inline virtual void computeSchema(Schema& schema) {
inline void computeSchema(Schema& schema) {
auto boundGroupPos = schema.getGroupPos(boundNode->getInternalIDPropertyName());
uint32_t nbrGroupPos = 0u;
if (!extendToNewGroup) {
Expand All @@ -35,58 +35,31 @@ class LogicalExtend : public LogicalOperator {
nbrGroupPos = schema.createGroup();
}
schema.insertToGroupAndScope(nbrNode->getInternalIDProperty(), nbrGroupPos);
for (auto& property : properties) {
schema.insertToGroupAndScope(property, nbrGroupPos);
}
}

inline shared_ptr<NodeExpression> getBoundNode() const { return boundNode; }
inline shared_ptr<NodeExpression> getNbrNode() const { return nbrNode; }
inline shared_ptr<RelExpression> getRel() const { return rel; }
inline RelDirection getDirection() const { return direction; }
inline expression_vector getProperties() const { return properties; }

unique_ptr<LogicalOperator> copy() override {
return make_unique<LogicalExtend>(
boundNode, nbrNode, rel, direction, extendToNewGroup, children[0]->copy());
boundNode, nbrNode, rel, direction, properties, extendToNewGroup, children[0]->copy());
}

protected:
shared_ptr<NodeExpression> boundNode;
shared_ptr<NodeExpression> nbrNode;
shared_ptr<RelExpression> rel;
RelDirection direction;
expression_vector properties;
// When extend might increase cardinality (i.e. n * m), we extend to a new factorization group.
bool extendToNewGroup;
};

class LogicalGenericExtend : public LogicalExtend {
public:
LogicalGenericExtend(shared_ptr<NodeExpression> boundNode, shared_ptr<NodeExpression> nbrNode,
shared_ptr<RelExpression> rel, RelDirection direction, bool extendToNewGroup,
expression_vector properties, shared_ptr<LogicalOperator> child)
: LogicalExtend(std::move(boundNode), std::move(nbrNode), std::move(rel), direction,
extendToNewGroup, std::move(child)),
properties{std::move(properties)} {}

inline LogicalOperatorType getLogicalOperatorType() const override {
return LogicalOperatorType::LOGICAL_GENERIC_EXTEND;
}

inline void computeSchema(Schema& schema) override {
LogicalExtend::computeSchema(schema);
auto nbrNodePos = schema.getGroupPos(nbrNode->getInternalIDPropertyName());
for (auto& property : properties) {
schema.insertToGroupAndScope(property, nbrNodePos);
}
}

inline expression_vector getProperties() const { return properties; }

unique_ptr<LogicalOperator> copy() override {
return make_unique<LogicalGenericExtend>(
boundNode, nbrNode, rel, direction, extendToNewGroup, properties, children[0]->copy());
}

private:
expression_vector properties;
};

} // namespace planner
} // namespace kuzu
Original file line number Diff line number Diff line change
@@ -1,49 +0,0 @@
#pragma once

#include "base_logical_operator.h"
#include "binder/expression/rel_expression.h"

namespace kuzu {
namespace planner {

class LogicalScanRelProperty : public LogicalOperator {
public:
LogicalScanRelProperty(shared_ptr<NodeExpression> boundNode, shared_ptr<NodeExpression> nbrNode,
shared_ptr<RelExpression> rel, RelDirection direction, shared_ptr<Expression> property,
shared_ptr<LogicalOperator> child)
: LogicalOperator{std::move(child)}, boundNode{std::move(boundNode)}, nbrNode{std::move(
nbrNode)},
rel{std::move(rel)}, direction{direction}, property{std::move(property)} {}

inline LogicalOperatorType getLogicalOperatorType() const override {
return LogicalOperatorType::LOGICAL_SCAN_REL_PROPERTY;
}

inline string getExpressionsForPrinting() const override { return property->getRawName(); }

inline void computeSchema(Schema& schema) {
auto nbrGroupPos = schema.getGroupPos(nbrNode->getInternalIDPropertyName());
schema.insertToGroupAndScope(property, nbrGroupPos);
}

inline shared_ptr<NodeExpression> getBoundNode() const { return boundNode; }
inline shared_ptr<NodeExpression> getNbrNode() const { return nbrNode; }
inline shared_ptr<RelExpression> getRel() const { return rel; }
inline RelDirection getDirection() const { return direction; }
inline shared_ptr<Expression> getProperty() const { return property; }

unique_ptr<LogicalOperator> copy() override {
return make_unique<LogicalScanRelProperty>(
boundNode, nbrNode, rel, direction, property, children[0]->copy());
}

private:
shared_ptr<NodeExpression> boundNode;
shared_ptr<NodeExpression> nbrNode;
shared_ptr<RelExpression> rel;
RelDirection direction;
shared_ptr<Expression> property;
};

} // namespace planner
} // namespace kuzu
11 changes: 0 additions & 11 deletions src/include/planner/query_planner.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,6 @@ class QueryPlanner {
void appendScanNodePropIfNecessary(const expression_vector& propertyExpressions,
shared_ptr<NodeExpression> node, LogicalPlan& plan);

inline void appendScanRelPropsIfNecessary(shared_ptr<NodeExpression> boundNode,
shared_ptr<NodeExpression> nbrNode, shared_ptr<RelExpression> rel, RelDirection direction,
const expression_vector& properties, LogicalPlan& plan) {
for (auto& property : properties) {
appendScanRelPropIfNecessary(boundNode, nbrNode, rel, direction, property, plan);
}
}
void appendScanRelPropIfNecessary(shared_ptr<NodeExpression> boundNode,
shared_ptr<NodeExpression> nbrNode, shared_ptr<RelExpression> rel, RelDirection direction,
shared_ptr<Expression> property, LogicalPlan& plan);

unique_ptr<LogicalPlan> createUnionPlan(
vector<unique_ptr<LogicalPlan>>& childrenPlans, bool isUnionAll);

Expand Down
4 changes: 0 additions & 4 deletions src/include/processor/mapper/plan_mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ class PlanMapper {
LogicalOperator* logicalOperator, MapperContext& mapperContext);
unique_ptr<PhysicalOperator> mapLogicalExtendToPhysical(
LogicalOperator* logicalOperator, MapperContext& mapperContext);
unique_ptr<PhysicalOperator> mapLogicalGenericExtendToPhysical(
LogicalOperator* logicalOperator, MapperContext& mapperContext);
unique_ptr<PhysicalOperator> mapLogicalFlattenToPhysical(
LogicalOperator* logicalOperator, MapperContext& mapperContext);
unique_ptr<PhysicalOperator> mapLogicalFilterToPhysical(
Expand All @@ -48,8 +46,6 @@ class PlanMapper {
LogicalOperator* logicalOperator, MapperContext& mapperContext);
unique_ptr<PhysicalOperator> mapLogicalScanNodePropertyToPhysical(
LogicalOperator* logicalOperator, MapperContext& mapperContext);
unique_ptr<PhysicalOperator> mapLogicalScanRelPropertyToPhysical(
LogicalOperator* logicalOperator, MapperContext& mapperContext);
unique_ptr<PhysicalOperator> mapLogicalSemiMaskerToPhysical(
LogicalOperator* logicalOperator, MapperContext& mapperContext);
unique_ptr<PhysicalOperator> mapLogicalHashJoinToPhysical(
Expand Down
32 changes: 32 additions & 0 deletions src/include/processor/operator/base_extend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include "processor/operator/physical_operator.h"

namespace kuzu {
namespace processor {

class BaseExtendAndScanRelProperties : public PhysicalOperator {
protected:
BaseExtendAndScanRelProperties(const DataPos& inNodeIDVectorPos,
const DataPos& outNodeIDVectorPos, vector<DataPos> outPropertyVectorsPos,
unique_ptr<PhysicalOperator> child, uint32_t id, const string& paramsString)
: PhysicalOperator{std::move(child), id, paramsString},
inNodeIDVectorPos{inNodeIDVectorPos}, outNodeIDVectorPos{outNodeIDVectorPos},
outPropertyVectorsPos{std::move(outPropertyVectorsPos)} {}
virtual ~BaseExtendAndScanRelProperties() override = default;

void initLocalStateInternal(ResultSet* resultSet, ExecutionContext* context) override;

protected:
// vector positions
DataPos inNodeIDVectorPos;
DataPos outNodeIDVectorPos;
vector<DataPos> outPropertyVectorsPos;
// vectors
shared_ptr<ValueVector> inNodeIDVector;
shared_ptr<ValueVector> outNodeIDVector;
vector<shared_ptr<ValueVector>> outPropertyVectors;
};

} // namespace processor
} // namespace kuzu
31 changes: 12 additions & 19 deletions src/include/processor/operator/generic_extend.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "processor/operator/physical_operator.h"
#include "processor/operator/base_extend.h"
#include "storage/storage_structure/column.h"
#include "storage/storage_structure/lists/lists.h"

Expand Down Expand Up @@ -52,6 +52,8 @@ class AdjAndPropertyCollection {
bool scanList(uint32_t idx, const shared_ptr<ValueVector>& inVector,
const shared_ptr<ValueVector>& outNodeVector,
const vector<shared_ptr<ValueVector>>& outPropertyVectors, Transaction* transaction);
void scanPropertyList(uint32_t idx, const vector<shared_ptr<ValueVector>>& outPropertyVectors,
Transaction* transaction);

private:
unique_ptr<ColumnAndListCollection> adjCollection;
Expand All @@ -69,18 +71,17 @@ class AdjAndPropertyCollection {
unique_ptr<ListSyncState> listSyncState = nullptr;
};

class GenericExtend : public PhysicalOperator {
class GenericExtendAndScanRelProperties : public BaseExtendAndScanRelProperties {
public:
GenericExtend(const DataPos& inVectorPos, const DataPos& outNodeVectorPos,
vector<DataPos> outPropertyVectorsPos,
GenericExtendAndScanRelProperties(const DataPos& inNodeIDVectorPos,
const DataPos& outNodeIDVectorPos, vector<DataPos> outPropertyVectorsPos,
unordered_map<table_id_t, unique_ptr<AdjAndPropertyCollection>>
adjAndPropertyCollectionPerNodeTable,
unique_ptr<PhysicalOperator> child, uint32_t id, const string& paramsString)
: PhysicalOperator{std::move(child), id, paramsString}, inVectorPos{inVectorPos},
outNodeVectorPos{outNodeVectorPos}, outPropertyVectorsPos{std::move(
outPropertyVectorsPos)},
: BaseExtendAndScanRelProperties{inNodeIDVectorPos, outNodeIDVectorPos,
std::move(outPropertyVectorsPos), std::move(child), id, paramsString},
adjAndPropertyCollectionPerNodeTable{std::move(adjAndPropertyCollectionPerNodeTable)} {}
~GenericExtend() override = default;
~GenericExtendAndScanRelProperties() override = default;

inline PhysicalOperatorType getOperatorType() override {
return PhysicalOperatorType::GENERIC_EXTEND;
Expand All @@ -95,24 +96,16 @@ class GenericExtend : public PhysicalOperator {
for (auto& [tableID, adjAndPropertyCollection] : adjAndPropertyCollectionPerNodeTable) {
clonedCollections.insert({tableID, adjAndPropertyCollection->clone()});
}
return make_unique<GenericExtend>(inVectorPos, outNodeVectorPos, outPropertyVectorsPos,
std::move(clonedCollections), children[0]->clone(), id, paramsString);
return make_unique<GenericExtendAndScanRelProperties>(inNodeIDVectorPos, outNodeIDVectorPos,
outPropertyVectorsPos, std::move(clonedCollections), children[0]->clone(), id,
paramsString);
}

private:
bool scanCurrentAdjAndPropertyCollection();
void initCurrentAdjAndPropertyCollection(const nodeID_t& nodeID);

private:
// vector positions
DataPos inVectorPos;
DataPos outNodeVectorPos;
vector<DataPos> outPropertyVectorsPos;
// vectors
shared_ptr<ValueVector> inVector;
shared_ptr<ValueVector> outNodeVector;
vector<shared_ptr<ValueVector>> outPropertyVectors;
// storage structures
unordered_map<table_id_t, unique_ptr<AdjAndPropertyCollection>>
adjAndPropertyCollectionPerNodeTable;
AdjAndPropertyCollection* currentAdjAndPropertyCollection = nullptr;
Expand Down
31 changes: 18 additions & 13 deletions src/include/processor/operator/scan_column/adj_column_extend.h
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
#pragma once

#include "processor/operator/base_extend.h"
#include "processor/operator/filtering_operator.h"
#include "processor/operator/scan_column/scan_column.h"
#include "storage/storage_structure/column.h"

namespace kuzu {
namespace processor {

class AdjColumnExtend : public ScanSingleColumn, public FilteringOperator {

class ColumnExtendAndScanRelProperties : public BaseExtendAndScanRelProperties,
public FilteringOperator {
public:
AdjColumnExtend(const DataPos& inputNodeIDVectorPos, const DataPos& outputNodeIDVectorPos,
Column* nodeIDColumn, unique_ptr<PhysicalOperator> child, uint32_t id,
ColumnExtendAndScanRelProperties(const DataPos& inNodeIDVectorPos,
const DataPos& outNodeIDVectorPos, vector<DataPos> outPropertyVectorsPos, Column* adjColumn,
vector<Column*> propertyColumns, unique_ptr<PhysicalOperator> child, uint32_t id,
const string& paramsString)
: ScanSingleColumn{inputNodeIDVectorPos, outputNodeIDVectorPos, move(child), id,
paramsString},
FilteringOperator{1 /* numStatesToSave */}, nodeIDColumn{nodeIDColumn} {}
: BaseExtendAndScanRelProperties{inNodeIDVectorPos, outNodeIDVectorPos,
std::move(outPropertyVectorsPos), std::move(child), id, paramsString},
FilteringOperator{1 /* numStatesToSave */}, adjColumn{adjColumn},
propertyColumns{std::move(propertyColumns)} {}
~ColumnExtendAndScanRelProperties() override = default;

PhysicalOperatorType getOperatorType() override { return COLUMN_EXTEND; }
inline PhysicalOperatorType getOperatorType() override { return COLUMN_EXTEND; }

bool getNextTuplesInternal() override;

unique_ptr<PhysicalOperator> clone() override {
return make_unique<AdjColumnExtend>(inputNodeIDVectorPos, outputVectorPos, nodeIDColumn,
children[0]->clone(), id, paramsString);
inline unique_ptr<PhysicalOperator> clone() override {
return make_unique<ColumnExtendAndScanRelProperties>(inNodeIDVectorPos, outNodeIDVectorPos,
outPropertyVectorsPos, adjColumn, propertyColumns, children[0]->clone(), id,
paramsString);
}

private:
Column* nodeIDColumn;
Column* adjColumn;
vector<Column*> propertyColumns;
};

} // namespace processor
Expand Down
Loading

0 comments on commit 2463999

Please sign in to comment.