Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into clang-format-18
Browse files Browse the repository at this point in the history
  • Loading branch information
mewim committed Apr 6, 2024
2 parents 757ffe4 + 33111c8 commit df2b728
Show file tree
Hide file tree
Showing 77 changed files with 1,105 additions and 539 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Welcome to Kùzu! We are excited that you are interested in contributing to Kùzu.
Before submitting your contribution though, please make sure to take a moment and read through the following guidelines.

Join our project's [Slack workspace](https://join.slack.com/t/kuzudb/shared_invite/zt-1w0thj6s7-0bLaU8Sb~4fDMKJ~oejG_g) for real-time communication with the core team and other contributors.
Join our project's [Discord community](https://discord.gg/VtX2gw9Rug) for real-time communication with the core team and other contributors.
If you have a question or need help, feel free to ask in the appropriate channel or create an issue.

## Code of Conduct
Expand Down
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,11 @@ To learn more about installation, see our [Installation](https://docs.kuzudb.com

## Getting Started

Refer to our [Getting Started](https://docs.kuzudb.com/getting-started/) page for your first example.

More information can be found at
- [Data Import](https://docs.kuzudb.com/data-import/)
- [Cypher Reference](https://docs.kuzudb.com/cypher/)
- [Client APIs](https://docs.kuzudb.com/client-apis/)
Refer to our [Getting Started](https://docs.kuzudb.com/get-started/) page for your first example.

## Build from Source

Instructions can be found at [Build Kùzu from Source](https://docs.kuzudb.com/development/building-kuzu).
You can build from source using the instructions provided in the [developer guide](https://docs.kuzudb.com/developer-guide).

## Contributing
We welcome contributions to Kùzu. If you are interested in contributing to Kùzu, please read our [Contributing Guide](CONTRIBUTING.md).
Expand Down
3 changes: 2 additions & 1 deletion src/binder/bind/bind_updating_clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ std::unique_ptr<BoundUpdatingClause> Binder::bindMergeClause(
auto boundGraphPattern = bindGraphPattern(mergeClause.getPatternElementsRef());
rewriteMatchPattern(boundGraphPattern);
auto createInfos = bindInsertInfos(boundGraphPattern.queryGraphCollection, patternsScope);
auto distinctMark = createVariable("__distinctMark", *LogicalType::BOOL());
auto boundMergeClause =
std::make_unique<BoundMergeClause>(std::move(boundGraphPattern.queryGraphCollection),
std::move(boundGraphPattern.where), std::move(createInfos));
std::move(boundGraphPattern.where), std::move(createInfos), std::move(distinctMark));
if (mergeClause.hasOnMatchSetItems()) {
for (auto& [lhs, rhs] : mergeClause.getOnMatchSetItemsRef()) {
auto setPropertyInfo = bindSetPropertyInfo(lhs.get(), rhs.get());
Expand Down
8 changes: 5 additions & 3 deletions src/c_api/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ kuzu_query_result* kuzu_connection_query(kuzu_connection* connection, const char
if (query_result == nullptr) {
return nullptr;
}
auto* c_query_result = new kuzu_query_result;
auto* c_query_result = (kuzu_query_result*)malloc(sizeof(kuzu_query_result));
c_query_result->_query_result = query_result;
c_query_result->_is_owned_by_cpp = false;
return c_query_result;
} catch (Exception& e) { return nullptr; }
}
Expand All @@ -64,7 +65,7 @@ kuzu_prepared_statement* kuzu_connection_prepare(kuzu_connection* connection, co
if (prepared_statement == nullptr) {
return nullptr;
}
auto* c_prepared_statement = new kuzu_prepared_statement;
auto* c_prepared_statement = (kuzu_prepared_statement*)malloc(sizeof(kuzu_prepared_statement));
c_prepared_statement->_prepared_statement = prepared_statement;
c_prepared_statement->_bound_values =
new std::unordered_map<std::string, std::unique_ptr<Value>>;
Expand Down Expand Up @@ -92,8 +93,9 @@ kuzu_query_result* kuzu_connection_execute(
if (query_result == nullptr) {
return nullptr;
}
auto* c_query_result = new kuzu_query_result;
auto* c_query_result = (kuzu_query_result*)malloc(sizeof(kuzu_query_result));
c_query_result->_query_result = query_result;
c_query_result->_is_owned_by_cpp = false;
return c_query_result;
}

Expand Down
2 changes: 1 addition & 1 deletion src/c_api/prepared_statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void kuzu_prepared_statement_destroy(kuzu_prepared_statement* prepared_statement
delete static_cast<std::unordered_map<std::string, std::unique_ptr<Value>>*>(
prepared_statement->_bound_values);
}
delete prepared_statement;
free(prepared_statement);
}

bool kuzu_prepared_statement_allow_active_transaction(kuzu_prepared_statement* prepared_statement) {
Expand Down
22 changes: 20 additions & 2 deletions src/c_api/query_result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ void kuzu_query_result_destroy(kuzu_query_result* query_result) {
return;
}
if (query_result->_query_result != nullptr) {
delete static_cast<QueryResult*>(query_result->_query_result);
if (!query_result->_is_owned_by_cpp) {
delete static_cast<QueryResult*>(query_result->_query_result);
}
}
delete query_result;
free(query_result);
}

bool kuzu_query_result_is_success(kuzu_query_result* query_result) {
Expand Down Expand Up @@ -69,6 +71,22 @@ bool kuzu_query_result_has_next(kuzu_query_result* query_result) {
return static_cast<QueryResult*>(query_result->_query_result)->hasNext();
}

bool kuzu_query_result_has_next_query_result(kuzu_query_result* query_result) {
return static_cast<QueryResult*>(query_result->_query_result)->hasNextQueryResult();
}

kuzu_query_result* kuzu_query_result_get_next_query_result(kuzu_query_result* query_result) {
auto next_query_result =
static_cast<QueryResult*>(query_result->_query_result)->getNextQueryResult();
if (next_query_result == nullptr) {
return nullptr;
}
auto* c_query_result = (kuzu_query_result*)malloc(sizeof(kuzu_query_result));
c_query_result->_query_result = next_query_result;
c_query_result->_is_owned_by_cpp = true;
return c_query_result;
}

kuzu_flat_tuple* kuzu_query_result_get_next(kuzu_query_result* query_result) {
auto flat_tuple = static_cast<QueryResult*>(query_result->_query_result)->getNext();
auto* flat_tuple_c = (kuzu_flat_tuple*)malloc(sizeof(kuzu_flat_tuple));
Expand Down
54 changes: 28 additions & 26 deletions src/include/binder/query/updating_clause/bound_merge_clause.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,91 +11,92 @@ namespace binder {
class BoundMergeClause : public BoundUpdatingClause {
public:
BoundMergeClause(QueryGraphCollection queryGraphCollection,
std::shared_ptr<Expression> predicate, std::vector<BoundInsertInfo> insertInfos)
: BoundUpdatingClause{common::ClauseType::MERGE}, queryGraphCollection{std::move(
queryGraphCollection)},
predicate{std::move(predicate)}, insertInfos{std::move(insertInfos)} {}
std::shared_ptr<Expression> predicate, std::vector<BoundInsertInfo> insertInfos,
std::shared_ptr<Expression> distinctMark)
: BoundUpdatingClause{common::ClauseType::MERGE},
queryGraphCollection{std::move(queryGraphCollection)}, predicate{std::move(predicate)},
insertInfos{std::move(insertInfos)}, distinctMark{std::move(distinctMark)} {}

inline const QueryGraphCollection* getQueryGraphCollection() const {
return &queryGraphCollection;
}
inline bool hasPredicate() const { return predicate != nullptr; }
inline std::shared_ptr<Expression> getPredicate() const { return predicate; }
const QueryGraphCollection* getQueryGraphCollection() const { return &queryGraphCollection; }
bool hasPredicate() const { return predicate != nullptr; }
std::shared_ptr<Expression> getPredicate() const { return predicate; }

inline const std::vector<BoundInsertInfo>& getInsertInfosRef() const { return insertInfos; }
inline const std::vector<BoundSetPropertyInfo>& getOnMatchSetInfosRef() const {
const std::vector<BoundInsertInfo>& getInsertInfosRef() const { return insertInfos; }
const std::vector<BoundSetPropertyInfo>& getOnMatchSetInfosRef() const {
return onMatchSetPropertyInfos;
}
inline const std::vector<BoundSetPropertyInfo>& getOnCreateSetInfosRef() const {
const std::vector<BoundSetPropertyInfo>& getOnCreateSetInfosRef() const {
return onCreateSetPropertyInfos;
}

inline bool hasInsertNodeInfo() const {
bool hasInsertNodeInfo() const {
return hasInsertInfo(
[](const BoundInsertInfo& info) { return info.tableType == common::TableType::NODE; });
}
inline std::vector<const BoundInsertInfo*> getInsertNodeInfos() const {
std::vector<const BoundInsertInfo*> getInsertNodeInfos() const {
return getInsertInfos(
[](const BoundInsertInfo& info) { return info.tableType == common::TableType::NODE; });
}
inline bool hasInsertRelInfo() const {
bool hasInsertRelInfo() const {
return hasInsertInfo(
[](const BoundInsertInfo& info) { return info.tableType == common::TableType::REL; });
}
inline std::vector<const BoundInsertInfo*> getInsertRelInfos() const {
std::vector<const BoundInsertInfo*> getInsertRelInfos() const {
return getInsertInfos(
[](const BoundInsertInfo& info) { return info.tableType == common::TableType::REL; });
}

inline bool hasOnMatchSetNodeInfo() const {
bool hasOnMatchSetNodeInfo() const {
return hasOnMatchSetInfo([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::NODE;
});
}
inline std::vector<const BoundSetPropertyInfo*> getOnMatchSetNodeInfos() const {
std::vector<const BoundSetPropertyInfo*> getOnMatchSetNodeInfos() const {
return getOnMatchSetInfos([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::NODE;
});
}
inline bool hasOnMatchSetRelInfo() const {
bool hasOnMatchSetRelInfo() const {
return hasOnMatchSetInfo([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::REL;
});
}
inline std::vector<const BoundSetPropertyInfo*> getOnMatchSetRelInfos() const {
std::vector<const BoundSetPropertyInfo*> getOnMatchSetRelInfos() const {
return getOnMatchSetInfos([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::REL;
});
}

inline bool hasOnCreateSetNodeInfo() const {
bool hasOnCreateSetNodeInfo() const {
return hasOnCreateSetInfo([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::NODE;
});
}
inline std::vector<const BoundSetPropertyInfo*> getOnCreateSetNodeInfos() const {
std::vector<const BoundSetPropertyInfo*> getOnCreateSetNodeInfos() const {
return getOnCreateSetInfos([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::NODE;
});
}
inline bool hasOnCreateSetRelInfo() const {
bool hasOnCreateSetRelInfo() const {
return hasOnCreateSetInfo([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::REL;
});
}
inline std::vector<const BoundSetPropertyInfo*> getOnCreateSetRelInfos() const {
std::vector<const BoundSetPropertyInfo*> getOnCreateSetRelInfos() const {
return getOnCreateSetInfos([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::REL;
});
}

inline void addOnMatchSetPropertyInfo(BoundSetPropertyInfo setPropertyInfo) {
void addOnMatchSetPropertyInfo(BoundSetPropertyInfo setPropertyInfo) {
onMatchSetPropertyInfos.push_back(std::move(setPropertyInfo));
}
inline void addOnCreateSetPropertyInfo(BoundSetPropertyInfo setPropertyInfo) {
void addOnCreateSetPropertyInfo(BoundSetPropertyInfo setPropertyInfo) {
onCreateSetPropertyInfos.push_back(std::move(setPropertyInfo));
}

std::shared_ptr<Expression> getDistinctMark() const { return distinctMark; }

private:
bool hasInsertInfo(const std::function<bool(const BoundInsertInfo& info)>& check) const;
std::vector<const BoundInsertInfo*> getInsertInfos(
Expand All @@ -121,6 +122,7 @@ class BoundMergeClause : public BoundUpdatingClause {
std::vector<BoundSetPropertyInfo> onMatchSetPropertyInfos;
// Update on create
std::vector<BoundSetPropertyInfo> onCreateSetPropertyInfos;
std::shared_ptr<Expression> distinctMark;
};

} // namespace binder
Expand Down
15 changes: 15 additions & 0 deletions src/include/c_api/kuzu.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ typedef struct {
*/
typedef struct {
void* _query_result;
bool _is_owned_by_cpp;
} kuzu_query_result;

/**
Expand Down Expand Up @@ -630,6 +631,20 @@ KUZU_C_API bool kuzu_query_result_has_next(kuzu_query_result* query_result);
* @param query_result The query result instance to return.
*/
KUZU_C_API kuzu_flat_tuple* kuzu_query_result_get_next(kuzu_query_result* query_result);
/**
* @brief Returns true if we have not consumed all query results, false otherwise. Use this function
* for loop results of multiple query statements
* @param query_result The query result instance to check.
*/
KUZU_C_API bool kuzu_query_result_has_next_query_result(kuzu_query_result* query_result);
/**
* @brief Returns the next query result. Use this function to loop multiple query statements'
* results.
* @param query_result The query result instance to return.
*/
KUZU_C_API kuzu_query_result* kuzu_query_result_get_next_query_result(
kuzu_query_result* query_result);

/**
* @brief Returns the query result as a string.
* @param query_result The query result instance to return.
Expand Down
3 changes: 2 additions & 1 deletion src/include/function/null/null_function_executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ struct NullOperationExecutor {
auto resultValues = (uint8_t*)result.getData();
if (operand.state->isFlat()) {
auto pos = operand.state->selVector->selectedPositions[0];
auto resultPos = result.state->selVector->selectedPositions[0];
FUNC::operation(
operand.getValue<uint8_t>(pos), (bool)operand.isNull(pos), resultValues[pos]);
operand.getValue<uint8_t>(pos), (bool)operand.isNull(pos), resultValues[resultPos]);
} else {
if (operand.state->selVector->isUnfiltered()) {
for (auto i = 0u; i < operand.state->selVector->selectedSize; i++) {
Expand Down
22 changes: 17 additions & 5 deletions src/include/main/query_result.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class QueryResult {
QueryResult* currentResult;

public:
QueryResultIterator() = default;

explicit QueryResultIterator(QueryResult* startResult) : currentResult(startResult) {}

void operator++() {
Expand All @@ -46,9 +48,9 @@ class QueryResult {
}
}

bool isEnd() { return currentResult == nullptr; }
bool isEnd() const { return currentResult == nullptr; }

QueryResult* getCurrentResult() { return currentResult; }
QueryResult* getCurrentResult() const { return currentResult; }
};

public:
Expand Down Expand Up @@ -97,15 +99,22 @@ class QueryResult {
* @return whether there are more tuples to read.
*/
KUZU_API bool hasNext() const;
std::unique_ptr<QueryResult> nextQueryResult;
/**
* @return whether there are more query results to read.
*/
KUZU_API bool hasNextQueryResult() const;
/**
* @return get next query result to read (for multiple query statements).
*/
KUZU_API QueryResult* getNextQueryResult();

std::string toSingleQueryString();
std::unique_ptr<QueryResult> nextQueryResult;
/**
* @return next flat tuple in the query result.
*/
KUZU_API std::shared_ptr<processor::FlatTuple> getNext();
/**
* @return string of query result.
* @return string of first query result.
*/
KUZU_API std::string toString();

Expand Down Expand Up @@ -158,6 +167,9 @@ class QueryResult {

// execution statistics
std::unique_ptr<QuerySummary> querySummary;

// query iterator
QueryResultIterator queryResultIterator;
};

} // namespace main
Expand Down
3 changes: 2 additions & 1 deletion src/include/optimizer/factorization_rewriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace kuzu {
namespace optimizer {

class FactorizationRewriter : public LogicalOperatorVisitor {
class FactorizationRewriter final : public LogicalOperatorVisitor {
public:
void rewrite(planner::LogicalPlan* plan);

Expand All @@ -19,6 +19,7 @@ class FactorizationRewriter : public LogicalOperatorVisitor {
void visitIntersect(planner::LogicalOperator* op) override;
void visitProjection(planner::LogicalOperator* op) override;
void visitAccumulate(planner::LogicalOperator* op) override;
void visitMarkAccumulate(planner::LogicalOperator*) override;
void visitAggregate(planner::LogicalOperator* op) override;
void visitOrderBy(planner::LogicalOperator* op) override;
void visitLimit(planner::LogicalOperator* op) override;
Expand Down
6 changes: 6 additions & 0 deletions src/include/optimizer/logical_operator_visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ class LogicalOperatorVisitor {
return op;
}

virtual void visitMarkAccumulate(planner::LogicalOperator* /*op*/) {}
virtual std::shared_ptr<planner::LogicalOperator> visitMarkAccumulateReplace(
std::shared_ptr<planner::LogicalOperator> op) {
return op;
}

virtual void visitDistinct(planner::LogicalOperator* /*op*/) {}
virtual std::shared_ptr<planner::LogicalOperator> visitDistinctReplace(
std::shared_ptr<planner::LogicalOperator> op) {
Expand Down
Loading

0 comments on commit df2b728

Please sign in to comment.