diff --git a/src/include/processor/operator/persistent/delete_executor.h b/src/include/processor/operator/persistent/delete_executor.h index 3d6ad25a319..d2e7a896b10 100644 --- a/src/include/processor/operator/persistent/delete_executor.h +++ b/src/include/processor/operator/persistent/delete_executor.h @@ -25,17 +25,17 @@ class NodeDeleteExecutor { common::ValueVector* nodeIDVector; }; -class SingleLabelNodeDeleteExecutor : public NodeDeleteExecutor { +class SingleLabelNodeDeleteExecutor final : public NodeDeleteExecutor { public: SingleLabelNodeDeleteExecutor(storage::NodeTable* table, const DataPos& nodeIDPos) : NodeDeleteExecutor(nodeIDPos), table{table} {} SingleLabelNodeDeleteExecutor(const SingleLabelNodeDeleteExecutor& other) : NodeDeleteExecutor(other.nodeIDPos), table{other.table} {} - void init(ResultSet* resultSet, ExecutionContext* context) final; - void delete_(ExecutionContext* context) final; + void init(ResultSet* resultSet, ExecutionContext* context); + void delete_(ExecutionContext* context); - inline std::unique_ptr copy() const final { + inline std::unique_ptr copy() const { return std::make_unique(*this); } @@ -44,7 +44,7 @@ class SingleLabelNodeDeleteExecutor : public NodeDeleteExecutor { std::unique_ptr pkVector; }; -class MultiLabelNodeDeleteExecutor : public NodeDeleteExecutor { +class MultiLabelNodeDeleteExecutor final : public NodeDeleteExecutor { public: MultiLabelNodeDeleteExecutor( std::unordered_map tableIDToTableMap, @@ -53,10 +53,10 @@ class MultiLabelNodeDeleteExecutor : public NodeDeleteExecutor { MultiLabelNodeDeleteExecutor(const MultiLabelNodeDeleteExecutor& other) : NodeDeleteExecutor(other.nodeIDPos), tableIDToTableMap{other.tableIDToTableMap} {} - void init(ResultSet* resultSet, ExecutionContext* context) final; - void delete_(ExecutionContext* context) final; + void init(ResultSet* resultSet, ExecutionContext* context); + void delete_(ExecutionContext* context); - inline std::unique_ptr copy() const final { + inline std::unique_ptr copy() const { return std::make_unique(*this); } @@ -75,7 +75,7 @@ class RelDeleteExecutor { void init(ResultSet* resultSet, ExecutionContext* context); - virtual void delete_() = 0; + virtual void delete_(ExecutionContext* context) = 0; virtual std::unique_ptr copy() const = 0; @@ -97,7 +97,7 @@ class SingleLabelRelDeleteExecutor final : public RelDeleteExecutor { relsStatistic{relsStatistic}, table{table} {} SingleLabelRelDeleteExecutor(const SingleLabelRelDeleteExecutor& other) = default; - void delete_(); + void delete_(ExecutionContext* context); inline std::unique_ptr copy() const { return std::make_unique(*this); @@ -119,7 +119,7 @@ class MultiLabelRelDeleteExecutor final : public RelDeleteExecutor { tableIDToTableMap)} {} MultiLabelRelDeleteExecutor(const MultiLabelRelDeleteExecutor& other) = default; - void delete_(); + void delete_(ExecutionContext* context); inline std::unique_ptr copy() const { return std::make_unique(*this); diff --git a/src/include/storage/local_storage/local_rel_table.h b/src/include/storage/local_storage/local_rel_table.h index a2c86bf4ff7..1a2e0cd574c 100644 --- a/src/include/storage/local_storage/local_rel_table.h +++ b/src/include/storage/local_storage/local_rel_table.h @@ -73,7 +73,7 @@ class LocalRelNG final : public LocalNodeGroup { const std::vector& propertyVectors); void update(common::ValueVector* srcNodeIDVector, common::ValueVector* relIDVector, common::column_id_t columnID, common::ValueVector* propertyVector); - void delete_(common::ValueVector* srcNodeIDVector, common::ValueVector* relIDVector); + bool delete_(common::ValueVector* srcNodeIDVector, common::ValueVector* relIDVector); inline LocalVectorCollection* getAdjChunk() { return adjChunk.get(); } inline LocalVectorCollection* getPropertyChunk(common::column_id_t columnID) { @@ -99,7 +99,8 @@ class LocalRelTableData final : public LocalTableData { const std::vector& propertyVectors); void update(common::ValueVector* srcNodeIDVector, common::ValueVector* relIDVector, common::column_id_t columnID, common::ValueVector* propertyVector); - void delete_(common::ValueVector* srcNodeIDVector, common::ValueVector* relIDVector); + bool delete_(common::ValueVector* srcNodeIDVector, common::ValueVector* dstNodeIDVector, + common::ValueVector* relIDVector); private: LocalNodeGroup* getOrCreateLocalNodeGroup(common::ValueVector* nodeIDVector); diff --git a/src/include/storage/local_storage/local_table.h b/src/include/storage/local_storage/local_table.h index bdff88340c2..cba9c28698b 100644 --- a/src/include/storage/local_storage/local_table.h +++ b/src/include/storage/local_storage/local_table.h @@ -44,8 +44,8 @@ class LocalVector { // contains 64 vectors (chunks). class LocalVectorCollection { public: - LocalVectorCollection(const common::LogicalType* dataType, MemoryManager* mm) - : dataType{dataType}, mm{mm}, numRows{0} {} + LocalVectorCollection(std::unique_ptr dataType, MemoryManager* mm) + : dataType{std::move(dataType)}, mm{mm}, numRows{0} {} void read(common::row_idx_t rowIdx, common::ValueVector* outputVector, common::sel_t posInOutputVector); @@ -62,7 +62,7 @@ class LocalVectorCollection { void prepareAppend(); private: - const common::LogicalType* dataType; + std::unique_ptr dataType; MemoryManager* mm; std::vector> vectors; common::row_idx_t numRows; diff --git a/src/include/storage/store/rel_table.h b/src/include/storage/store/rel_table.h index 2a81f2e5ecb..ae37b371824 100644 --- a/src/include/storage/store/rel_table.h +++ b/src/include/storage/store/rel_table.h @@ -28,9 +28,14 @@ class RelTable : public Table { common::ValueVector* inNodeIDVector, const std::vector& outputVectors) final; + void insert(transaction::Transaction* transaction, common::ValueVector* srcNodeIDVector, + common::ValueVector* dstNodeIDVector, + const std::vector& propertyVectors); void update(transaction::Transaction* transaction, common::column_id_t columnID, common::ValueVector* srcNodeIDVector, common::ValueVector* dstNodeIDVector, common::ValueVector* relIDVector, common::ValueVector* propertyVector); + void delete_(transaction::Transaction* transaction, common::ValueVector* srcNodeIDVector, + common::ValueVector* dstNodeIDVector, common::ValueVector* relIDVector); void addColumn(transaction::Transaction* transaction, const catalog::Property& property, common::ValueVector* defaultValueVector) final; diff --git a/src/include/storage/store/rel_table_data.h b/src/include/storage/store/rel_table_data.h index a7b46ed767a..12371347f07 100644 --- a/src/include/storage/store/rel_table_data.h +++ b/src/include/storage/store/rel_table_data.h @@ -57,9 +57,14 @@ class RelTableData final : public TableData { common::ValueVector* inNodeIDVector, const std::vector& outputVectors); + void insert(transaction::Transaction* transaction, common::ValueVector* srcNodeIDVector, + common::ValueVector* dstNodeIDVector, + const std::vector& propertyVectors); void update(transaction::Transaction* transaction, common::column_id_t columnID, common::ValueVector* srcNodeIDVector, common::ValueVector* relIDVector, common::ValueVector* propertyVector); + bool delete_(transaction::Transaction* transaction, common::ValueVector* srcNodeIDVector, + common::ValueVector* dstNodeIDVector, common::ValueVector* relIDVector); void append(NodeGroup* nodeGroup); @@ -87,6 +92,17 @@ class RelTableData final : public TableData { void prepareCommitCSRNGWithoutSliding(transaction::Transaction* transaction, common::node_group_idx_t nodeGroupIdx, CSRRelNGInfo* relNodeGroupInfo, ColumnChunk* csrOffsetChunk, ColumnChunk* relIDChunk, LocalRelNG* localNodeGroup); + void prepareCommitCSRNGWithSliding(transaction::Transaction* transaction, + common::node_group_idx_t nodeGroupIdx, CSRRelNGInfo* relNodeGroupInfo, + ColumnChunk* csrOffsetChunk, ColumnChunk* relIDChunk, LocalRelNG* localNodeGroup); + + std::unique_ptr slideCSROffsetColumnChunk(ColumnChunk* csrOffsetChunk, + CSRRelNGInfo* relNodeGroupInfo, common::offset_t nodeGroupStartOffset); + std::unique_ptr slideCSRColumnChunk(transaction::Transaction* transaction, + ColumnChunk* csrOffsetChunk, ColumnChunk* slidedCSROffsetChunkForCheck, + ColumnChunk* relIDChunk, const offset_to_offset_to_row_idx_t& insertInfo, + const offset_to_offset_to_row_idx_t& updateInfo, const offset_to_offset_set_t& deleteInfo, + common::node_group_idx_t nodeGroupIdx, Column* column, LocalVectorCollection* localChunk); static inline common::ColumnDataFormat getDataFormatFromSchema( catalog::RelTableSchema* tableSchema, common::RelDataDirection direction) { diff --git a/src/processor/operator/persistent/delete.cpp b/src/processor/operator/persistent/delete.cpp index 20e86c6db5d..772aed15709 100644 --- a/src/processor/operator/persistent/delete.cpp +++ b/src/processor/operator/persistent/delete.cpp @@ -39,7 +39,7 @@ bool DeleteRel::getNextTuplesInternal(ExecutionContext* context) { return false; } for (auto& executor : executors) { - executor->delete_(); + executor->delete_(context); } return true; } diff --git a/src/processor/operator/persistent/delete_executor.cpp b/src/processor/operator/persistent/delete_executor.cpp index c7e8f3d93e4..2e95f2deac8 100644 --- a/src/processor/operator/persistent/delete_executor.cpp +++ b/src/processor/operator/persistent/delete_executor.cpp @@ -48,22 +48,19 @@ void RelDeleteExecutor::init(ResultSet* resultSet, ExecutionContext* /*context*/ relIDVector = resultSet->getValueVector(relIDPos).get(); } -void SingleLabelRelDeleteExecutor::delete_() { - // TODO(Guodong): Fix delete. - // table->deleteRel(srcNodeIDVector, dstNodeIDVector, relIDVector); - // relsStatistic->updateNumRelsByValue(table->getTableID(), -1); +void SingleLabelRelDeleteExecutor::delete_(ExecutionContext* context) { + table->delete_(context->clientContext->getActiveTransaction(), srcNodeIDVector, dstNodeIDVector, + relIDVector); } -void MultiLabelRelDeleteExecutor::delete_() { +void MultiLabelRelDeleteExecutor::delete_(ExecutionContext* context) { KU_ASSERT(relIDVector->state->isFlat()); auto pos = relIDVector->state->selVector->selectedPositions[0]; auto relID = relIDVector->getValue(pos); KU_ASSERT(tableIDToTableMap.contains(relID.tableID)); auto [table, statistic] = tableIDToTableMap.at(relID.tableID); - // TODO(Guodong): Fix delete. - // table->deleteRel(srcNodeIDVector, dstNodeIDVector, relIDVector); - // KU_ASSERT(table->getTableID() == relID.tableID); - // statistic->updateNumRelsByValue(table->getTableID(), -1); + table->delete_(context->clientContext->getActiveTransaction(), srcNodeIDVector, dstNodeIDVector, + relIDVector); } } // namespace processor diff --git a/src/processor/operator/persistent/insert_executor.cpp b/src/processor/operator/persistent/insert_executor.cpp index e78d9bb2d62..5bb811966bb 100644 --- a/src/processor/operator/persistent/insert_executor.cpp +++ b/src/processor/operator/persistent/insert_executor.cpp @@ -128,9 +128,7 @@ void RelInsertExecutor::insert(transaction::Transaction* tx) { for (auto i = 1; i < propertyRhsEvaluators.size(); ++i) { propertyRhsEvaluators[i]->evaluate(); } - // TODO(Guodong): Fix insert. - // table->insertRel(srcNodeIDVector, dstNodeIDVector, propertyRhsVectors); - // relsStatistics.updateNumRelsByValue(table->getRelTableID(), 1); + table->insert(tx, srcNodeIDVector, dstNodeIDVector, propertyRhsVectors); for (auto i = 0u; i < propertyLhsVectors.size(); ++i) { auto lhsVector = propertyLhsVectors[i]; auto rhsVector = propertyRhsVectors[i]; diff --git a/src/storage/local_storage/local_rel_table.cpp b/src/storage/local_storage/local_rel_table.cpp index 77c651ed376..f807762d370 100644 --- a/src/storage/local_storage/local_rel_table.cpp +++ b/src/storage/local_storage/local_rel_table.cpp @@ -23,7 +23,7 @@ void RegularRelNGInfo::insert(offset_t srcNodeOffset, offset_t /*relOffset*/, } void RegularRelNGInfo::update( - offset_t srcNodeOffset, offset_t relOffset, column_id_t columnID, row_idx_t rowIdx) { + offset_t srcNodeOffset, offset_t /*relOffset*/, column_id_t columnID, row_idx_t rowIdx) { if (deleteInfo.contains(srcNodeOffset)) { // We choose to ignore the update operation if the node is deleted. return; @@ -32,9 +32,9 @@ void RegularRelNGInfo::update( KU_ASSERT(columnID < updateInfoPerChunk.size()); if (insertInfoPerChunk[columnID].contains(srcNodeOffset)) { // Update newly inserted value. - insertInfoPerChunk[columnID][relOffset] = rowIdx; + insertInfoPerChunk[columnID][srcNodeOffset] = rowIdx; } else { - updateInfoPerChunk[columnID][relOffset] = rowIdx; + updateInfoPerChunk[columnID][srcNodeOffset] = rowIdx; } } @@ -141,13 +141,15 @@ LocalRelNG::LocalRelNG(ColumnDataFormat dataFormat, std::vector da KU_UNREACHABLE; } } + adjChunk = std::make_unique(LogicalType::INTERNAL_ID(), mm); } void LocalRelNG::insert(ValueVector* srcNodeIDVector, ValueVector* dstNodeIDVector, const std::vector& propertyVectors) { - KU_ASSERT(propertyVectors.size() == chunks.size() && propertyVectors.size() > 1); + KU_ASSERT(propertyVectors.size() == chunks.size() && propertyVectors.size() >= 1); auto adjNodeIDRowIdx = adjChunk->append(dstNodeIDVector); std::vector propertyValuesRowIdx; + propertyValuesRowIdx.reserve(propertyVectors.size()); for (auto i = 0u; i < propertyVectors.size(); ++i) { propertyValuesRowIdx.push_back(chunks[i]->append(propertyVectors[i])); } @@ -169,12 +171,12 @@ void LocalRelNG::update(ValueVector* srcNodeIDVector, ValueVector* relIDVector, relNGInfo->update(srcNodeOffset, relOffset, columnID, rowIdx); } -void LocalRelNG::delete_(ValueVector* srcNodeIDVector, ValueVector* relIDVector) { +bool LocalRelNG::delete_(ValueVector* srcNodeIDVector, ValueVector* relIDVector) { auto srcNodeIDPos = srcNodeIDVector->state->selVector->selectedPositions[0]; auto srcNodeOffset = srcNodeIDVector->getValue(srcNodeIDPos).offset; auto relIDPos = relIDVector->state->selVector->selectedPositions[0]; auto relOffset = relIDVector->getValue(relIDPos).offset; - relNGInfo->delete_(srcNodeOffset, relOffset); + return relNGInfo->delete_(srcNodeOffset, relOffset); } void LocalRelTableData::insert(ValueVector* srcNodeIDVector, ValueVector* dstNodeIDVector, @@ -197,7 +199,8 @@ void LocalRelTableData::update(ValueVector* srcNodeIDVector, ValueVector* relIDV KU_ASSERT(srcNodeIDVector->state->selVector->selectedSize == 1 && relIDVector->state->selVector->selectedSize == 1); auto srcNodeIDPos = srcNodeIDVector->state->selVector->selectedPositions[0]; - if (srcNodeIDVector->isNull(srcNodeIDPos)) { + auto relIDPos = relIDVector->state->selVector->selectedPositions[0]; + if (srcNodeIDVector->isNull(srcNodeIDPos) || relIDVector->isNull(relIDPos)) { return; } auto localNodeGroup = @@ -205,16 +208,18 @@ void LocalRelTableData::update(ValueVector* srcNodeIDVector, ValueVector* relIDV localNodeGroup->update(srcNodeIDVector, relIDVector, columnID, propertyVector); } -void LocalRelTableData::delete_(ValueVector* srcNodeIDVector, ValueVector* relIDVector) { +bool LocalRelTableData::delete_( + ValueVector* srcNodeIDVector, ValueVector* dstNodeIDVector, ValueVector* relIDVector) { KU_ASSERT(srcNodeIDVector->state->selVector->selectedSize == 1 && relIDVector->state->selVector->selectedSize == 1); auto srcNodeIDPos = srcNodeIDVector->state->selVector->selectedPositions[0]; - if (srcNodeIDVector->isNull(srcNodeIDPos)) { - return; + auto dstNodeIDPos = dstNodeIDVector->state->selVector->selectedPositions[0]; + if (srcNodeIDVector->isNull(srcNodeIDPos) || dstNodeIDVector->isNull(dstNodeIDPos)) { + return false; } auto localNodeGroup = ku_dynamic_cast(getOrCreateLocalNodeGroup(srcNodeIDVector)); - localNodeGroup->delete_(srcNodeIDVector, relIDVector); + return localNodeGroup->delete_(srcNodeIDVector, relIDVector); } LocalNodeGroup* LocalRelTableData::getOrCreateLocalNodeGroup(ValueVector* nodeIDVector) { diff --git a/src/storage/local_storage/local_table.cpp b/src/storage/local_storage/local_table.cpp index 4c9fe68c07c..8a8e4b4bd89 100644 --- a/src/storage/local_storage/local_table.cpp +++ b/src/storage/local_storage/local_table.cpp @@ -59,7 +59,7 @@ LocalNodeGroup::LocalNodeGroup(std::vector dataTypes, MemoryManage for (auto i = 0u; i < dataTypes.size(); ++i) { // To avoid unnecessary memory consumption, we chunk local changes of each column in the // node group into chunks of size DEFAULT_VECTOR_CAPACITY. - chunks[i] = std::make_unique(dataTypes[i], mm); + chunks[i] = std::make_unique(dataTypes[i]->copy(), mm); } } diff --git a/src/storage/store/column.cpp b/src/storage/store/column.cpp index 5979792a9ee..2afbc693d52 100644 --- a/src/storage/store/column.cpp +++ b/src/storage/store/column.cpp @@ -388,17 +388,15 @@ void Column::scan( columnChunk->setNumValues(0); } else { auto chunkMetadata = metadataDA->get(nodeGroupIdx, transaction->getType()); - KU_ASSERT(chunkMetadata.numValues <= columnChunk->getCapacity()); auto cursor = PageElementCursor(chunkMetadata.pageIdx, 0); uint64_t numValuesPerPage = chunkMetadata.compMeta.numValues(BufferPoolConstants::PAGE_4KB_SIZE, *dataType); uint64_t numValuesScanned = 0u; - auto numValuesToScan = columnChunk->getCapacity(); - if (chunkMetadata.numValues < numValuesToScan) { - numValuesToScan = chunkMetadata.numValues; + if (chunkMetadata.numValues > columnChunk->getCapacity()) { + columnChunk->resize(std::bit_ceil(chunkMetadata.numValues)); } + auto numValuesToScan = chunkMetadata.numValues; KU_ASSERT(chunkMetadata.numValues <= columnChunk->getCapacity()); - // TODO(Guodong): We should resize as needed here. while (numValuesScanned < numValuesToScan) { auto numValuesToReadInPage = std::min(numValuesPerPage, numValuesToScan - numValuesScanned); @@ -677,29 +675,43 @@ bool Column::canCommitInPlace(Transaction* transaction, node_group_idx_t nodeGro void Column::commitLocalChunkInPlace(Transaction* /*transaction*/, LocalVectorCollection* localChunk, const offset_to_row_idx_t& insertInfo, - const offset_to_row_idx_t& updateInfo, const offset_set_t& /*deleteInfo*/) { + const offset_to_row_idx_t& updateInfo, const offset_set_t& deleteInfo) { applyLocalChunkToColumn(localChunk, updateInfo); applyLocalChunkToColumn(localChunk, insertInfo); + // Set nulls based on deleteInfo. Note that this code path actually only gets executed when the + // column is a regular format one. This is not a good design, should be unified with csr one in + // the future. + for (auto nodeOffset : deleteInfo) { + setNull(nodeOffset); + } } void Column::commitLocalChunkOutOfPlace(Transaction* transaction, node_group_idx_t nodeGroupIdx, LocalVectorCollection* localChunk, bool isNewNodeGroup, const offset_to_row_idx_t& insertInfo, - const offset_to_row_idx_t& updateInfo, const offset_set_t& /*deleteInfo*/) { + const offset_to_row_idx_t& updateInfo, const offset_set_t& deleteInfo) { auto columnChunk = ColumnChunkFactory::createColumnChunk(dataType->copy(), enableCompression); + auto startNodeOffsetInChunk = nodeGroupIdx << StorageConstants::NODE_GROUP_SIZE_LOG2; if (isNewNodeGroup) { - KU_ASSERT(updateInfo.empty()); + KU_ASSERT(updateInfo.empty() && deleteInfo.empty()); // Apply inserts from the local chunk. - applyLocalChunkToColumnChunk(localChunk, columnChunk.get(), - nodeGroupIdx << StorageConstants::NODE_GROUP_SIZE_LOG2, insertInfo); + applyLocalChunkToColumnChunk( + localChunk, columnChunk.get(), startNodeOffsetInChunk, insertInfo); } else { // First, scan the whole column chunk from persistent storage. scan(transaction, nodeGroupIdx, columnChunk.get()); // Then, apply updates from the local chunk. - applyLocalChunkToColumnChunk(localChunk, columnChunk.get(), - nodeGroupIdx << StorageConstants::NODE_GROUP_SIZE_LOG2, updateInfo); + applyLocalChunkToColumnChunk( + localChunk, columnChunk.get(), startNodeOffsetInChunk, updateInfo); // Lastly, apply inserts from the local chunk. - applyLocalChunkToColumnChunk(localChunk, columnChunk.get(), - nodeGroupIdx << StorageConstants::NODE_GROUP_SIZE_LOG2, insertInfo); + applyLocalChunkToColumnChunk( + localChunk, columnChunk.get(), startNodeOffsetInChunk, insertInfo); + if (columnChunk->getNullChunk()) { + // Set nulls based on deleteInfo. + for (auto nodeOffset : deleteInfo) { + columnChunk->getNullChunk()->setNull( + nodeOffset - startNodeOffsetInChunk, true /* isNull */); + } + } } columnChunk->finalize(); append(columnChunk.get(), nodeGroupIdx); diff --git a/src/storage/store/column_chunk.cpp b/src/storage/store/column_chunk.cpp index 20511bcc8fa..dd275eb8170 100644 --- a/src/storage/store/column_chunk.cpp +++ b/src/storage/store/column_chunk.cpp @@ -473,6 +473,29 @@ class FixedListColumnChunk : public ColumnChunk { } }; +class InternalIDColumnChunk final : public ColumnChunk { +public: + // Physically, we only materialize offset of INTERNAL_ID, which is same as INT64, + InternalIDColumnChunk(uint64_t capacity) + : ColumnChunk(LogicalType::INT64(), capacity, false /* enableCompression */) {} + + void append(ValueVector* vector) { + KU_ASSERT(vector->dataType.getPhysicalType() == PhysicalTypeID::INTERNAL_ID); + copyVectorToBuffer(vector, numValues); + numValues += vector->state->selVector->selectedSize; + } + + void copyVectorToBuffer(ValueVector* vector, offset_t startPosInChunk) { + auto relIDsInVector = (internalID_t*)vector->getData(); + for (auto i = 0u; i < vector->state->selVector->selectedSize; i++) { + auto pos = vector->state->selVector->selectedPositions[i]; + nullChunk->setNull(startPosInChunk + i, vector->isNull(pos)); + memcpy(buffer.get() + (startPosInChunk + i) * numBytesPerValue, + &relIDsInVector[pos].offset, numBytesPerValue); + } + } +}; + std::unique_ptr ColumnChunkFactory::createColumnChunk( std::unique_ptr dataType, bool enableCompression, uint64_t capacity) { switch (dataType->getPhysicalType()) { @@ -500,8 +523,7 @@ std::unique_ptr ColumnChunkFactory::createColumnChunk( } // Physically, we only materialize offset of INTERNAL_ID, which is same as INT64, case PhysicalTypeID::INTERNAL_ID: { - return std::make_unique( - LogicalType::INT64(), capacity, false /* enableCompression */); + return std::make_unique(capacity); } case PhysicalTypeID::FIXED_LIST: { return std::make_unique( diff --git a/src/storage/store/rel_table.cpp b/src/storage/store/rel_table.cpp index 89b5bd1501c..15953d4196a 100644 --- a/src/storage/store/rel_table.cpp +++ b/src/storage/store/rel_table.cpp @@ -30,6 +30,14 @@ void RelTable::read(Transaction* transaction, TableReadState& readState, } } +void RelTable::insert(Transaction* transaction, ValueVector* srcNodeIDVector, + ValueVector* dstNodeIDVector, const std::vector& propertyVectors) { + fwdRelTableData->insert(transaction, srcNodeIDVector, dstNodeIDVector, propertyVectors); + bwdRelTableData->insert(transaction, dstNodeIDVector, srcNodeIDVector, propertyVectors); + auto relsStats = ku_dynamic_cast(tablesStatistics); + relsStats->updateNumRelsByValue(tableID, 1); +} + void RelTable::update(transaction::Transaction* transaction, column_id_t columnID, ValueVector* srcNodeIDVector, ValueVector* dstNodeIDVector, ValueVector* relIDVector, ValueVector* propertyVector) { @@ -37,6 +45,19 @@ void RelTable::update(transaction::Transaction* transaction, column_id_t columnI bwdRelTableData->update(transaction, columnID, dstNodeIDVector, relIDVector, propertyVector); } +void RelTable::delete_(Transaction* transaction, ValueVector* srcNodeIDVector, + ValueVector* dstNodeIDVector, ValueVector* relIDVector) { + auto fwdDeleted = + fwdRelTableData->delete_(transaction, srcNodeIDVector, dstNodeIDVector, relIDVector); + auto bwdDeleted = + bwdRelTableData->delete_(transaction, dstNodeIDVector, srcNodeIDVector, relIDVector); + KU_ASSERT(fwdDeleted == bwdDeleted); + if (fwdDeleted && bwdDeleted) { + auto relsStats = ku_dynamic_cast(tablesStatistics); + relsStats->updateNumRelsByValue(tableID, -1); + } +} + void RelTable::scan(Transaction* transaction, RelDataReadState& scanState, ValueVector* inNodeIDVector, const std::vector& outputVectors) { auto tableData = getDirectedTableData(scanState.direction); diff --git a/src/storage/store/rel_table_data.cpp b/src/storage/store/rel_table_data.cpp index bb7a1b3421f..32e4f04c00a 100644 --- a/src/storage/store/rel_table_data.cpp +++ b/src/storage/store/rel_table_data.cpp @@ -159,6 +159,14 @@ void RelTableData::lookup(Transaction* transaction, TableReadState& readState, } } +void RelTableData::insert(transaction::Transaction* transaction, ValueVector* srcNodeIDVector, + ValueVector* dstNodeIDVector, const std::vector& propertyVectors) { + auto localTableData = ku_dynamic_cast( + transaction->getLocalStorage()->getOrCreateLocalTableData( + tableID, columns, TableType::REL, dataFormat, getDataIdxFromDirection(direction))); + localTableData->insert(srcNodeIDVector, dstNodeIDVector, propertyVectors); +} + void RelTableData::update(transaction::Transaction* transaction, column_id_t columnID, ValueVector* srcNodeIDVector, ValueVector* relIDVector, ValueVector* propertyVector) { KU_ASSERT(columnID < columns.size() && columnID != REL_ID_COLUMN_ID); @@ -168,6 +176,14 @@ void RelTableData::update(transaction::Transaction* transaction, column_id_t col localTableData->update(srcNodeIDVector, relIDVector, columnID, propertyVector); } +bool RelTableData::delete_(transaction::Transaction* transaction, ValueVector* srcNodeIDVector, + ValueVector* dstNodeIDVector, ValueVector* relIDVector) { + auto localTableData = ku_dynamic_cast( + transaction->getLocalStorage()->getOrCreateLocalTableData( + tableID, columns, TableType::REL, dataFormat, getDataIdxFromDirection(direction))); + return localTableData->delete_(srcNodeIDVector, dstNodeIDVector, relIDVector); +} + void RelTableData::append(NodeGroup* nodeGroup) { if (dataFormat == ColumnDataFormat::CSR) { auto csrNodeGroup = static_cast(nodeGroup); @@ -191,14 +207,14 @@ void RelTableData::prepareLocalTableToCommit( } void RelTableData::prepareCommitForRegularColumns( - transaction::Transaction* transaction, kuzu::storage::LocalRelTableData* localTableData) { + Transaction* transaction, LocalRelTableData* localTableData) { for (auto& [nodeGroupIdx, nodeGroup] : localTableData->nodeGroups) { auto relNG = ku_dynamic_cast(nodeGroup.get()); KU_ASSERT(relNG); auto relNodeGroupInfo = ku_dynamic_cast(relNG->getRelNGInfo()); adjColumn->prepareCommitForChunk(transaction, nodeGroupIdx, relNG->getAdjChunk(), - relNodeGroupInfo->adjInsertInfo, {}, relNodeGroupInfo->deleteInfo); + relNodeGroupInfo->adjInsertInfo, {} /* updateInfo */, relNodeGroupInfo->deleteInfo); for (auto columnID = 0u; columnID < columns.size(); columnID++) { columns[columnID]->prepareCommitForChunk(transaction, nodeGroupIdx, relNG->getPropertyChunk(columnID), relNodeGroupInfo->insertInfoPerChunk[columnID], @@ -208,7 +224,7 @@ void RelTableData::prepareCommitForRegularColumns( } void RelTableData::prepareCommitForCSRColumns( - transaction::Transaction* transaction, kuzu::storage::LocalRelTableData* localTableData) { + Transaction* transaction, LocalRelTableData* localTableData) { for (auto& [nodeGroupIdx, nodeGroup] : localTableData->nodeGroups) { auto relNG = ku_dynamic_cast(nodeGroup.get()); KU_ASSERT(relNG); @@ -239,7 +255,8 @@ void RelTableData::prepareCommitForCSRColumns( } else { // We need to update the csr offset column. Thus, we cannot simply fall back to directly // update the adj column and property columns based on csr offsets. - KU_UNREACHABLE; + prepareCommitCSRNGWithSliding(transaction, nodeGroupIdx, relNodeGroupInfo, + csrOffsetChunk.get(), relIDChunk.get(), relNG); } } } @@ -291,6 +308,160 @@ void RelTableData::prepareCommitCSRNGWithoutSliding(Transaction* transaction, } } +void RelTableData::prepareCommitCSRNGWithSliding(Transaction* transaction, + node_group_idx_t nodeGroupIdx, CSRRelNGInfo* relNodeGroupInfo, ColumnChunk* csrOffsetChunk, + ColumnChunk* relIDChunk, LocalRelNG* localNodeGroup) { + // We need to update the csr offset column. Thus, we cannot simply fall back to directly update + // the adj column and property columns based on csr offsets. Instead, we need to for loop each + // node in the node group, slide accordingly, and update the csr offset column, adj column and + // property columns. + auto nodeGroupStartOffset = StorageUtils::getStartOffsetOfNodeGroup(nodeGroupIdx); + // Slide column by column. + // First we slide the csr offset column chunk, and keep the slided csr offset column chunk in + // memory, so it can be used for assertion checking later. + auto slidedCSROffsetChunk = + slideCSROffsetColumnChunk(csrOffsetChunk, relNodeGroupInfo, nodeGroupStartOffset); + csrOffsetColumn->append(slidedCSROffsetChunk.get(), nodeGroupIdx); + // Then we slide the adj column chunk, rel id column chunk, and all property column chunks. + auto slidedAdjColumnChunk = + slideCSRColumnChunk(transaction, csrOffsetChunk, slidedCSROffsetChunk.get(), relIDChunk, + relNodeGroupInfo->adjInsertInfo, {} /* updateInfo */, relNodeGroupInfo->deleteInfo, + nodeGroupStartOffset, adjColumn.get(), localNodeGroup->getAdjChunk()); + adjColumn->append(slidedAdjColumnChunk.get(), nodeGroupIdx); + slidedAdjColumnChunk.reset(); + for (auto columnID = 0u; columnID < columns.size(); columnID++) { + auto slidedColumnChunk = slideCSRColumnChunk(transaction, csrOffsetChunk, + slidedCSROffsetChunk.get(), relIDChunk, relNodeGroupInfo->insertInfoPerChunk[columnID], + relNodeGroupInfo->updateInfoPerChunk[columnID], relNodeGroupInfo->deleteInfo, + nodeGroupStartOffset, columns[columnID].get(), + localNodeGroup->getLocalColumnChunk(columnID)); + columns[columnID]->append(slidedColumnChunk.get(), nodeGroupIdx); + slidedColumnChunk.reset(); + } +} + +std::unique_ptr RelTableData::slideCSROffsetColumnChunk( + ColumnChunk* csrOffsetChunk, CSRRelNGInfo* relNodeGroupInfo, offset_t nodeGroupStartOffset) { + auto csrOffsets = (offset_t*)csrOffsetChunk->getData(); + auto slidedCSRChunk = + ColumnChunkFactory::createColumnChunk(LogicalType::INT64(), enableCompression); + int64_t currentCSROffset = 0; + auto currentNumSrcNodesInNG = csrOffsetChunk->getNumValues(); + auto newNumSrcNodesInNG = currentNumSrcNodesInNG; + for (auto i = 0; i < currentNumSrcNodesInNG; i++) { + auto nodeOffset = nodeGroupStartOffset + i; + int64_t numRowsInCSR = i == 0 ? csrOffsets[i] : csrOffsets[i] - csrOffsets[i - 1]; + KU_ASSERT(numRowsInCSR >= 0); + int64_t numDeletions = relNodeGroupInfo->deleteInfo.contains(nodeOffset) ? + relNodeGroupInfo->deleteInfo[nodeOffset].size() : + 0; + int64_t numInsertions = relNodeGroupInfo->adjInsertInfo.contains(nodeOffset) ? + relNodeGroupInfo->adjInsertInfo[nodeOffset].size() : + 0; + int64_t numRowsAfterSlide = numRowsInCSR + numInsertions - numDeletions; + KU_ASSERT(numRowsAfterSlide >= 0); + currentCSROffset += numRowsAfterSlide; + slidedCSRChunk->setValue(currentCSROffset, i); + } + for (auto i = currentNumSrcNodesInNG; i < StorageConstants::NODE_GROUP_SIZE; i++) { + auto nodeOffset = nodeGroupStartOffset + i; + // Assert that should only have insertions for these nodes. + KU_ASSERT(!relNodeGroupInfo->deleteInfo.contains(nodeOffset)); + for (auto columnID = 0u; columnID < columns.size(); columnID++) { + KU_ASSERT(!relNodeGroupInfo->updateInfoPerChunk[columnID].contains(nodeOffset)); + } + auto numRowsInCSR = 0; + if (relNodeGroupInfo->adjInsertInfo.contains(nodeOffset)) { + // This node is inserted now. Update csr offset accordingly. + numRowsInCSR += relNodeGroupInfo->adjInsertInfo.at(nodeOffset).size(); + newNumSrcNodesInNG = i + 1; + } + currentCSROffset += numRowsInCSR; + slidedCSRChunk->setValue(currentCSROffset, i); + } + slidedCSRChunk->setNumValues(newNumSrcNodesInNG); + return slidedCSRChunk; +} + +std::unique_ptr RelTableData::slideCSRColumnChunk(Transaction* transaction, + ColumnChunk* csrOffsetChunk, ColumnChunk* slidedCSROffsetChunkForCheck, ColumnChunk* relIDChunk, + const offset_to_offset_to_row_idx_t& insertInfo, + const offset_to_offset_to_row_idx_t& updateInfo, const offset_to_offset_set_t& deleteInfo, + node_group_idx_t nodeGroupIdx, Column* column, LocalVectorCollection* localChunk) { + auto oldCapacity = csrOffsetChunk->getNumValues() == 0 ? + 0 : + csrOffsetChunk->getValue(csrOffsetChunk->getNumValues() - 1); + auto newCapacity = slidedCSROffsetChunkForCheck->getNumValues() == 0 ? + 0 : + slidedCSROffsetChunkForCheck->getValue( + slidedCSROffsetChunkForCheck->getNumValues() - 1); + // TODO: No need to allocate the new column chunk if this is relID. + auto columnChunk = ColumnChunkFactory::createColumnChunk( + column->getDataType()->copy(), enableCompression, oldCapacity); + column->scan(transaction, nodeGroupIdx, columnChunk.get()); + auto newColumnChunk = ColumnChunkFactory::createColumnChunk( + column->getDataType()->copy(), enableCompression, newCapacity); + auto currentNumSrcNodesInNG = csrOffsetChunk->getNumValues(); + auto csrOffsets = (offset_t*)csrOffsetChunk->getData(); + auto relIDs = (offset_t*)relIDChunk->getData(); + auto nodeGroupStartOffset = StorageUtils::getStartOffsetOfNodeGroup(nodeGroupIdx); + for (auto i = 0; i < currentNumSrcNodesInNG; i++) { + auto nodeOffset = nodeGroupStartOffset + i; + auto [startCSROffset, endCSROffset] = + getCSRStartAndEndOffset(nodeGroupStartOffset, csrOffsets, nodeOffset); + auto hasDeletions = deleteInfo.contains(nodeOffset); + auto hasUpdates = updateInfo.contains(nodeOffset); + auto hasInsertions = insertInfo.contains(nodeOffset); + if (!hasDeletions && !hasUpdates && !hasInsertions) { + // Append the whole csr. + newColumnChunk->append( + columnChunk.get(), startCSROffset, endCSROffset - startCSROffset); + continue; + } + for (auto csrOffset = startCSROffset; csrOffset < endCSROffset; csrOffset++) { + auto relID = relIDs[csrOffset]; + if (hasDeletions && deleteInfo.at(nodeOffset).contains(relID)) { + // This rel is deleted now. Skip. + } else if (hasUpdates && updateInfo.at(nodeOffset).contains(relID)) { + // This rel is inserted or updated. Append from local data to the column chunk. + auto rowIdx = insertInfo.at(nodeOffset).at(relID); + auto localVector = localChunk->getLocalVector(rowIdx)->getVector(); + auto offsetInVector = rowIdx & (DEFAULT_VECTOR_CAPACITY - 1); + localVector->state->selVector->selectedPositions[0] = offsetInVector; + newColumnChunk->append(localVector); + } else { + // This rel is not updated. Append to the column chunk. + newColumnChunk->append(columnChunk.get(), csrOffset, 1 /* numValuesToAppend */); + } + } + if (hasInsertions) { + // Append the newly inserted rels. + for (auto [_, rowIdx] : insertInfo.at(nodeOffset)) { + auto localVector = localChunk->getLocalVector(rowIdx)->getVector(); + auto offsetInVector = rowIdx & (DEFAULT_VECTOR_CAPACITY - 1); + localVector->state->selVector->selectedPositions[0] = offsetInVector; + newColumnChunk->append(localVector); + } + } + } + if (!insertInfo.empty()) { + // Append the newly inserted rels. + for (auto i = currentNumSrcNodesInNG; i < StorageConstants::NODE_GROUP_SIZE; i++) { + auto nodeOffset = nodeGroupStartOffset + i; + if (insertInfo.contains(nodeOffset)) { + for (auto [relID, rowIdx] : insertInfo.at(nodeOffset)) { + auto localVector = localChunk->getLocalVector(rowIdx)->getVector(); + auto offsetInVector = rowIdx & (DEFAULT_VECTOR_CAPACITY - 1); + localVector->state->selVector->selectedPositions[0] = offsetInVector; + newColumnChunk->append(localVector); + } + } + } + } + KU_ASSERT(newColumnChunk->getNumValues() == newCapacity); + return newColumnChunk; +} + void RelTableData::checkpointInMemory() { if (csrOffsetColumn) { csrOffsetColumn->checkpointInMemory(); diff --git a/test/test_files/copy/copy_large_list.test b/test/test_files/copy/copy_large_list.test index fa639b56863..4e62a831501 100644 --- a/test/test_files/copy/copy_large_list.test +++ b/test/test_files/copy/copy_large_list.test @@ -45,7 +45,6 @@ 0 -CASE AddPropertyWithLargeListTest --SKIP -STATEMENT alter table knows add length INT64 DEFAULT 50 ---- ok -STATEMENT match (:person)-[e:knows]->(:person) return e.length diff --git a/test/test_files/demo_db/demo_db_create.test b/test/test_files/demo_db/demo_db_create.test index 4f99d047b37..c545029a5cf 100644 --- a/test/test_files/demo_db/demo_db_create.test +++ b/test/test_files/demo_db/demo_db_create.test @@ -31,7 +31,6 @@ Alice|35 Dimitri| -CASE CreateRelTest1 --SKIP -STATEMENT CREATE (u:User {name: 'Alice'}) ---- ok -STATEMENT MATCH (a:User) WHERE a.name = 'Adam' WITH a MATCH (b:User) WHERE b.name = 'Alice' WITH a, b CREATE (a)-[e:Follows {since:1990}]->(b) @@ -44,7 +43,6 @@ Karissa Zhang -CASE CreateRelTest2 --SKIP -STATEMENT MATCH (a:User), (b:User) WHERE a.name='Zhang' AND b.name='Karissa' CREATE (a)-[:Follows {since:2022}]->(b) ---- ok -CHECK_ORDER @@ -54,7 +52,6 @@ Karissa Noura -CASE CreateAvgNullTest --SKIP -STATEMENT MATCH (a:User) WHERE a.name = 'Adam' CREATE (a)-[:Follows]->(b:User {name:'Alice'}) ---- ok -CHECK_ORDER @@ -67,7 +64,6 @@ Noura {_ID: 0:3, _LABEL: User, name: Noura, age: 25}|25.000000|25|1|1 -CASE MergeComplexPattern --SKIP -STATEMENT MERGE (a:User {name:'A'})-[e:Follows]->(b:User {name:'B'})-[:LivesIn]->(:City {name:'Toronto'}); ---- ok -STATEMENT MATCH (a:User)-[:Follows]->(b:User)-[:LivesIn]->(c:City) RETURN a.name, b.name, c.name; diff --git a/test/test_files/demo_db/demo_db_delete.test b/test/test_files/demo_db/demo_db_delete.test index a625f4d5c14..6de2ea709d6 100644 --- a/test/test_files/demo_db/demo_db_delete.test +++ b/test/test_files/demo_db/demo_db_delete.test @@ -16,7 +16,6 @@ 4 -CASE DeleteRelTest --SKIP -STATEMENT MATCH (u:User)-[f:Follows]->(u1:User) WHERE u.name = 'Adam' AND u1.name = 'Karissa' DELETE f ---- ok -STATEMENT MATCH (u:User)-[f:Follows]->(u1:User) WHERE u.name='Adam' RETURN u1.name diff --git a/test/test_files/issue/issue.test b/test/test_files/issue/issue.test index 08e28da2e0a..7c2207c301d 100644 --- a/test/test_files/issue/issue.test +++ b/test/test_files/issue/issue.test @@ -4,7 +4,6 @@ -- -CASE 2158 --SKIP -STATEMENT CREATE NODE TABLE N1(name STRING, PRIMARY KEY(name)); ---- ok -STATEMENT CREATE NODE TABLE N2(name STRING, PRIMARY KEY(name)); @@ -30,7 +29,6 @@ {_ID: 0:0, _LABEL: Test, id: 0, content: mycontent} -CASE Kind-Of-Fruit --SKIP -STATEMENT CREATE NODE TABLE T(name STRING, PRIMARY KEY(name)); ---- ok -STATEMENT CREATE NODE TABLE Fruit(name STRING, PRIMARY KEY(name)); diff --git a/test/test_files/tck/match/match1.test b/test/test_files/tck/match/match1.test index 49b87bfee11..d1c3b85f9be 100644 --- a/test/test_files/tck/match/match1.test +++ b/test/test_files/tck/match/match1.test @@ -1,4 +1,4 @@ --GROUP TCK +-GROUP TCKMatch1 -DATASET CSV tck -- diff --git a/test/test_files/tck/match/match2.test b/test/test_files/tck/match/match2.test index cc77164c5c8..e8eb7d79f33 100644 --- a/test/test_files/tck/match/match2.test +++ b/test/test_files/tck/match/match2.test @@ -1,4 +1,4 @@ --GROUP TCK +-GROUP TCKMatch2 -DATASET CSV tck -- @@ -12,7 +12,6 @@ Binder exception: No rel table exists in database. # Matching a relationship pattern using a label predicate on both sides -CASE Scenario2 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE B(ID SERIAL, PRIMARY KEY(ID)); @@ -36,7 +35,6 @@ Binder exception: No rel table exists in database. # Matching a self-loop with an undirected relationship pattern -CASE Scenario3&4 --SKIP -STATEMENT CREATE NODE TABLE A(name STRING, PRIMARY KEY(name)); ---- ok -STATEMENT CREATE REL TABLE T(FROM A TO A); @@ -55,7 +53,6 @@ Binder exception: No rel table exists in database. # Match relationship with inline property value -CASE Scenario5 --SKIP -STATEMENT CREATE NODE TABLE A(ID INT64, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE KNOWS(FROM A TO A, name STRING); @@ -69,7 +66,6 @@ Binder exception: No rel table exists in database. # Match relationships with multiple types -CASE Scenario6 --SKIP -STATEMENT CREATE NODE TABLE A(name STRING, PRIMARY KEY(name)); ---- ok -STATEMENT CREATE REL TABLE KNOWS(FROM A TO A, name STRING); @@ -99,7 +95,6 @@ Binder exception: No rel table exists in database. # Matching twice with conflicting relationship types on same relationship -CASE Scenario7 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE T(FROM A TO A); diff --git a/test/test_files/tck/match/match3.test b/test/test_files/tck/match/match3.test index 2fa8ac00979..acb75e138e6 100644 --- a/test/test_files/tck/match/match3.test +++ b/test/test_files/tck/match/match3.test @@ -1,11 +1,10 @@ --GROUP TCK +-GROUP TCKMatch3 -DATASET CSV tck -- # Get neighbours -CASE Scenario1 --SKIP -STATEMENT CREATE NODE TABLE A(num INT64, PRIMARY KEY(num)); ---- ok -STATEMENT CREATE NODE TABLE B(num INT64, PRIMARY KEY(num)); @@ -20,7 +19,6 @@ # Directed match of a simple relationship -CASE Scenario2 --SKIP -LOG Scenario2 -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok @@ -36,7 +34,6 @@ # Undirected match on simple relationship graph -CASE Scenario3 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE B(ID SERIAL, PRIMARY KEY(ID)); @@ -71,7 +68,6 @@ # Return two subgraphs with bound undirected relationship -CASE Scenario5 --SKIP -STATEMENT CREATE NODE TABLE A(num INT64, PRIMARY KEY(num)); ---- ok -STATEMENT CREATE NODE TABLE B(num INT64, PRIMARY KEY(num)); @@ -87,7 +83,6 @@ # Matching a relationship pattern using a label predicate -CASE Scenario6 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE Foo(ID SERIAL, PRIMARY KEY(ID)); @@ -95,15 +90,14 @@ -STATEMENT CREATE REL TABLE T(FROM A TO Foo); ---- ok -STATEMENT CREATE (a)-[:T]->(b1), (a)-[:T]->(b2) ----- 0 -# not implemented +---- error +Binder exception: Create node a with multiple node labels is not supported. # Matching nodes with many labels #-CASE Scenario7 # Matching using relationship predicate with multiples of the same type -CASE Scenario8 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE B(ID SERIAL, PRIMARY KEY(ID)); @@ -118,7 +112,6 @@ # Get related to related to -CASE Scenario9 --SKIP -STATEMENT CREATE NODE TABLE A(num INT64, PRIMARY KEY(num)); ---- ok -STATEMENT CREATE NODE TABLE B(num INT64, PRIMARY KEY(num)); @@ -137,7 +130,6 @@ # Matching using self-referencing pattern returns no result -CASE Scenario10 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE T(FROM A TO A); @@ -168,7 +160,6 @@ # Directed match on self-relationship graph # Directed match of self-relationship on self-relationship graph -CASE Scenario13&14 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE LOOP(FROM A TO A); @@ -216,7 +207,6 @@ # handle cyclic patterns # Handling cyclic patterns when separated into two parts -CASE Scenario17&18 --SKIP -STATEMENT CREATE NODE TABLE T1(ID SERIAL, name STRING, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE T2(ID SERIAL, name STRING, PRIMARY KEY(ID)); @@ -238,7 +228,6 @@ a # Two bound nodes pointing to the same node # -- is equiv to <--> so do not implement -CASE Scenario19 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, name STRING, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE KNOWS(FROM A TO A); @@ -255,7 +244,6 @@ a # Three bound nodes pointing to the same node -CASE Scenario20 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, name STRING, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE KNOWS(FROM A TO A); @@ -273,7 +261,6 @@ a # Three bound nodes pointing to the same node with extra connections -CASE Scenario21 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, name STRING, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE KNOWS(FROM A TO A); @@ -295,7 +282,6 @@ a # Returning bound nodes that are not part of the pattern -CASE Scenario22 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, name STRING, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE KNOWS(FROM A TO A); @@ -312,7 +298,6 @@ a # Matching disconnected patterns -CASE Scenario23 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE B(ID SERIAL, PRIMARY KEY(ID)); @@ -336,7 +321,6 @@ a # Matching twice with duplicate relationship types on same relationship -CASE Scenario24 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE B(ID SERIAL, PRIMARY KEY(ID)); @@ -361,7 +345,6 @@ Binder exception: Bind relationship r to relationship with same name is not supp # Matching twice with an additional node label -CASE Scenario25 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE T (FROM A TO A); @@ -377,7 +360,6 @@ Binder exception: Bind relationship r to relationship with same name is not supp # Matching twice with a duplicate predicate -CASE Scenario26 --SKIP -STATEMENT CREATE NODE TABLE X(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE Y(ID SERIAL, PRIMARY KEY(ID)); @@ -395,14 +377,14 @@ Binder exception: Bind relationship r to relationship with same name is not supp # Matching from null nodes should return no results owing to finding no matches -CASE Scenario27 --SKIP -STATEMENT CREATE NODE TABLE X(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT OPTIONAL MATCH (a) WITH a MATCH (a)-->(b) RETURN b ----- 0 +---- error +Binder exception: No rel table exists in database. # Matching from null nodes should return no results owing to matches being filtered out #-CASE Scenario28 diff --git a/test/test_files/tck/match/match4.test b/test/test_files/tck/match/match4.test index 131123ddc9f..08b589db668 100644 --- a/test/test_files/tck/match/match4.test +++ b/test/test_files/tck/match/match4.test @@ -1,8 +1,9 @@ --GROUP TCK +-GROUP TCKMatch4 -DATASET CSV tck -- +# TODO: Should add filter for the query, otherwise could lead to multiple possible results. # Handling fixed-length variable length pattern -CASE Scenario1 -SKIP @@ -19,7 +20,6 @@ # Simple variable length pattern -CASE Scenario2 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, name STRING, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE CONTAIN(FROM A TO A); @@ -39,7 +39,6 @@ # Zero-length variable length pattern in the middle of the pattern -CASE Scenario3 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, name STRING, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE CONTAIN(FROM A TO A); @@ -59,6 +58,7 @@ {_ID: 0:0, _LABEL: A, ID: 0, name: A}|{_ID: 0:1, _LABEL: A, ID: 1, name: B}|{_ID: 0:1, _LABEL: A, ID: 1, name: B} {_ID: 0:0, _LABEL: A, ID: 0, name: A}|{_ID: 0:1, _LABEL: A, ID: 1, name: B}|{_ID: 0:2, _LABEL: A, ID: 2, name: C} +# TODO: Catalog exception: LEN function does not exist. # Matching longer variable length paths -CASE Scenario4 -SKIP @@ -78,12 +78,11 @@ ---- ok -STATEMENT MATCH (n {var: 'start'})-[:T*]->(m {var: 'end'}) RETURN m ----- 1 -{_ID: 0:1, _LABEL: A, ID: 1, var: end} +---- error +Binder exception: Expression start has data type STRING but expected INT64. Implicit cast is not supported. # Matching variable length pattern with property predicate -CASE Scenario5 --SKIP -STATEMENT CREATE NODE TABLE Artist(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE WORKED_WITH(FROM Artist TO Artist, year INT64); @@ -101,6 +100,7 @@ ---- 1 {_ID: 0:1, _LABEL: Artist, ID: 1}|{_ID: 0:2, _LABEL: Artist, ID: 2} +# TODO: Should add filter for the query, otherwise could lead to multiple possible results. # Matching variable length patterns from a bound node -CASE Scenario6 -SKIP @@ -122,7 +122,6 @@ # Matching variable length patterns including a bound relationship -CASE Scenario7 --SKIP -STATEMENT CREATE NODE TABLE Node1(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE REL TABLE EDGE(FROM Node1 TO Node1); @@ -138,12 +137,11 @@ -STATEMENT MATCH ()-[r:EDGE]-() MATCH p = (n)-[*0..1]-()-[r:EDGE]-()-[*0..1]-(m) RETURN count(p) AS c ----- 1 -32 +---- error +Binder exception: Bind relationship r to relationship with same name is not supported. # Matching relationships into a list and matching variable length using the list -CASE Scenario8 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE B(ID SERIAL, PRIMARY KEY(ID)); @@ -155,19 +153,19 @@ -STATEMENT CREATE (a:A), (b:B), (c:C) CREATE (a)-[:Y]->(b), (b)-[:Y]->(c) ----- ok +---- error +Binder exception: Create rel with multiple rel labels or bound by multiple node labels is not supported. -STATEMENT MATCH ()-[r1]->()-[r2]->() WITH [r1, r2] AS rs LIMIT 1 MATCH (first)-[rs*]->(second) RETURN first, second; ----- 1 -{_ID: 0:0, _LABEL: A, ID: 0}|{_ID: 2:0, _LABEL: C, ID: 0} +---- error +Binder exception: rs has data type VAR_LIST but (RECURSIVE_REL) was expected. # Fail when asterisk operator is missing # Fail on negative bound -CASE Scenario9&10 --SKIP -STATEMENT CREATE NODE TABLE A(ID SERIAL, name STRING, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE B(ID SERIAL, name STRING, PRIMARY KEY(ID)); diff --git a/test/test_files/tinysnb/function/range.test b/test/test_files/tinysnb/function/range.test index 536c25e4559..48c45a21d70 100644 --- a/test/test_files/tinysnb/function/range.test +++ b/test/test_files/tinysnb/function/range.test @@ -131,7 +131,6 @@ Binder exception: Cannot match a built-in function for given function RANGE(STRI -STATEMENT RETURN range(3, 4, 0); ---- error Runtime exception: Step of range cannot be 0. --SKIP -STATEMENT RETURN range(0, -1, 9223372036854775807); ---- 1 -[] \ No newline at end of file +[] diff --git a/test/test_files/tinysnb/var_length_extend/range_literal.test b/test/test_files/tinysnb/var_length_extend/range_literal.test index 26b18872beb..a626c9c9c5a 100644 --- a/test/test_files/tinysnb/var_length_extend/range_literal.test +++ b/test/test_files/tinysnb/var_length_extend/range_literal.test @@ -44,7 +44,6 @@ Carol 484 -CASE BothBound --SKIP -STATEMENT MATCH(a:person {fName: "Alice"})-[e:meets*1..1]->(b:person) RETURN b.fName; ---- 1 Bob @@ -67,7 +66,6 @@ Mike Mike -CASE SingleAsterisk --SKIP -STATEMENT MATCH (c:person) WHERE c.fName="Dan" CREATE(c)-[:meets]->(b:person {ID: 11, fName: "Mike"}); ---- ok -STATEMENT MATCH(a:person {fName: "Alice"})-[e:meets*]->(b:person) RETURN b.fName; @@ -81,7 +79,6 @@ Alice Hubert Blaine Wolfeschlegelsteinhausenbergerdorff -CASE NoBound --SKIP -STATEMENT MATCH (c:person) WHERE c.fName="Dan" CREATE(c)-[:meets]->(b:person {ID: 11, fName: "Mike"}); ---- ok -STATEMENT MATCH(a:person {fName: "Alice"})-[e:meets*..]->(b:person) RETURN b.fName; diff --git a/test/test_files/transaction/create_rel/insert_rels_to_different_nodes.test b/test/test_files/transaction/create_rel/insert_rels_to_different_nodes.test index 0d8b60f909b..e175c1aa313 100644 --- a/test/test_files/transaction/create_rel/insert_rels_to_different_nodes.test +++ b/test/test_files/transaction/create_rel/insert_rels_to_different_nodes.test @@ -1,6 +1,5 @@ -GROUP CreateRelTest -DATASET CSV rel-update-tests --SKIP -- -DEFINE_STATEMENT_BLOCK INSERT_RELS_TO_DIFFERENT_NODES [ diff --git a/test/test_files/transaction/create_rel/insert_rels_to_large_list.test b/test/test_files/transaction/create_rel/insert_rels_to_large_list.test index 4aaaa9f36c3..49faf54f50c 100644 --- a/test/test_files/transaction/create_rel/insert_rels_to_large_list.test +++ b/test/test_files/transaction/create_rel/insert_rels_to_large_list.test @@ -1,6 +1,5 @@ -GROUP CreateRelTest -DATASET CSV rel-update-tests --SKIP -- -DEFINE_STATEMENT_BLOCK INSERT_RELS_TO_LARGE_LIST [ diff --git a/test/test_files/transaction/create_rel/insert_rels_to_many_to_one_rel_table.test b/test/test_files/transaction/create_rel/insert_rels_to_many_to_one_rel_table.test index 109dde28672..aae9b064402 100644 --- a/test/test_files/transaction/create_rel/insert_rels_to_many_to_one_rel_table.test +++ b/test/test_files/transaction/create_rel/insert_rels_to_many_to_one_rel_table.test @@ -1,6 +1,5 @@ -GROUP CreateRelTest -DATASET CSV rel-update-tests --SKIP -- -DEFINE_STATEMENT_BLOCK INSERT_RELS_TO_MANY_TO_ONE_REL_TABLE [ diff --git a/test/test_files/transaction/create_rel/insert_rels_to_newly_added_node.test b/test/test_files/transaction/create_rel/insert_rels_to_newly_added_node.test index 6fccfd50e80..f85fc6d8b23 100644 --- a/test/test_files/transaction/create_rel/insert_rels_to_newly_added_node.test +++ b/test/test_files/transaction/create_rel/insert_rels_to_newly_added_node.test @@ -1,6 +1,5 @@ -GROUP CreateRelTest -DATASET CSV rel-update-tests --SKIP -- -DEFINE_STATEMENT_BLOCK INSERT_RELS_TO_DIFFERENT_NODES [ diff --git a/test/test_files/transaction/create_rel/insert_rels_to_one_to_one_rel_table.test b/test/test_files/transaction/create_rel/insert_rels_to_one_to_one_rel_table.test index 6a81858b4c8..b83a9104de5 100644 --- a/test/test_files/transaction/create_rel/insert_rels_to_one_to_one_rel_table.test +++ b/test/test_files/transaction/create_rel/insert_rels_to_one_to_one_rel_table.test @@ -1,6 +1,5 @@ -GROUP CreateRelTest -DATASET CSV rel-update-tests --SKIP -- -DEFINE_STATEMENT_BLOCK INSERT_RELS_TO_ONE_TO_ONE_REL_TABLE [ diff --git a/test/test_files/transaction/create_rel/insert_rels_to_small_list.test b/test/test_files/transaction/create_rel/insert_rels_to_small_list.test index 22c09c4baad..d3b357d6737 100644 --- a/test/test_files/transaction/create_rel/insert_rels_to_small_list.test +++ b/test/test_files/transaction/create_rel/insert_rels_to_small_list.test @@ -1,6 +1,5 @@ -GROUP CreateRelTest -DATASET CSV rel-update-tests --SKIP -- -DEFINE_STATEMENT_BLOCK INSERT_RELS_TO_SMALL_LIST [ diff --git a/test/test_files/transaction/create_rel/small_list_becomes_large_list_after_insertion.test b/test/test_files/transaction/create_rel/small_list_becomes_large_list_after_insertion.test index 3438e89a52f..43a47a97d03 100644 --- a/test/test_files/transaction/create_rel/small_list_becomes_large_list_after_insertion.test +++ b/test/test_files/transaction/create_rel/small_list_becomes_large_list_after_insertion.test @@ -1,6 +1,5 @@ -GROUP CreateRelTest -DATASET CSV rel-update-tests --SKIP -- -CASE smallListBecomesLargeListAfterInsertionCommitNormalExecution diff --git a/test/test_files/transaction/delete_rel/delete_all_inserted_rels.test b/test/test_files/transaction/delete_rel/delete_all_inserted_rels.test index 49bb377d638..c4037f93489 100644 --- a/test/test_files/transaction/delete_rel/delete_all_inserted_rels.test +++ b/test/test_files/transaction/delete_rel/delete_all_inserted_rels.test @@ -3,6 +3,7 @@ -SKIP -- +# This test should be added back once support read under write transaction. -DEFINE_STATEMENT_BLOCK DELETE_REL_TEST_DELETE_ALL_INSERTED_RELS [ -STATEMENT MATCH (p1:person), (p2:person) WHERE p1.ID = 1 AND p2.ID = 51 create (p1)-[:knows {length: 51}]->(p2); ---- ok diff --git a/test/test_files/transaction/delete_rel/delete_all_rels_from_large_list.test b/test/test_files/transaction/delete_rel/delete_all_rels_from_large_list.test index eab98a288fb..3c7ccb1c54a 100644 --- a/test/test_files/transaction/delete_rel/delete_all_rels_from_large_list.test +++ b/test/test_files/transaction/delete_rel/delete_all_rels_from_large_list.test @@ -1,6 +1,5 @@ -GROUP DeleteRelTest -DATASET CSV rel-update-tests --SKIP -- -CASE deleteAllRelsFromLargeListCommitNormalExecution diff --git a/test/test_files/transaction/delete_rel/delete_all_rels_from_small_list.test b/test/test_files/transaction/delete_rel/delete_all_rels_from_small_list.test index 70baedde8f4..258bd35d14b 100644 --- a/test/test_files/transaction/delete_rel/delete_all_rels_from_small_list.test +++ b/test/test_files/transaction/delete_rel/delete_all_rels_from_small_list.test @@ -1,6 +1,5 @@ -GROUP DeleteRelTest -DATASET CSV rel-update-tests --SKIP -- -CASE deleteAllRelsFromSmallListCommitNormalExecution diff --git a/test/test_files/transaction/delete_rel/delete_large_num_rels_from_large_list.test b/test/test_files/transaction/delete_rel/delete_large_num_rels_from_large_list.test index bbaea0da101..d9aa9c11af0 100644 --- a/test/test_files/transaction/delete_rel/delete_large_num_rels_from_large_list.test +++ b/test/test_files/transaction/delete_rel/delete_large_num_rels_from_large_list.test @@ -1,6 +1,5 @@ -GROUP DeleteRelTest_deleteLargeNumRelsFromLargeList -DATASET CSV rel-update-tests --SKIP -- -CASE deleteLargeNumRelsFromLargeListCommitNormalExecution diff --git a/test/test_files/transaction/delete_rel/delete_multiple_rels.test b/test/test_files/transaction/delete_rel/delete_multiple_rels.test index 9de724ae21a..2ac4ca53b11 100644 --- a/test/test_files/transaction/delete_rel/delete_multiple_rels.test +++ b/test/test_files/transaction/delete_rel/delete_multiple_rels.test @@ -1,6 +1,5 @@ -GROUP DeleteRelTest -DATASET CSV rel-update-tests --SKIP -- -CASE deleteMultipleRelsCommitNormalExecution diff --git a/test/test_files/transaction/delete_rel/delete_rels_from_large_list.test b/test/test_files/transaction/delete_rel/delete_rels_from_large_list.test index e0d2b541c5c..0cfd66a9b0b 100644 --- a/test/test_files/transaction/delete_rel/delete_rels_from_large_list.test +++ b/test/test_files/transaction/delete_rel/delete_rels_from_large_list.test @@ -1,6 +1,5 @@ -GROUP DeleteRelTest -DATASET CSV rel-update-tests --SKIP -- -CASE deleteRelsFromLargeListCommitNormalExecution diff --git a/test/test_files/transaction/delete_rel/delete_rels_from_many_to_one_table.test b/test/test_files/transaction/delete_rel/delete_rels_from_many_to_one_table.test index b899d33e22c..9df38d58aca 100644 --- a/test/test_files/transaction/delete_rel/delete_rels_from_many_to_one_table.test +++ b/test/test_files/transaction/delete_rel/delete_rels_from_many_to_one_table.test @@ -1,6 +1,5 @@ -GROUP DeleteRelTest -DATASET CSV rel-update-tests --SKIP -- -CASE deleteRelsFromManyToOneTableCommitNormalExecution diff --git a/test/test_files/transaction/delete_rel/delete_rels_from_one_to_one_table.test b/test/test_files/transaction/delete_rel/delete_rels_from_one_to_one_table.test index 90eec896dfa..898266b71af 100644 --- a/test/test_files/transaction/delete_rel/delete_rels_from_one_to_one_table.test +++ b/test/test_files/transaction/delete_rel/delete_rels_from_one_to_one_table.test @@ -1,6 +1,5 @@ -GROUP DeleteRelTest -DATASET CSV rel-update-tests --SKIP -- -DEFINE_STATEMENT_BLOCK DELETE_RELS_FROM_ONE_TO_ONE_TABLE [ diff --git a/test/test_files/transaction/delete_rel/delete_rels_from_small_list.test b/test/test_files/transaction/delete_rel/delete_rels_from_small_list.test index 3fa7bd1138f..88388c439d7 100644 --- a/test/test_files/transaction/delete_rel/delete_rels_from_small_list.test +++ b/test/test_files/transaction/delete_rel/delete_rels_from_small_list.test @@ -1,6 +1,5 @@ -GROUP DeleteRelTest -DATASET CSV rel-update-tests --SKIP -- -CASE deleteRelsFromSmallListCommitNormalExecution diff --git a/test/test_files/transaction/delete_rel/delete_rels_from_update_store.test b/test/test_files/transaction/delete_rel/delete_rels_from_update_store.test index d24af0064f4..1536dcc5fe1 100644 --- a/test/test_files/transaction/delete_rel/delete_rels_from_update_store.test +++ b/test/test_files/transaction/delete_rel/delete_rels_from_update_store.test @@ -3,6 +3,7 @@ -SKIP -- +# This test should be added back once support read under write transaction. -DEFINE_STATEMENT_BLOCK DELETE_RELS_FROM_UPDATE_STORE [ -STATEMENT MATCH (p1:person), (p2:person) WHERE p1.ID = 51 AND p2.ID = 0 create (p1)-[:knows]->(p2); ---- ok diff --git a/test/test_files/transaction/delete_rel/delete_rels_two_hop.test b/test/test_files/transaction/delete_rel/delete_rels_two_hop.test index 753eb704653..3271d0b2d7a 100644 --- a/test/test_files/transaction/delete_rel/delete_rels_two_hop.test +++ b/test/test_files/transaction/delete_rel/delete_rels_two_hop.test @@ -1,6 +1,5 @@ -GROUP DeleteRelTest -DATASET CSV rel-update-tests --SKIP -- -CASE DeleteRelsTwoHopCommitNormalExecution diff --git a/test/test_files/transaction/delete_rel/mixed_delete_and_create_rels.test b/test/test_files/transaction/delete_rel/mixed_delete_and_create_rels.test index 301e6385c7d..f69fd26ffe5 100644 --- a/test/test_files/transaction/delete_rel/mixed_delete_and_create_rels.test +++ b/test/test_files/transaction/delete_rel/mixed_delete_and_create_rels.test @@ -3,6 +3,7 @@ -SKIP -- +# This test should be added back once support read under write transaction. -CASE MixedDeleteAndCreateRelsCommitNormalExecution -STATEMENT BEGIN TRANSACTION ---- ok diff --git a/test/test_files/transaction/update_rel/update_one_to_one_rel_table.test b/test/test_files/transaction/update_rel/update_one_to_one_rel_table.test index 65ba9f4f223..1220f2fa9a2 100644 --- a/test/test_files/transaction/update_rel/update_one_to_one_rel_table.test +++ b/test/test_files/transaction/update_rel/update_one_to_one_rel_table.test @@ -1,6 +1,5 @@ -GROUP UpdateRelTest -DATASET CSV rel-update-tests --SKIP -- -DEFINE_STATEMENT_BLOCK UPDATE_ONE_TO_ONE_REL_TABLE [ diff --git a/test/test_files/update_node/create_tinysnb.test b/test/test_files/update_node/create_tinysnb.test index fdae44d5937..a2b7fd4ca7c 100644 --- a/test/test_files/update_node/create_tinysnb.test +++ b/test/test_files/update_node/create_tinysnb.test @@ -68,7 +68,6 @@ 9|Greg|40 -CASE InsertSingleNToNRelTest --SKIP -STATEMENT MATCH (a:person), (b:person) WHERE a.ID = 9 AND b.ID = 10 CREATE (a)-[:knows {meetTime:timestamp('1976-12-23 11:21:42'), validInterval:interval('2 years'), comments:['A', 'k'], date:date('1997-03-22')}]->(b) ---- ok -STATEMENT MATCH (a:person)-[e:knows]->(b:person) WHERE a.ID > 8 RETURN a.ID, b.ID, e, ID(e) @@ -76,7 +75,6 @@ 9|10|(0:6)-{_LABEL: knows, _ID: 3:14, date: 1997-03-22, meetTime: 1976-12-23 11:21:42, validInterval: 2 years, comments: [A,k]}->(0:7)|3:14 -CASE InsertSingleNTo1RelTest --SKIP -STATEMENT MATCH (a:person), (b:organisation) WHERE a.ID = 9 AND b.orgCode = 934 CREATE (a)-[:studyAt {year:2022}]->(b) ---- ok -STATEMENT MATCH (a:person)-[e:studyAt]->(b:organisation) WHERE a.ID > 5 RETURN a.ID, b.orgCode, e, ID(e) @@ -85,7 +83,6 @@ 9|934|(0:6)-{_LABEL: studyAt, _ID: 4:3, year: 2022}->(1:1)|4:3 -CASE InsertRepeatedNToNRelTest --SKIP -STATEMENT MATCH (a:person), (b:person) WHERE a.ID = 7 AND b.ID = 8 CREATE (a)-[:knows {validInterval:interval('3 years')}]->(b) ---- ok -STATEMENT MATCH (a:person)-[e:knows]->(b:person) WHERE a.ID=7 RETURN b.ID, e.validInterval @@ -95,7 +92,6 @@ 9|00:47:58 -CASE InsertMixedRelTest --SKIP -STATEMENT MATCH (a:person), (b:person), (c:organisation) WHERE a.ID = 0 AND b.ID = 9 AND c.ID = 4 CREATE (b)-[:studyAt]->(c), (a)<-[:knows]-(b) ---- ok -STATEMENT MATCH (a:person)-[:knows]->(b:person)-[:studyAt]->(c:organisation) RETURN COUNT(*) @@ -103,7 +99,6 @@ 9 -CASE InsertMultipleRelsTest --SKIP -STATEMENT MATCH (a:person)-[:knows]->(b:person) WHERE a.ID = 7 CREATE (a)<-[:knows]-(b) ---- ok -STATEMENT MATCH (a:person)-[e:knows]->(b:person) WHERE a.ID > 6 RETURN a.ID, b.ID, ID(e) @@ -114,7 +109,6 @@ 9|7|3:15 -CASE InsertNodeAndRelTest --SKIP -STATEMENT CREATE (a:person {ID:100})-[:knows {date:date('1997-03-22')}]->(b:person {ID:202}) ---- ok -STATEMENT MATCH (a:person)-[e:knows]->(b:person) WHERE a.ID > 50 RETURN a.ID, b.ID, e.date @@ -122,7 +116,6 @@ 100|202|1997-03-22 -CASE InsertNodeAndRelTest2 --SKIP -STATEMENT CREATE (c:organisation {ID:50})<-[:workAt]-(a:person {ID:100}), (a)-[:studyAt]->(c) ---- ok -STATEMENT MATCH (a:person)-[e1:studyAt]->(b:organisation), (a)-[e2:workAt]->(b) RETURN a.ID, b.ID, ID(e1), ID(e2) @@ -130,20 +123,20 @@ 100|50|4:3|5:3 # TODO: Fix issue 2257 to enable this test -#-CASE InsertNodeWithListTest -#-STATEMENT BEGIN TRANSACTION -#---- ok -#-STATEMENT CREATE (:person {ID:11, workedHours:[1,2,3], usedNames:['A', 'this is a long name']}) -#---- ok -#-STATEMENT MATCH (a:person) WHERE a.ID > 8 RETURN a.ID, a.workedHours,a.usedNames -#---- 3 -#10|[10,11,12,3,4,5,6,7]|[Ad,De,Hi,Kye,Orlan] -#11|[1,2,3]|[A,this is a long name] -#9|[1]|[Grad] +-CASE InsertNodeWithListTest +-SKIP +-STATEMENT BEGIN TRANSACTION +---- ok +-STATEMENT CREATE (:person {ID:11, workedHours:[1,2,3], usedNames:['A', 'this is a long name']}) +---- ok +-STATEMENT MATCH (a:person) WHERE a.ID > 8 RETURN a.ID, a.workedHours,a.usedNames +---- 3 +10|[10,11,12,3,4,5,6,7]|[Ad,De,Hi,Kye,Orlan] +11|[1,2,3]|[A,this is a long name] +9|[1]|[Grad] #-COMMIT -#-STATEMENT MATCH (a:person) WHERE a.ID > 8 RETURN a.ID, a.workedHours,a.usedNames -#---- 3 -#10|[10,11,12,3,4,5,6,7]|[Ad,De,Hi,Kye,Orlan] -#11|[1,2,3]|[A,this is a long name] -#9|[1]|[Grad] - +-STATEMENT MATCH (a:person) WHERE a.ID > 8 RETURN a.ID, a.workedHours,a.usedNames +---- 3 +10|[10,11,12,3,4,5,6,7]|[Ad,De,Hi,Kye,Orlan] +11|[1,2,3]|[A,this is a long name] +9|[1]|[Grad] diff --git a/test/test_files/update_node/delete_tinysnb.test b/test/test_files/update_node/delete_tinysnb.test index efa0643ea42..2ade29b1e00 100644 --- a/test/test_files/update_node/delete_tinysnb.test +++ b/test/test_files/update_node/delete_tinysnb.test @@ -15,7 +15,6 @@ 101|| -CASE MixedDeleteInsertTest --SKIP -STATEMENT CREATE (a:organisation {ID:30, mark:3.3}) ---- ok -STATEMENT MATCH (a:organisation) WHERE a.ID = 30 RETURN a.orgCode, a.mark diff --git a/test/test_files/update_node/set_tinysnb.test b/test/test_files/update_node/set_tinysnb.test index ca654ff76c1..b708ad73ee1 100644 --- a/test/test_files/update_node/set_tinysnb.test +++ b/test/test_files/update_node/set_tinysnb.test @@ -170,7 +170,6 @@ Runtime exception: Maximum length of strings is 4096. Input string's length is 2 9|2 -CASE SetRelInt16PropTest --SKIP -STATEMENT MATCH (a:person)-[e:studyAt]->(b:organisation) WHERE a.ID = 0 SET e.length=99 ---- ok -STATEMENT MATCH (a:person)-[e:studyAt]->(b:organisation) RETURN e.length @@ -232,7 +231,6 @@ Runtime exception: Maximum length of strings is 4096. Input string's length is 2 1|10 -CASE SETMultiLabelWithPruning --SKIP -STATEMENT MATCH (a:person)-[:knows]->(b) WHERE a.ID=0 SET b.name = "a", b.fName = "XX" RETURN b.name, b.fName; ---- 3 |XX diff --git a/test/test_files/update_rel/create_empty.test b/test/test_files/update_rel/create_empty.test index 216c939543c..8f13a735f91 100644 --- a/test/test_files/update_rel/create_empty.test +++ b/test/test_files/update_rel/create_empty.test @@ -1,10 +1,8 @@ -GROUP EmptyCreateRelTest -DATASET CSV empty --SKIP -- -CASE CreateOneToOneRel --PARALLELISM 1 -STATEMENT CREATE NODE TABLE N1(ID INT64, PRIMARY KEY(ID)); ---- ok -STATEMENT CREATE NODE TABLE N2(ID INT64, PRIMARY KEY(ID)); @@ -21,9 +19,3 @@ ---- 2 12 8 --STATEMENT COPY Rel1 FROM '${KUZU_ROOT_DIRECTORY}/dataset/one_to_one_rel/rel.csv'; ----- ok --STATEMENT MATCH (n1:N1)-[e:Rel1]->(n2:N2) RETURN e ----- 2 -(0:0)-{_LABEL: Rel1, _ID: 2:0}->(1:1) -(0:1)-{_LABEL: Rel1, _ID: 2:1}->(1:0) diff --git a/test/test_files/update_rel/create_read_tinysnb.test b/test/test_files/update_rel/create_read_tinysnb.test index 1beeff5ef70..091834f6f19 100644 --- a/test/test_files/update_rel/create_read_tinysnb.test +++ b/test/test_files/update_rel/create_read_tinysnb.test @@ -1,6 +1,5 @@ -GROUP TinySnbCreateReadRelTest -DATASET CSV tinysnb --SKIP -- -CASE CreateRelRead1 @@ -12,7 +11,7 @@ (0:0)-{_LABEL: knows, _ID: 0:15, date: 2023-04-04}->(0:1) -STATEMENT MATCH (a:person)-[e:knows]->(b:person) WHERE a.ID = 0 AND b.ID = 2 RETURN e; ---- 3 -(0:0)-{_LABEL: knows, _ID: 3:0, date: 2021-06-30, meetTime: 1986-10-21 21:08:31.521, validInterval: 10 years 5 months 13:00:00.000024, comments: [rnme,m8sihsdnf2990nfiwf]}->(0:1) +(0:0)-{_LABEL: knows, _ID: 3:0, date: 2021-06-30, meetTime: 1986-10-21 21:08:31.521, validInterval: 10 years 5 months 13:00:00.000024, comments: [rnme,m8sihsdnf2990nfiwf], summary: {locations: ['toronto','waterloo'], transfer: {day: 2021-01-02, amount: [100,200]}}, notes: 1}->(0:1) (0:0)-{_LABEL: knows, _ID: 3:14, date: 2023-03-03}->(0:1) (0:0)-{_LABEL: knows, _ID: 3:15, date: 2023-04-04}->(0:1) @@ -24,9 +23,9 @@ (0:0)-{_LABEL: knows, _ID: 0:16, date: 2023-04-04}->(0:3) -STATEMENT MATCH (a:person)-[e:knows]->(b:person) WHERE a.ID = 0 RETURN e; ---- 6 -(0:0)-{_LABEL: knows, _ID: 3:0, date: 2021-06-30, meetTime: 1986-10-21 21:08:31.521, validInterval: 10 years 5 months 13:00:00.000024, comments: [rnme,m8sihsdnf2990nfiwf]}->(0:1) -(0:0)-{_LABEL: knows, _ID: 3:1, date: 2021-06-30, meetTime: 1946-08-25 19:07:22, validInterval: 20 years 30 days 48:00:00, comments: [njnojppo9u0jkmf,fjiojioh9h9h89hph]}->(0:2) -(0:0)-{_LABEL: knows, _ID: 3:2, date: 2021-06-30, meetTime: 2012-12-11 20:07:22, validInterval: 10 days, comments: [ioji232,jifhe8w99u43434]}->(0:3) +(0:0)-{_LABEL: knows, _ID: 3:0, date: 2021-06-30, meetTime: 1986-10-21 21:08:31.521, validInterval: 10 years 5 months 13:00:00.000024, comments: [rnme,m8sihsdnf2990nfiwf], summary: {locations: ['toronto','waterloo'], transfer: {day: 2021-01-02, amount: [100,200]}}, notes: 1}->(0:1) +(0:0)-{_LABEL: knows, _ID: 3:1, date: 2021-06-30, meetTime: 1946-08-25 19:07:22, validInterval: 20 years 30 days 48:00:00, comments: [njnojppo9u0jkmf,fjiojioh9h9h89hph], summary: {locations: , transfer: }, notes: 2020-10-10}->(0:2) +(0:0)-{_LABEL: knows, _ID: 3:2, date: 2021-06-30, meetTime: 2012-12-11 20:07:22, validInterval: 10 days, comments: [ioji232,jifhe8w99u43434], summary: {locations: ['shanghai'], transfer: {day: 1990-09-10, amount: [10]}}, notes: nice weather}->(0:3) (0:0)-{_LABEL: knows, _ID: 3:14, date: 2023-04-04}->(0:1) (0:0)-{_LABEL: knows, _ID: 3:15, date: 2023-04-04}->(0:2) (0:0)-{_LABEL: knows, _ID: 3:16, date: 2023-04-04}->(0:3) diff --git a/test/test_files/update_rel/delete_tinysnb.test b/test/test_files/update_rel/delete_tinysnb.test index ae8fe7ff4d6..2a37c929d16 100644 --- a/test/test_files/update_rel/delete_tinysnb.test +++ b/test/test_files/update_rel/delete_tinysnb.test @@ -1,6 +1,5 @@ -GROUP TinySnbDeleteRelTest -DATASET CSV tinysnb --SKIP -- -CASE DeleteRelMultiLabel1 diff --git a/test/test_files/update_rel/merge_tinysnb.test b/test/test_files/update_rel/merge_tinysnb.test index 223a39da816..9a4ccbfeb29 100644 --- a/test/test_files/update_rel/merge_tinysnb.test +++ b/test/test_files/update_rel/merge_tinysnb.test @@ -1,6 +1,5 @@ -GROUP TinySnbMergeRelTest -DATASET CSV tinysnb --SKIP -- -CASE Merge1 diff --git a/test/test_files/update_rel/set_read_tinysnb.test b/test/test_files/update_rel/set_read_tinysnb.test index 48dcc43013f..c4f8680b08c 100644 --- a/test/test_files/update_rel/set_read_tinysnb.test +++ b/test/test_files/update_rel/set_read_tinysnb.test @@ -19,7 +19,6 @@ ---- 1 -CASE SetReadTest2 --SKIP -STATEMENT CREATE REL TABLE play(FROM person TO person, date DATE, year INT64); ---- ok -STATEMENT MATCH (a:person), (b:person) WHERE a.ID=0 AND b.ID = 2 CREATE (a)-[e:play {date:date('2023-01-01'), year:2023}]->(b); diff --git a/test/test_files/update_rel/set_tinysnb.test b/test/test_files/update_rel/set_tinysnb.test index d430dc2b9af..64f5e7b9c79 100644 --- a/test/test_files/update_rel/set_tinysnb.test +++ b/test/test_files/update_rel/set_tinysnb.test @@ -1,6 +1,5 @@ -GROUP TinySnbSetRelTest -DATASET CSV tinysnb --SKIP -- -CASE SETMultiLabelNodePropTest