-
Notifications
You must be signed in to change notification settings - Fork 470
vector extension optional params + features #5955
Changes from 12 commits
3e16709
116fbab
6ff9087
31708d0
c755952
b262c50
8b05d3b
9ffda8f
750d3e7
1ba2062
567cd37
fffb318
c90c925
93eec34
456ea05
395ac62
23f903b
410f0d5
109f99a
aa33657
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||
| #include "catalog/catalog_entry/function_catalog_entry.h" | ||||||
| #include "catalog/catalog_entry/node_table_catalog_entry.h" | ||||||
| #include "catalog/hnsw_index_catalog_entry.h" | ||||||
| #include "common/exception/binder.h" | ||||||
| #include "function/built_in_function_utils.h" | ||||||
| #include "function/hnsw_index_functions.h" | ||||||
| #include "function/table/bind_data.h" | ||||||
|
|
@@ -44,14 +45,21 @@ static std::unique_ptr<TableFuncBindData> createInMemHNSWBindFunc(main::ClientCo | |||||
| const auto tableName = input->getLiteralVal<std::string>(0); | ||||||
| const auto indexName = input->getLiteralVal<std::string>(1); | ||||||
| const auto columnName = input->getLiteralVal<std::string>(2); | ||||||
| auto tableEntry = HNSWIndexUtils::bindNodeTable(*context, tableName, indexName, | ||||||
| HNSWIndexUtils::IndexOperation::CREATE); | ||||||
| const auto tableID = tableEntry->getTableID(); | ||||||
| HNSWIndexUtils::validateColumnType(*tableEntry, columnName); | ||||||
| auto config = HNSWIndexConfig{input->optionalParams}; | ||||||
| const auto operation = config.skipIfExists ? | ||||||
| HNSWIndexUtils::IndexOperation::CREATE_IF_NOT_EXISTS : | ||||||
| HNSWIndexUtils::IndexOperation::CREATE; | ||||||
| const auto tableEntry = HNSWIndexUtils::bindTable(*context, tableName); | ||||||
| if (HNSWIndexUtils::validateIndexExistence(*context, tableEntry, indexName, operation)) { | ||||||
| return std::make_unique<CreateHNSWIndexBindData>(context, indexName, nullptr, 0, 0, | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We inline comments as follows:
Suggested change
|
||||||
| std::move(config), true); | ||||||
| } | ||||||
| const auto nodeTableEntry = tableEntry->ptrCast<catalog::NodeTableCatalogEntry>(); | ||||||
| const auto tableID = nodeTableEntry->getTableID(); | ||||||
| HNSWIndexUtils::validateColumnType(*nodeTableEntry, columnName); | ||||||
| const auto& table = | ||||||
| storage::StorageManager::Get(*context)->getTable(tableID)->cast<storage::NodeTable>(); | ||||||
| auto propertyID = tableEntry->getPropertyID(columnName); | ||||||
| auto config = HNSWIndexConfig{input->optionalParams}; | ||||||
| auto propertyID = nodeTableEntry->getPropertyID(columnName); | ||||||
| auto numNodes = table.getStats(context->getTransaction()).getTableCard(); | ||||||
| return std::make_unique<CreateHNSWIndexBindData>(context, indexName, tableEntry, propertyID, | ||||||
| numNodes, std::move(config)); | ||||||
|
|
@@ -326,6 +334,9 @@ static std::string rewriteCreateHNSWQuery(main::ClientContext& context, | |||||
| const TableFuncBindData& bindData) { | ||||||
| context.setUseInternalCatalogEntry(true /* useInternalCatalogEntry */); | ||||||
| const auto hnswBindData = bindData.constPtrCast<CreateHNSWIndexBindData>(); | ||||||
| if (hnswBindData->skipAfterBind) { | ||||||
| return ""; | ||||||
| } | ||||||
| std::string query = "BEGIN TRANSACTION;"; | ||||||
| auto indexName = hnswBindData->indexName; | ||||||
| auto tableName = hnswBindData->tableEntry->getName(); | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| #include "catalog/catalog.h" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need such function right now. @ray6080 can comment there as well.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fine either ways, just saw a usecase here: https://github.com/getzep/graphiti/blob/c0fcc82ebef01dadde12d669dfe3beadfa238a1e/graphiti_core/utils/maintenance/graph_data_operations.py#L40 |
||
| #include "catalog/catalog_entry/index_catalog_entry.h" | ||
| #include "catalog/catalog_entry/node_table_catalog_entry.h" | ||
| #include "catalog/hnsw_index_catalog_entry.h" | ||
| #include "common/exception/binder.h" | ||
| #include "function/hnsw_index_functions.h" | ||
| #include "function/table/bind_data.h" | ||
| #include "index/hnsw_index_utils.h" | ||
| #include "main/client_context.h" | ||
| #include "processor/execution_context.h" | ||
| #include "storage/storage_manager.h" | ||
|
|
||
| using namespace kuzu::function; | ||
|
|
||
| namespace kuzu { | ||
| namespace vector_extension { | ||
|
|
||
| struct DropAllHNSWIndexesBindData final : TableFuncBindData { | ||
| catalog::NodeTableCatalogEntry* tableEntry; | ||
| std::vector<std::string> indexNames; | ||
|
|
||
| DropAllHNSWIndexesBindData(catalog::NodeTableCatalogEntry* tableEntry, | ||
| std::vector<std::string> indexNames) | ||
| : TableFuncBindData{0}, tableEntry{tableEntry}, indexNames{std::move(indexNames)} {} | ||
|
|
||
| std::unique_ptr<TableFuncBindData> copy() const override { | ||
| return std::make_unique<DropAllHNSWIndexesBindData>(tableEntry, indexNames); | ||
| } | ||
| }; | ||
|
|
||
| static std::unique_ptr<TableFuncBindData> bindFunc(main::ClientContext* context, | ||
| const TableFuncBindInput* input) { | ||
| const auto tableName = input->getLiteralVal<std::string>(0); | ||
| const auto tableEntry = HNSWIndexUtils::bindTable(*context, tableName); | ||
| const auto nodeTableEntry = tableEntry->ptrCast<catalog::NodeTableCatalogEntry>(); | ||
| const auto tableID = tableEntry->getTableID(); | ||
| std::vector<std::string> vectorIndexes; | ||
| auto indexEntries = | ||
| catalog::Catalog::Get(*context)->getIndexEntries(context->getTransaction(), tableID); | ||
| for (auto indexEntry : indexEntries) { | ||
| if (indexEntry->getIndexType() == HNSWIndexCatalogEntry::TYPE_NAME) { | ||
| vectorIndexes.push_back(indexEntry->getIndexName()); | ||
| } | ||
| } | ||
| return std::make_unique<DropAllHNSWIndexesBindData>(nodeTableEntry, vectorIndexes); | ||
| } | ||
|
|
||
| static std::string dropAllHNSWIndexesTables(main::ClientContext& context, | ||
| const TableFuncBindData& bindData) { | ||
| const auto dropAllHNSWIndexesBindData = bindData.constPtrCast<DropAllHNSWIndexesBindData>(); | ||
| context.setUseInternalCatalogEntry(true /* useInternalCatalogEntry */); | ||
| std::string query = ""; | ||
| for (const auto& indexName : dropAllHNSWIndexesBindData->indexNames) { | ||
| const auto requireNewTransaction = !context.getTransactionContext()->hasActiveTransaction(); | ||
| if (requireNewTransaction) { | ||
| query += "BEGIN TRANSACTION;"; | ||
| } | ||
| auto nodeTableID = dropAllHNSWIndexesBindData->tableEntry->getTableID(); | ||
| query += common::stringFormat("CALL _DROP_HNSW_INDEX('{}', '{}');", | ||
| dropAllHNSWIndexesBindData->tableEntry->getName(), indexName); | ||
| query += common::stringFormat("DROP TABLE {};", | ||
| HNSWIndexUtils::getUpperGraphTableName(nodeTableID, indexName)); | ||
| query += common::stringFormat("DROP TABLE {};", | ||
| HNSWIndexUtils::getLowerGraphTableName(nodeTableID, indexName)); | ||
| if (requireNewTransaction) { | ||
| query += "COMMIT;"; | ||
| } | ||
| } | ||
| return query; | ||
| } | ||
|
|
||
| function_set DropAllVectorIndexesFunction::getFunctionSet() { | ||
| function_set functionSet; | ||
| std::vector inputTypes = {common::LogicalTypeID::STRING}; | ||
| auto func = std::make_unique<TableFunction>(name, inputTypes); | ||
| func->tableFunc = TableFunction::emptyTableFunc; | ||
| func->bindFunc = bindFunc; | ||
| func->initSharedStateFunc = SimpleTableFunc::initSharedState; | ||
| func->initLocalStateFunc = TableFunction::initEmptyLocalState; | ||
| func->rewriteFunc = dropAllHNSWIndexesTables; | ||
| func->canParallelFunc = [] { return false; }; | ||
| functionSet.push_back(std::move(func)); | ||
| return functionSet; | ||
| } | ||
|
|
||
| } // namespace vector_extension | ||
| } // namespace kuzu | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| #include "catalog/catalog.h" | ||
| #include "catalog/catalog_entry/node_table_catalog_entry.h" | ||
| #include "common/exception/binder.h" | ||
| #include "function/hnsw_index_functions.h" | ||
| #include "function/table/bind_data.h" | ||
| #include "index/hnsw_index_utils.h" | ||
|
|
@@ -15,22 +16,31 @@ namespace vector_extension { | |
| struct DropHNSWIndexBindData final : TableFuncBindData { | ||
| catalog::NodeTableCatalogEntry* tableEntry; | ||
| std::string indexName; | ||
| bool skipAfterBind; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename to something along the line of |
||
|
|
||
| DropHNSWIndexBindData(catalog::NodeTableCatalogEntry* tableEntry, std::string indexName) | ||
| : TableFuncBindData{0}, tableEntry{tableEntry}, indexName{std::move(indexName)} {} | ||
| DropHNSWIndexBindData(catalog::NodeTableCatalogEntry* tableEntry, std::string indexName, | ||
| bool skipAfterBind = false) | ||
| : TableFuncBindData{0}, tableEntry{tableEntry}, indexName{std::move(indexName)}, | ||
| skipAfterBind{skipAfterBind} {} | ||
|
|
||
| std::unique_ptr<TableFuncBindData> copy() const override { | ||
| return std::make_unique<DropHNSWIndexBindData>(tableEntry, indexName); | ||
| return std::make_unique<DropHNSWIndexBindData>(tableEntry, indexName, skipAfterBind); | ||
| } | ||
| }; | ||
|
|
||
| static std::unique_ptr<TableFuncBindData> bindFunc(main::ClientContext* context, | ||
| const TableFuncBindInput* input) { | ||
| const auto tableName = input->getLiteralVal<std::string>(0); | ||
| const auto indexName = input->getLiteralVal<std::string>(1); | ||
| const auto tableEntry = HNSWIndexUtils::bindNodeTable(*context, tableName, indexName, | ||
| HNSWIndexUtils::IndexOperation::DROP); | ||
| return std::make_unique<DropHNSWIndexBindData>(tableEntry, indexName); | ||
| auto config = DropHNSWConfig{input->optionalParams}; | ||
| const auto operation = config.skipIfNotExists ? HNSWIndexUtils::IndexOperation::DROP_IF_EXISTS : | ||
| HNSWIndexUtils::IndexOperation::DROP; | ||
| const auto tableEntry = HNSWIndexUtils::bindTable(*context, tableName); | ||
| if (!HNSWIndexUtils::validateIndexExistence(*context, tableEntry, indexName, operation)) { | ||
| return std::make_unique<DropHNSWIndexBindData>(nullptr, indexName, true); | ||
| } | ||
| const auto nodeTableEntry = tableEntry->ptrCast<catalog::NodeTableCatalogEntry>(); | ||
| return std::make_unique<DropHNSWIndexBindData>(nodeTableEntry, indexName); | ||
| } | ||
|
|
||
| static common::offset_t internalTableFunc(const TableFuncInput& input, TableFuncOutput&) { | ||
|
|
@@ -48,6 +58,9 @@ static std::string dropHNSWIndexTables(main::ClientContext& context, | |
| const TableFuncBindData& bindData) { | ||
| const auto dropHNSWIndexBindData = bindData.constPtrCast<DropHNSWIndexBindData>(); | ||
| context.setUseInternalCatalogEntry(true /* useInternalCatalogEntry */); | ||
| if (dropHNSWIndexBindData->skipAfterBind) { | ||
| return ""; | ||
| } | ||
| std::string query = ""; | ||
| const auto requireNewTransaction = !context.getTransactionContext()->hasActiveTransaction(); | ||
| if (requireNewTransaction) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,16 +17,18 @@ struct CreateHNSWIndexBindData final : function::TableFuncBindData { | |
| catalog::TableCatalogEntry* tableEntry; | ||
| common::property_id_t propertyID; | ||
| HNSWIndexConfig config; | ||
| bool skipAfterBind; | ||
|
acquamarin marked this conversation as resolved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rename this to |
||
|
|
||
| CreateHNSWIndexBindData(main::ClientContext* context, std::string indexName, | ||
| catalog::TableCatalogEntry* tableEntry, common::property_id_t propertyID, | ||
| common::offset_t numNodes, HNSWIndexConfig config) | ||
| common::offset_t numNodes, HNSWIndexConfig config, bool skipAfterBind = false) | ||
| : TableFuncBindData{numNodes}, context{context}, indexName{std::move(indexName)}, | ||
| tableEntry{tableEntry}, propertyID{propertyID}, config{std::move(config)} {} | ||
| tableEntry{tableEntry}, propertyID{propertyID}, config{std::move(config)}, | ||
| skipAfterBind{skipAfterBind} {} | ||
|
|
||
| std::unique_ptr<TableFuncBindData> copy() const override { | ||
| return std::make_unique<CreateHNSWIndexBindData>(context, indexName, tableEntry, propertyID, | ||
| numRows, config.copy()); | ||
| numRows, config.copy(), skipAfterBind); | ||
| } | ||
| }; | ||
|
|
||
|
|
@@ -141,5 +143,11 @@ struct QueryVectorIndexFunction final { | |
| static function::function_set getFunctionSet(); | ||
| }; | ||
|
|
||
| struct DropAllVectorIndexesFunction final { | ||
|
carminite marked this conversation as resolved.
Outdated
|
||
| static constexpr const char* name = "DROP_ALL_VECTOR_INDEXES"; | ||
|
|
||
| static function::function_set getFunctionSet(); | ||
| }; | ||
|
|
||
| } // namespace vector_extension | ||
| } // namespace kuzu | ||
Uh oh!
There was an error while loading. Please reload this page.